2015-11-06 2 views
0

Следующая структура дается:сочетающий в себе элементы различной длины из вложенного списка

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[[1]][1] может быть объединен с a[[2]][1], a[[2]][2] и a[[2]][3]. Все эти результаты могут быть объединены с a[[3]][1], ..., a[[3]][5] (В целом это должно быть 30 комбинаций). Комбинируя, я имею в виду применение c к элементам.

Я предполагаю, что это сводится к поисковым элементам в конце дерева (например, если у меня есть A1 или A2 в фазе 1, B1 или B2 в фазе 2 и C1 или C2 в фазе 3, все результаты будут следующими: A1B1C1 , A1B1C2, A1B2C1, A1B2C2, A2B1C1, A2B1C2.)

Теперь я знаю, как это сделать с тройным вложенным циклом, но что произойдет, если список a станет больше? Я не знаю, можно ли это сделать иначе. Любые предложения оценили.

+0

как 'expand.grid (sapply (длины (а), seq.int))' и сделать некоторую индексацию – rawr

+0

со списком топ н-элементного (в вашем case 'a' имеет три элемента), он похож на индексирование n-мерного массива. – jogo

ответ

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

В качестве альтернативы expand.grid, если вы ищете более высокую скорость по мере роста списков, вы можете проверить CJ от «data.table» пакет:

Такой подход был бы:

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 
+0

Спасибо! 'data.table' кажется очень мощным. Мне нужно войти в него. – EDC

Смежные вопросы