2016-09-12 4 views
2

Iはリストそのような等があるとします。私はカラムnとリスト内の各データフレームの最初の2列の合併である望ん非公開にし、Rのデータフレーム列を選択マージ

df1<-data.frame(n=letters[1:4], x=1:4, y=2:5, z=3:6) 
df2<-data.frame(n=letters[2:5], x=2:5, y=3:6, z=4:7) 
df3<-data.frame(n=letters[3:7], x=2:6, y=3:7, z=4:8) 
ls<-list(df1, df2, df3) 
ls 
[[1]] 
    n x y z 
1 a 1 2 3 
2 b 2 3 4 
3 c 3 4 5 
4 d 4 5 6 

[[2]] 
    n x y z 
1 b 2 3 4 
2 c 3 4 5 
3 d 4 5 6 
4 e 5 6 7 

[[3]] 
    n x y z 
1 c 2 3 4 
2 d 3 4 5 
3 e 4 5 6 
4 f 5 6 7 
5 g 6 7 8 

所望の出力は次のようになります。

y、zのための
n x1 x2 x3 
1 a 1 NA NA 
2 b 2 2 NA 
3 c 3 3 2 
4 d 4 4 3 
5 e NA 5 4 
6 f NA NA 5 
7 g NA NA 6 

と同じこと:

n y1 y2 y3 
1 a 2 NA NA 
2 b 3 3 NA 
3 c 4 4 3 
4 d 5 5 4 
5 e NA 6 5 
6 f NA NA 6 
7 g NA NA 7 

    n z1 z2 z3 
1 a 3 NA NA 
2 b 4 4 NA 
3 c 5 5 4 
4 d 6 6 5 
5 e NA 7 6 
6 f NA NA 7 
7 g NA NA 8 

答えて

3

の列名は、listからdata.frameの 'n'( 'nm1')を除き、それらをループ(lapply(nm1,...)、 'ls'(lapply(ls, function(x) ...)の 'data.frame'の各列をサブセット化します。 mergeReduceを使用して、listのデータセットをマージします。

nm1 <- setdiff(unlist(lapply(ls, names)), "n") 
lapply(nm1, function(nm) setNames(Reduce(function(...) 
    merge(..., all=TRUE, by = "n"), lapply(ls, 
       function(x) x[c("n", nm)])), make.unique(c("n", rep(nm, length(nm1)))))) 
#[[1]] 
# n x x.1 x.2 
#1 a 1 NA NA 
#2 b 2 2 NA 
#3 c 3 3 2 
#4 d 4 4 3 
#5 e NA 5 4 
#6 f NA NA 5 
#7 g NA NA 6 

#[[2]] 
# n y y.1 y.2 
#1 a 2 NA NA 
#2 b 3 3 NA 
#3 c 4 4 3 
#4 d 5 5 4 
#5 e NA 6 5 
#6 f NA NA 6 
#7 g NA NA 7 

#[[3]] 
# n z z.1 z.2 
#1 a 3 NA NA 
#2 b 4 4 NA 
#3 c 5 5 4 
#4 d 6 6 5 
#5 e NA 7 6 
#6 f NA NA 7 
#7 g NA NA 8 

注:lsは、オブジェクトをリストする関数名です。既知のR関数を使用してオブジェクトに名前を付けるのは避けてください。

1

,data.frame、およびcbindをネストしたlapply関数内に使用するもう1つのベースRメソッドです。変数名の各貫通

# get all levels of n across data frames 
allN <- unique(unlist(sapply(ls, "[[", "n"))) 
# extract desired columns and provide names with setNames 
lapply(names(ls[[1]])[-1], function(var) { 
     cbind("n"=allN, setNames(do.call(data.frame, 
     lapply(seq_along(ls), function(i) { 
           ls[[i]][[var]][match(allN, ls[[i]]$n, nomatch=NA)] 
           })), paste0(var, seq_along(ls)))) 
}) 

最初lapplyラン、第lapplyは、リスト内の各データフレームから現在の変数を抽出します。真ん中で、do.callはリストをdata.frameにし、setNamesは望ましい名前を提供し、n列はcbindで追加されます。

内側のlapplyの最も内側の部分では、コードls[[i]][[var]][match(allN, ls[[i]]$n, nomatch=NA)]を使用して、allNのレベルに従って現在のベクトルを展開(および場合によっては並べ替え)します。現在のベクトルにレベルがない場合、nomatch = NAはmatchに代わりにNAを返すよう指示します。

関連する問題