deepAgrawal
deepAgrawal

Reputation: 733

combination of rows of dataframe in R

I want to create a new dataframes such that

df1

A1 B1 C1
1  2  3
4  5  6
7  8  9

result_df

A1 B1 C1 A2 B2 C2
1  2  3  4  5  6
1  2  3  7  8  9
4  5  6  7  8  9

Basically, pairwise combination of rows such that row[i] != row [j] I can do this using for loop. But I was wondering is there a way I can use data.table or apply function to make it faster.

Upvotes: 2

Views: 1117

Answers (2)

ekstroem
ekstroem

Reputation: 6171

If it's always numbers in your data frame then you can use the following

## Generate data
DF <- as.data.frame(matrix(1:9,3))
DF
  V1 V2 V3
1  1  4  7
2  2  5  8
3  3  6  9

Then combine the rows

t(apply(t(combn(3,2)), 1, FUN = function(x){unlist(DF[x])}))

which yields this matrix

     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    1    2    3    4    5    6
[2,]    1    2    3    7    8    9
[3,]    4    5    6    7    8    9

If you need non-numeric columns in your data frame then the code above needs to be tweaked a bit.

Update based on the comment below

To make the input identical to the OP we just need to make sure that we extract rows instead of columns in the function call

DF <- as.data.frame(matrix(1:9,3,byrow=TRUE))
t(apply(t(combn(3,2)), 1, FUN = function(x){unlist(DF[x,])}))

which produces

     V11 V12 V21 V22 V31 V32
[1,]   1   4   2   5   3   6
[2,]   1   7   2   8   3   9
[3,]   4   7   5   8   6   9

The order becomes different but the result is the same.

Upvotes: 4

thelatemail
thelatemail

Reputation: 93813

A solution that won't force different columns to all be the same type:

DF <- as.data.frame(matrix(1:9,3,byrow=TRUE))

cmb <- combn(seq_len(nrow(DF)), 2)
cbind(DF[cmb[1,],], DF[cmb[2,],])

#    V1 V2 V3 V1 V2 V3
#1    1  2  3  4  5  6
#1.1  1  2  3  7  8  9
#2    4  5  6  7  8  9

Upvotes: 2

Related Questions