在试图回答一个问题之前,我遇到了一个似乎应该很简单的问题,但我无法弄明白.
如果我有一个数据帧列表:
df1 <- data.frame(a=1:3, x=rnorm(3))
df2 <- data.frame(a=1:3, x=rnorm(3))
df3 <- data.frame(a=1:3, x=rnorm(3))
df.list <- list(df1, df2, df3)
Run Code Online (Sandbox Code Playgroud)
我想要rbind在一起,我可以做到以下几点:
df.all <- ldply(df.list, rbind)
Run Code Online (Sandbox Code Playgroud)
但是,我想要另一个列来标识data.frame每行来自哪一行.我希望能够使用该deparse(substitute(x))方法(此处和其他地方)获取相关的名称data.frame并添加一列.这就是我接近它的方式:
fun <- function(x) {
name <- deparse(substitute(x))
x$id <- name
return(x)
}
df.all <- ldply(df.list, fun)
Run Code Online (Sandbox Code Playgroud)
哪个回报
a x id
1 1 1.1138062 X[[1L]]
2 2 -0.5742069 X[[1L]]
3 3 0.7546323 X[[1L]]
4 1 1.8358605 X[[2L]]
5 2 0.9107199 X[[2L]]
6 3 0.8313439 X[[2L]]
7 1 0.5827148 X[[3L]]
8 2 -0.9896495 X[[3L]]
9 3 -0.9451503 X[[3L]]
Run Code Online (Sandbox Code Playgroud)
显然,列表中的每个元素都不包含我认为它的名称.任何人都可以建议一种方法来达到我的预期(如下所示)?
a x id
1 1 1.1138062 df1
2 2 -0.5742069 df1
3 3 0.7546323 df1
4 1 1.8358605 df2
5 2 0.9107199 df2
6 3 0.8313439 df2
7 1 0.5827148 df3
8 2 -0.9896495 df3
9 3 -0.9451503 df3
Run Code Online (Sandbox Code Playgroud)
使用名称定义列表,它应该为您提供一个名称.id列data.frame
df.list <- list(df1=df1, df2=df2, df3=df3)
df.all <- ldply(df.list, rbind)
Run Code Online (Sandbox Code Playgroud)
输出:
.id a x
1 df1 1 1.84658809
2 df1 2 -0.01177462
3 df1 3 0.58579469
4 df2 1 -0.64748756
5 df2 2 0.24384614
6 df2 3 0.59012676
7 df3 1 -0.63037679
8 df3 2 -1.17416295
9 df3 3 1.09349618
Run Code Online (Sandbox Code Playgroud)
然后,您可以data.frame从列中了解该名称df.all$.id
编辑: 根据@Gary Weissman的评论,如果您想自动生成名称,您可以这样做
names(df.list) <- paste0('df',seq_along(df.list)
Run Code Online (Sandbox Code Playgroud)