我有一个这样的嵌套列表:
nested_list <- list(a = c(1,2),
b = list(
c = c(3,4),
d = list(
e = c(5,6,7)
)))
我想简化它,所以它看起来像这样(只有一个级别,使用冒号分组的嵌套名称):
simplified_list <- list(a = c(1,2),
"b:c" = c(3,4),
"b:d:e" = c(5,6,7)
)
最好的方法是什么?
答案 0 :(得分:8)
这种方法具有很短的优点。它不使用任何包。它假定输入名称不包含尾随数字:
u <- unlist(nested_list)
res <- tapply(u, sub("\\d+$", "", names(u)), unname)
,并提供:
> res
$a
[1] 1 2
$b.c
[1] 3 4
$b.d.e
[1] 5 6 7
如果重要的是将名称分隔:而不是。然后添加:
names(res) <- chartr(".", ":", names(res))
答案 1 :(得分:3)
我没有声称&#34;最好&#34;,但这有效:
d <- reshape2::melt(nested_list)
> d
value L3 L2 L1
1 1 <NA> <NA> a
2 2 <NA> <NA> a
3 3 <NA> c b
4 4 <NA> c b
5 5 e d b
6 6 e d b
7 7 e d b
> d$L <- apply(d[,c('L1','L2','L3')],1,function(x) paste(unique(x[!is.na(x)]),collapse = ":"))
> l <- plyr::dlply(d,"L",function(x) unlist(x$value))
> l
$a
[1] 1 2
$`b:c`
[1] 3 4
$`b:d:e`
[1] 5 6 7
答案 2 :(得分:3)
我太慢了,但也许我的解决方案仍有帮助。它比joran有点长,但(至少对我而言)似乎更容易理解。 (但也许这只是因为我对plyr
包不太熟悉。)我绝对不会声称它是最好的解决方案...
# create names for the list
nm <- names(unlist(nested_list))
nm <- unique(sub("[0-9]*$","",nm))
nm <- gsub("\\.",":",nm)
# construct list
new_list <- lapply(nm,function(n) {
nested_list[[strsplit(n,":")[[1]]]]
})
# apply names
names(new_list) <- nm
> new_list
$a
[1] 1 2
$`b:c`
[1] 3 4
$`b:d:e`
[1] 5 6 7
答案 3 :(得分:3)
另一种选择:
nested_list <- list(a = c(1,2),
b = list(
c = c(3,4),
d = list(
e = c(5,6,7)
)))
ul <- unlist(nested_list)
sp <- split(unname(ul), gsub('\\d', '', names(ul)))
`names<-`(sp, gsub('\\.', ':', names(sp)))
# $a
# [1] 1 2
#
# $`b:c`
# [1] 3 4
#
# $`b:d:e`
# [1] 5 6 7
答案 4 :(得分:3)
我前段时间LinearizeNestedList
遇到了一个名为Akhil S Bhel的函数,并将其保存为Gist。它似乎完全符合你的要求:
LinearizeNestedList(nested_list, NameSep = ".")
# $a
# [1] 1 2
#
# $b.c
# [1] 3 4
#
# $b.d.e
# [1] 5 6 7