【问题标题】:Combining elements of different length from nested list从嵌套列表中组合不同长度的元素
【发布时间】:2015-11-06 15:40:00
【问题描述】:

给出如下结构:

a <- list()
a[[1]] <- list(c(1:3),c(3:8))
a[[2]] <- list(c(2:6),c(7:9),c(18:24))
a[[3]] <- list(c(11:13),c(10:16),c(17:19),c(11:14),c(17:20))

这意味着a[[1]] 有2 个元素,a[[2]] 3 个元素和a[[3]] 5 个元素。

我想从 a 中的元素创建所有可能的组合。 例如a[[1]][1] 可以与a[[2]][1]a[[2]][2]a[[2]][3] 结合使用。所有这些结果都可以与a[[3]][1],...,a[[3]][5] 组合在一起(总而言之应该是 30 种组合)。通过组合,我的意思是将c 应用于元素。

我认为这归结为在树的末尾搜索元素(例如,如果我在阶段 1 中有 A1 或 A2,在阶段 2 中有 B1 或 B2,在阶段 3 中有 C1 或 C2,所有结果将是:A1B1C1, A1B1C2,A1B2C1,A1B2C2,A2B1C1,A2B1C2,A2B2C1,A2B2C2。)

好的,现在我知道如何使用三重嵌套循环来执行此操作,但是如果列表 a 变大会发生什么?我不知道是否可以这样做。任何建议表示赞赏。

【问题讨论】:

  • 喜欢expand.grid(sapply(lengths(a), seq.int)) 并做一些索引
  • 具有 n 元素顶部列表(在您的情况下,a 具有三个元素)它类似于 n 维数组的索引。

标签: r list combinations


【解决方案1】:

使用expand.grid {base}

a <- list()
a[[1]] <- list(c(1:3),c(3:8))
a[[2]] <- list(c(2:6),c(7:9),c(18:24))
a[[3]] <- list(c(11:13),c(10:16),c(17:19),c(11:14),c(17:20))

comb <- expand.grid(a)

【讨论】:

    【解决方案2】:

    作为expand.grid 的替代方案,如果您希望随着列表的增长而提高速度,您可以查看“data.table”包中的CJ

    方法是:

    library(data.table)
    do.call(CJ, a)
    

    这里是前几行:

    > head(do.call(CJ, a), 10)
           V1        V2                 V3
     1: 1,2,3 2,3,4,5,6           11,12,13
     2: 1,2,3 2,3,4,5,6 10,11,12,13,14,15,
     3: 1,2,3 2,3,4,5,6           17,18,19
     4: 1,2,3 2,3,4,5,6        11,12,13,14
     5: 1,2,3 2,3,4,5,6        17,18,19,20
     6: 1,2,3     7,8,9           11,12,13
     7: 1,2,3     7,8,9 10,11,12,13,14,15,
     8: 1,2,3     7,8,9           17,18,19
     9: 1,2,3     7,8,9        11,12,13,14
    10: 1,2,3     7,8,9        17,18,19,20
    

    do.call 方法也适用于 expand.grid)。


    快速比较:

    a <- list()
    a[[1]] <- list(c(1:3),c(3:8))
    a[[2]] <- list(c(2:6),c(7:9),c(18:24))
    a[[3]] <- list(c(11:13),c(10:16),c(17:19),c(11:14),c(17:20))
    
    ## 15 item list
    a <- unlist(replicate(5, a, FALSE), recursive = FALSE)
    
    system.time(do.call(expand.grid, a))
    #    user  system elapsed 
    #   8.020   2.232  10.254 
    system.time(do.call(CJ, a))
    #    user  system elapsed 
    #   2.180   0.828   3.004 
    

    【讨论】:

    • 谢谢! data.table 似乎很强大。我需要进入它。
    猜你喜欢
    • 2023-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多