使用 R 中的笛卡尔积将行移入多列
Shift Rows Into Multiple Columns With Cartesian Product in R
假设一个简单的数据集类似于:
col data
0 A
0 B
0 C
1 D
1 E
1 F
2 G
2 H
2 I
... 目标是将其转换为由 "col" 中不同值的数量给出的列数,并且在每一列中,由关联的 "data" 指定的值对于该专栏...然后所有内容都呈现为一种笛卡尔积(其中各栏不应在其内部混合):
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)
通过生成正确数量的列让我开始了,但我仍然需要从那里开始进行各种叉积,每列中的值。最后要注意的是,这里的列数没有任何内在的东西:任何解决方案都必须适用于原始数据中指定的列数。
expand.grid
"create[s] a data frame from all combinations of the supplied vectors or factors",outer
笛卡尔积的一种长版。它需要一组 vectors/factors 或包含此类的列表,这让我们可以通过 col
:
简单地 split
data
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
我们也可以使用 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))]
假设一个简单的数据集类似于:
col data
0 A
0 B
0 C
1 D
1 E
1 F
2 G
2 H
2 I
... 目标是将其转换为由 "col" 中不同值的数量给出的列数,并且在每一列中,由关联的 "data" 指定的值对于该专栏...然后所有内容都呈现为一种笛卡尔积(其中各栏不应在其内部混合):
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)
通过生成正确数量的列让我开始了,但我仍然需要从那里开始进行各种叉积,每列中的值。最后要注意的是,这里的列数没有任何内在的东西:任何解决方案都必须适用于原始数据中指定的列数。
expand.grid
"create[s] a data frame from all combinations of the supplied vectors or factors",outer
笛卡尔积的一种长版。它需要一组 vectors/factors 或包含此类的列表,这让我们可以通过 col
:
split
data
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
我们也可以使用 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))]