4つのdfからデータを収集し、それらを行名でマージしたいと思います。これを行う効率的な方法を探しています。これは、私が持っているデータの簡略版です。
df1 <- data.frame(N= sample(seq(9, 27, 0.5), 40, replace= T),
P= sample(seq(0.3, 4, 0.1), 40, replace= T),
C= sample(seq(400, 500, 1), 40, replace= T))
df2 <- data.frame(Origin= sample(c("A", "B", "C", "D", "E"), 40,
replace= T),
foo1= sample(c(T, F), 40, replace= T),
X= sample(seq(145600, 148300, 100), 40, replace= T),
Y= sample(seq(349800, 398600, 100), 40, replace= T))
df3 <- matrix(sample(seq(0, 1, 0.01), 40), 40, 100)
df4 <- matrix(sample(seq(0, 1, 0.01), 40), 40, 100)
rownames(df1) <- paste("P", sprintf("%02d", c(1:40)), sep= "")
rownames(df2) <- rownames(df1)
rownames(df3) <- rownames(df1)
rownames(df4) <- rownames(df1)
これは私が通常行うことです:
# merge df1 and df2
dat <- merge(df1, df2, by= "row.names", all.x= F, all.y= F) #merge
rownames(dat) <- dat$Row.names #reset rownames
dat$Row.names <- NULL #remove added rownames col
# merge dat and df3
dat <- merge(dat, df3, by= "row.names", all.x= F, all.y= F) #merge
rownames(dat) <- dat$Row.names #reset rownames
dat$Row.names <- NULL #remove added rownames col
# merge dat and df4
dat <- merge(dat, df4, by= "row.names", all.x= F, all.y= F) #merge
rownames(dat) <- dat$Row.names #reset rownames
dat$Row.names <- NULL #remove added rownames col
ご覧のとおり、これには多くのコードが必要です。私の質問は、同じ結果がより簡単な手段で達成できるかどうかです。私は試しました(成功せず):更新:これは今すぐ動作します!
MyMerge <- function(x, y){
df <- merge(x, y, by= "row.names", all.x= F, all.y= F)
rownames(df) <- df$Row.names
df$Row.names <- NULL
return(df)
}
dat <- Reduce(MyMerge, list(df1, df2, df3, df4))
提案を事前に感謝します
3行のコードでまったく同じ結果が得られます。
dat2 <- cbind(df1, df2, df3, df4)
colnames(dat2)[-(1:7)] <- paste(paste('V', rep(1:100, 2),sep = ''),
rep(c('x', 'y'), each = 100), sep = c('.'))
all.equal(dat,dat2)
ああ、今、あなたがなぜそんなに苦しんでいるのか理解しています。古いfor
ループを使用すると、確実にトリックが実行されます。さらに賢い解決策があるかもしれません
rn <- rownames(df1)
l <- list(df1, df2, df3, df4)
dat <- l[[1]]
for(i in 2:length(l)) {
dat <- merge(dat, l[[i]], by= "row.names", all.x= F, all.y= F) [,-1]
rownames(dat) <- rn
}
join_all
from plyr
はおそらくあなたが望むことをするでしょう。しかし、それらはすべてデータフレームでなければならず、行名は列として追加されます
require(plyr)
df3 <- data.frame(df3)
df4 <- data.frame(df4)
df1$rn <- rownames(df1)
df2$rn <- rownames(df2)
df3$rn <- rownames(df3)
df4$rn <- rownames(df4)
df <- join_all(list(df1,df2,df3,df4), by = 'rn', type = 'full')
type
引数は、行名が変化して一致しない場合でも役立ちます。行名が必要ない場合:
df$rn <- NULL
関数を編集して、特定の列キー(列の名前)により多くのデータフレームをマージできる関数を思いつきました。結果のデータフレームには、マージされたデータフレームのすべての変数が含まれます(共通変数のみを保持する場合(NAを除き、all.x= FALSE, all.y= FALSE
)
MyMerge <- function(x, y){
df <- merge(x, y, by= "name of the common column", all.x= TRUE, all.y= TRUE)
return(df)
}
new.df <- Reduce(MyMerge, list(df1, df2, df3, df4))
私は同じ機能を探していました。ここと他の場所でいくつかのオプションを試した後。私にとって最も簡単なのは:
cbind.data.frame(df1、df2、df3、df4 ....)