如何在使用R保留结构的同时从嵌套列表创建所有组合? [英] How to create all combinations from a nested list while preserving the structure using R?

查看:90
本文介绍了如何在使用R保留结构的同时从嵌套列表创建所有组合?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出一个嵌套列表,如何在保留嵌套列表结构的同时从其元素创建所有可能的列表?

Given a nested list, how to create all possible lists from its elements, while preserving the structure of the nested list?

嵌套列表:

l = list(
    a = list(
        b = 1:2
    ),
    c = list(
        d = list(
            e = 3:4,
            f = 5:6
        )
    ),
    g = 7
)

所需的输出:l的所有可能组合,同时保留结构,例如:

Desired output: all possible combinations of the elements of l, while preserving the structure, e.g.:

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

到目前为止,我的方法是:

My approach so far is to:

  1. 拉平列表(例如,如此答案中所述)
  2. expand.grid() 并得到一个矩阵,其中每一行代表一个唯一的组合
  3. 解析所得矩阵的每一行,并从 names() 使用正则表达式
  1. flatten the list (e.g., as discussed in this answer)
  2. expand.grid() and get a matrix where each row represents a unique combination
  3. parse every row of the resulting matrix and reconstruct the structure from the names() using regular expressions

我正在寻找一种不太麻烦的方法,因为我不能保证列表元素的名称不会更改.

I am looking for a less cumbersome approach because I have no guarantee that the names of the list elements will not change.

推荐答案

utils中的relist函数似乎是为该任务而设计的:

The relist function from utils seems to be designed for this task:

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

它保存列表的结构(skeleton).这意味着现在可以操纵嵌套列表中的数据,然后将其重新分配到结构中(flesh).这里是扩展矩阵的第一行.

It saves the structure of the list (skeleton). This means one can now manipulate the data within the nested list and re-assign it into the structure (flesh). Here with the first row of the expanded matrix.

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"  

请注意,由于结构保持不变,因此我需要提供与原始列表中相同数量的元素.这就是为什么使用rep将元素重复两次的原因.我猜也可以用NA填充它.

Note that since the structure stays the same, I need to supply the same amount of elements as in the original list. This is why used rep to repeat the element twice. One could also fill it with NA, I guess.

对于每种可能的组合,请通过r进行迭代(扩展):

For every possible combination iterate through r (expanded):

lapply(1:nrow(r), function(x) 
          relist(rep(unname(unlist(r[x,])),each = 2), skeleton = rl))

这篇关于如何在使用R保留结构的同时从嵌套列表创建所有组合?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆