R 在lappy/ldply中使用列表中的对象名称

R 在lappy/ldply中使用列表中的对象名称,r,plyr,R,Plyr,在尝试回答之前的问题时,我遇到了一个看似简单的问题,但我无法解决 如果我有一个数据帧列表: 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) 但是,我需要另一列来标识每行来自哪个data.frame。我希望能够使用deparse(subs

在尝试回答之前的问题时,我遇到了一个看似简单的问题,但我无法解决

如果我有一个数据帧列表:

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)
但是,我需要另一列来标识每行来自哪个
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)
所以很明显,列表中的每个元素都不包含我认为它包含的名称。有人能提出一种方法来实现我的期望吗(如下所示)


仅使用base,可以尝试以下操作:

dd <- lapply(seq_along(df.list), function(x) cbind(df_name = paste0('df',x),df.list[[x]]))

do.call(rbind,dd)

dd在您的定义中,
df.list
没有名称,但是,即使这样,deparse替换习惯用法似乎也不容易使用(因为
lappy
调用
.Internal(lappy(X,FUN))
——您必须查看源代码以查看对象名称是否可用以及如何获取它

差不多

names(df.list) <- paste('df', 1:3, sep = '')

foo <- function(n, .list){
         .list[[n]]$id <- n
         .list[[n]]
       } 

     a          x id
1 1  0.8204213  a
2 2 -0.8881671  a
3 3  1.2880816  a
4 1 -2.2766111  b
5 2  0.3912521  b
6 3 -1.3963381  b
7 1 -1.8057246  c
8 2  0.5862760  c
9 3  0.5605867  c

names(df.list)用名称定义列表,它应该给您一个
.id
列,其中包含
data.frame
名称

df.list <- list(df1=df1, df2=df2, df3=df3)
df.all <- ldply(df.list, rbind)
然后您可以从列
df.all$.id

编辑: 根据@Gary Weissman的评论,如果您想自动生成名称,您可以这样做

names(df.list) <- paste0('df',seq_along(df.list)

names(df.list)如果要使用
函数,而不是
deparse(substitute(x))
请使用
match.call()
,并且要使用第二个参数,确保将其转换为
字符

 name <- as.character(match.call()[[2]])

name不完全是一个答案,但你可能会对所使用的各种方法感兴趣。不使用命名列表来射击自己的脚。呵呵。我确实试过了,但那是在你真正完成编辑之前。有一段时间,你只有
lappy
列表(还有一个不同的版本)这肯定不起作用。啊,对不起,我的浏览器被冻结了,我的编辑被弄乱了;-(+1每个元素至少有一个唯一的名称,但问题是每个元素都是按顺序命名的(即与数据帧名称无关)。@alexwhan获取名称的另一种方法是替换为
df_name=names(df.list)[x]
我写了同样的东西,除了用
do.call(rbind,df.list)
而不是
ldply
,ldply也给出了原始行。这种方法唯一的缺点是你实际上必须手工键入所有数据帧的名称。你能做一些类似
名称(df.list)的事情吗+1这真的很有帮助-本质上,我的问题的答案是“列一个名单”-但我很感激你走得更远!@Gary Weissman-这很好,因为它提供了一个唯一的标识符,但没有链接到特定的名称。当然,一旦它是一个未命名的列表,就不可能进行链接。很高兴它起了作用。是的,关键是“命名列表”您可以根据@Gary的评论手动或自动提供名称
df.list <- list(df1=df1, df2=df2, df3=df3)
df.all <- ldply(df.list, rbind)
  .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
names(df.list) <- paste0('df',seq_along(df.list)
 name <- as.character(match.call()[[2]])