簡體   English   中英

取消列出並合並選定的列到R中的數據框

[英]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.framelist中獲得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.calldata.framecbind基本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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM