使用plyr
llply
而不是lapply
的优势在于它保留了列表名称。有关说明,请参阅?llply
。我喜欢这个功能,但似乎无法在嵌套列表的情况下使其工作。例如:
library(plyr)
m <- as.list(1:2)
names(m) <- c('M1', 'M2')
foo <- list(m, m)
names(foo) <- paste0("R", 1:2)
result <- ldply(foo, function(x){
ldply(x, function(z) { data.frame(a=z, b= z^2)})
})
> result
.id a b
1 M1 1 1
2 M2 2 4
3 M1 1 1
4 M2 2 4
# if I don't operate on the inner list, I can preserve the outer list's names
result2 <- ldply(foo, function(x){
data.frame(a = x[[1]], b = x[[1]]^2)
})
> result2
.id a b
1 R1 1 1
2 R2 1 1
请注意,result
不包含R1
和R2
(如果我没有在每个元素内的嵌套列表中操作,那么它将被添加为.id
与foo
)的情况一样result2
。在处理嵌套列表时,如何确保添加外部列表名称?
答案 0 :(得分:5)
似乎列名是问题所在:
result <- ldply(foo, function(x){
df <- ldply(x, function(z) { data.frame(a=z, b= z^2)})
names(df)[1] <- ".id2"; df
})
result
.id .id2 a b
1 R1 M1 1 1
2 R1 M2 2 4
3 R2 M1 1 1
4 R2 M2 2 4
答案 1 :(得分:3)
问题是ldply
如果已经存在,则.id
不会分配给ldply
变量。如果您查看一个内部> ldply(foo[[1]], function(z) { data.frame(a=z, b= z^2)})
.id a b
1 M1 1 1
2 M2 2 4
的结果,那就很好了:
result <- ldply(foo, function(x){
rename(ldply(x, function(z) { data.frame(a=z, b= z^2)}),
c(".id" = ".id2"))
})
将其重命名并按预期工作。
> result
.id .id2 a b
1 R1 M1 1 1
2 R1 M2 2 4
3 R2 M1 1 1
4 R2 M2 2 4
给出
{{1}}