给定一个嵌套列表,如何在保留嵌套列表结构的同时从其元素创建所有可能的列表?
嵌套列表:
l = list(
a = list(
b = 1:2
),
c = list(
d = list(
e = 3:4,
f = 5:6
)
),
g = 7
)
Run Code Online (Sandbox Code Playgroud)
所需的输出:l保留元素的结构的所有可能组合,例如:
# One possible output:
list(
a = list(
b = 1
),
c = list(
d = list(
e = 3,
f = 5
)
),
g = 7
)
# Another possible output:
list(
a = list(
b = 1
),
c = list(
d = list(
e = 4,
f = 5
)
),
g = 7
)
Run Code Online (Sandbox Code Playgroud)
到目前为止,我的方法是:
expand.grid() 并得到一个矩阵,其中每一行代表一个唯一的组合names()使用正则表达式重建结构我正在寻找一种不太麻烦的方法,因为我不能保证列表元素的名称不会更改。
relist来自的功能utils似乎是为该任务而设计的:
rl <- as.relistable(l)
r <- expand.grid(data.frame(rl), KEEP.OUT.ATTRS = F)
> head(r, 5)
b c.d.e c.d.f g
1 1 3 5 7
2 2 3 5 7
3 1 4 5 7
4 2 4 5 7
5 1 3 6 7
Run Code Online (Sandbox Code Playgroud)
它保存列表的结构(skeleton)。这意味着现在可以操纵嵌套列表中的数据,然后将其重新分配到结构(flesh)中。这里是扩展矩阵的第一行。
r <- rep(unname(unlist(r[1,])),each = 2)
l2 <- relist(r, skeleton = rl)
> l2
$a
$a$b
[1] 1 1
$c
$c$d
$c$d$e
[1] 3 3
$c$d$f
[1] 5 5
$g
[1] 7
attr(,"class")
[1] "relistable" "list"
Run Code Online (Sandbox Code Playgroud)
请注意,由于结构保持不变,因此我需要提供与原始列表中相同数量的元素。这就是为什么用来rep重复元素两次。NA我猜也可以用它填充它。
对于每种可能的组合,反复迭代r(扩展):
lapply(1:nrow(r), function(x)
relist(rep(unname(unlist(r[x,])),each = 2), skeleton = rl))
Run Code Online (Sandbox Code Playgroud)
结合Ben Nutzer的出色回答和Charis Chau的出色评论,答案将成为一线书:
apply(expand.grid(data.frame(l)), 1L, relist, skeleton = rapply(l, head, n = 1L, how = "list"))
Run Code Online (Sandbox Code Playgroud)
它会创建一个列表列表,其中包含的元素数量与返回的行数相同expand.grid()。通过以下输出可以更好地可视化结果str():
str(apply(expand.grid(data.frame(l)), 1L, relist, skeleton = rapply(l, head, n = 1L, how = "list")))
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)List of 16 $ :List of 3 ..$ a:List of 1 .. ..$ b: num 1 ..$ c:List of 1 .. ..$ d:List of 2 .. .. ..$ e: num 3 .. .. ..$ f: num 5 ..$ g: num 7 $ :List of 3 ..$ a:List of 1 .. ..$ b: num 2 ..$ c:List of 1 .. ..$ d:List of 2 .. .. ..$ e: num 3 .. .. ..$ f: num 5 ..$ g: num 7 ... ... ... $ :List of 3 ..$ a:List of 1 .. ..$ b: num 2 ..$ c:List of 1 .. ..$ d:List of 2 .. .. ..$ e: num 4 .. .. ..$ f: num 6 ..$ g: num 7