[英]unlist and merge selected columns to data frame in 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
我想要的是按n
列合並列表中每個數據幀的前兩列,而所需的輸出將是:
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
對於y和z同樣如此:
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
我們從data.frame
的list
中獲得unique
列名,除了'n'('nm1')之外,遍歷那些( lapply(nm1,...
),將每個'data.frame'的列作為子集在'ls'( lapply(ls, function(x) ...
)中)中,並使用帶有merge
lapply(ls, function(x) ...
Reduce
merge
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
函數命名對象。
這是另一個在嵌套的lapply
函數對中使用do.call
, data.frame
和cbind
基本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
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.