问题描述
此问题有一个很好的扁平化列表解决方案,同时保留了它们的数据类型( unlist
可以做到这一点不是):
This question has a nice solution of flattening lists while preserving their data types (which unlist
does not):
flatten = function(x, unlist.vectors=F) {
while(any(vapply(x, is.list, logical(1)))) {
if (! unlist.vectors)
x = lapply(x, function(x) if(is.list(x)) x else list(x))
x = unlist(x, recursive=F)
}
x
}
如果我给它以下列表,它的行为将符合预期:
If I give it the following list, it behaves as expected:
> a = list(c(1,2,3), list(52, 561), "a")
> flatten(a)
[[1]]
[1] 1 2 3
[[2]]
[1] 52
[[3]]
[1] 561
[[4]]
[1] "a"
现在,我想像 a
那样重组平面列表. relist
惨败:
Now I'd like to restructure the flat list like a
. relist
fails miserably:
> relist(flatten(a), skeleton=a)
[[1]]
[[1]][[1]]
[1] 1 2 3
[[1]][[2]]
[1] 52
[[1]][[3]]
[1] 561
[[2]]
[[2]][[1]]
[[2]][[1]][[1]]
[1] "a"
[[2]][[2]]
[[2]][[2]][[1]]
NULL
[[3]]
[[3]][[1]]
NULL
现在,我当然可以执行 relist(unlist(b),a)
,但这又丢失了数据类型.重组平面列表的好方法是什么?
Now, I could of course do relist(unlist(b), a)
but that loses data types again. What is a good way to restructure a flat list?
奖励指出它是否正确处理了与 unlist.vectors
类似的属性.
Bonus points if it handles the analogous attribute to unlist.vectors
correctly.
推荐答案
一种方法是:
relist2 = function(x, like, relist.vectors=F) {
if (! relist.vectors)
like = rapply(a, function(f) NA, how='replace')
lapply(relist(x, skeleton=like), function(e) unlist(e, recursive=F))
}
这保留了类并区分列表和向量:
This retains the classes and distinguishes between lists and vectors:
> relist2(flatten(a), like=a)
[[1]]
[1] 1 2 3
[[2]]
[[2]][[1]]
[1] 52
[[2]][[2]]
[1] 561
[[3]]
[1] "a"
> relist2(flatten(a, unlist.vectors=T), like=a, relist.vectors=T)
[[1]]
[1] 1 2 3
[[2]]
[[2]][[1]]
[1] 52
[[2]][[2]]
[1] 561
[[3]]
[1] "a"
这篇关于R:重新列出平面清单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!