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]])