johnjps111
johnjps111

Reputation: 1170

Shift Rows Into Multiple Columns With Cartesian Product in R

Assume a simple dataset something like:

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

... where the goal is to convert this into a number of columns given by the number of distinct values in "col", and within each column, the values specified by the associated "data" for that column... then everything presented as a sort of Cartesian product (where columns should not mix within themselves):

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

I've been putzing with it for a bit, and dcast(df, data ~ col) gets me started by generating the correct number of columns, but I still need to go from there to a cross product of sorts, of the values in each of the columns. A final note is that there's nothing inherent in the number of columns here: any solution must work for however many columns are specified in the original data.

Upvotes: 3

Views: 207

Answers (2)

akrun
akrun

Reputation: 887108

We can also use CJ from 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

Or in another way

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

Upvotes: 3

alistaire
alistaire

Reputation: 43334

expand.grid "create[s] a data frame from all combinations of the supplied vectors or factors", a sort of long version of outer's cartesian product. It takes a set of vectors/factors or a list containing such, which lets us simply split data by 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

Upvotes: 6

Related Questions