从嵌套列表中组合不同长度的元素

时间:2015-11-06 15:40:00

标签: r list combinations

给出以下结构:

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变大,会发生什么?我不知道是否可以这样做。任何建议表示赞赏。

2 个答案:

答案 0 :(得分:5)

使用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)

答案 1 :(得分:3)

作为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