假设我有一个类似的列表:
int main (void)
{
int min; /*variable to hold minutes*/
printf ("How many minutes does it take you to use a shower? ");
scanf ("%d", &min);
while (min <= 0)
{
printf ("Please enter the positive number: ");
scanf ("%d", &min);
}
int numbtl = min * 12; /*computes number of bottles*/
printf ("Taking a shower you use %d bottles of water", numbtl);
return 0;
}
我想要的是按列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
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
答案 0 :(得分:3)
我们从unique
list
获取data.frame
列名称,但&#39; n&#39; (&#39; nm1&#39;),循环遍历那些(lapply(nm1,...
),将每个数据框的列子集合在一起。在&#39; ls&#39; (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
函数命名对象。
答案 1 :(得分:1)
以下是在嵌套的do.call
函数对中使用data.frame
,cbind
和lapply
的另一种基本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
。