2016-06-28 3 views
3

Предположим, простой набор данных что-то вроде:сдвига строки в несколько столбцов с декартовой продукта в R

col data 
0 A 
0 B 
0 C 
1 D 
1 E 
1 F 
2 G 
2 H 
2 I 

... где цель состоит в том, чтобы преобразовать это в число столбцов задается число различных значений в «Col», и в каждом столбце значения, указанные ассоциированными «данные» для этого столбца ... тогда все представляется как своего рода декартова произведения (где столбцы не должны смешиваться внутри себя):

0 1 2 (column names) 
A D G 
A D H 
A D I 
A E G 
A E H 
A E I 
A F G 
A F H 
A F I 
B D G 
B D H 
B D I 
(etc...) 

Я немного задираю его, и dcast(df, data ~ col) получает меня началось с создания правильного количества столбцов, но мне все равно нужно перейти оттуда к перекрестному произведению сортировки значений из каждого столбца. Последнее замечание состоит в том, что здесь нет ничего, что могло бы означать количество столбцов: любое решение должно работать, хотя в исходных данных указано много столбцов.

ответ

6

expand.grid «создать [s] кадр данных из всех комбинаций предоставленных векторов или факторов», своего рода длинную версию декартова продукта outer. Он принимает набор векторов/факторов или список, содержащий такие, что позволяет нам просто splitdata по col:

expand.grid(split(df$data, df$col)) 

# 0 1 2 
# 1 A D G 
# 2 B D G 
# 3 C D G 
# 4 A E G 
# 5 B E G 
# 6 C E G 
# 7 A F G 
# 8 B F G 
# 9 C F G 
# 10 A D H 
# 11 B D H 
# 12 C D H 
# 13 A E H 
# 14 B E H 
# 15 C E H 
# 16 A F H 
# 17 B F H 
# 18 C F H 
# 19 A D I 
# 20 B D I 
# 21 C D I 
# 22 A E I 
# 23 B E I 
# 24 C E I 
# 25 A F I 
# 26 B F I 
# 27 C F I 
3

Мы можем также использовать CJ из data.table

library(data.table) 
do.call(CJ, split(df$data, df$col)) 
# 0 1 2 
# 1: A D G 
# 2: A D H 
# 3: A D I 
# 4: A E G 
# 5: A E H 
# 6: A E I 
# 7: A F G 
# 8: A F H 
# 9: A F I 
#10: B D G 
#11: B D H 
#12: B D I 
#13: B E G 
#14: B E H 
#15: B E I 
#16: B F G 
#17: B F H 
#18: B F I 
#19: C D G 
#20: C D H 
#21: C D I 
#22: C E G 
#23: C E H 
#24: C E I 
#25: C F G 
#26: C F H 
#27: C F I 

Или по-другому

setDT(df)[, do.call(CJ, split(data, col))]