22

Rの要素としてデータフレームを含むリストがあります.

例:

df1 <- data.frame("names"=c("John","Sam","Dave"),"age"=c(21,22,25))
df2 <- data.frame("names"=c("John","Sam"),"score"=c(22,25))
df3 <- data.frame("names"=c("John","Sam","Dave"),"country"=c("US","SA","NZ"))
mylist <- list(df1,df2,df3)

ループを使用せずに mylist のすべての要素をマージすることは可能ですか?

この例の私の望ましい出力は次のとおりです。

  names age score country
1  John  21    22      US
2   Sam  22    25      SA

この例のリストには 3 つの要素しかありません。ただし、任意の数の要素を処理できるソリューションを探しています。

4

4 に答える 4

31

Reduceワンライナーソリューションを使用できます。

Reduce(merge,mylist)

  names age score country
1  John  21    22      US
2   Sam  22    25      SA
于 2013-02-26T02:08:15.913 に答える
8

手っ取り早い例:

merge(merge(df1, df2),df3)

編集- ここで非常によく似た質問:リスト内の複数のdata.framesを同時にマージします

解決:

merged.data.frame = Reduce(function(...) merge(..., all=F), my.list)

免責事項-@Charlesの回答から変更したのは、作成することだけでしたmerge(..., all=F)-Tこのようにして、目的の出力が得られます。

于 2013-02-26T00:02:07.220 に答える
6

別の方法で実行できることを示すために...

mymerge <- function(mylist) {
  names(mylist) <- sapply(mylist, function(x) names(x)[2])
  ns <- unique(unlist(lapply(mylist, function(x) levels(x$names))))
  as.data.frame(c(list(names=ns), lapply(mylist, function(x) 
                         {x[match(ns, x$names),2]})))
}

> mymerge(mylist)
  names age score country
1  Dave  25    NA      NZ
2  John  21    22      US
3   Sam  22    25      SA

値が欠落している行を削除するように簡単に適応できます。または、後で単に削除することもできますcomplete.cases

高速であることを示すために、より大きなデータ セットを作成します。100 個の変数と 25 個の名前。

set.seed(5)
vs <- paste0("V", 1:100)
mylist <- lapply(vs, function(v) {
  x <- data.frame(names=LETTERS[1:25], round(runif(25, 0,100)))
  names(x)[2] <- v
  x
})

> microbenchmark(Reduce(merge, mylist), myf(mylist))
Unit: milliseconds
                   expr       min        lq    median        uq       max
1           myf(mylist)  12.81371  13.19746  13.36571  14.40093  33.90468
2 Reduce(merge, mylist) 199.23714 206.28608 207.30247 208.44939 226.05980
于 2013-02-26T02:21:46.707 に答える
0

この機能を試しましたか?

http://rss.acs.unt.edu/Rdoc/library/gtools/html/smartbind.html

library(gtools)
df1 <- data.frame(list(A=1:10), B=LETTERS[1:10], C=rnorm(10) )
df2 <- data.frame(A=11:20, D=rnorm(10), E=letters[1:10] )
df3 <- df1

out <- smartbind( mylist <- list(df1,df2,df3))
于 2013-07-05T14:17:29.383 に答える