How to attach each row of a dataframe against all the other rows in a pairwise manner

63 Views Asked by At

I have a data frame:

df1<-data.frame(1:3,4:6,7:9)

And I want to attach each row of it against each row of the same dataframe so I get this:

result<-data.frame(c("1 1","1 2","1 3","2 1","2 2","2 3","3 1","3 2","3 3"),c("4 4","4 5","4 6","5 4","5 5","5 6","6 4","6 5","6 6"),c("7 7","7 8","7 9","8 7","8 8","8 9","9 7","9 8","9 9"))

Each element in each cell is then pairwise attached to the other elements of the same column.

I've tried different 'paste' combinations but I don't get what I want. One possible solution that I tested was the following:

fpaste <- function(x){mapply(paste, x, df1)}
result_exp <- apply(t(df1), 1, fpaste)

But it doesn't work. I'm looking for a 'base' solution and trying to avoid packages as 'dplyr'. Thanks in advance for your help.

2

There are 2 best solutions below

0
Maël On BEST ANSWER

Use expand.grid:

sapply(list(1:3, 4:6, 7:9), \(x) do.call(paste, expand.grid(x, x)))

#       [,1]  [,2]  [,3] 
# [1,] "1 1" "4 4" "7 7"
# [2,] "2 1" "5 4" "8 7"
# [3,] "3 1" "6 4" "9 7"
# [4,] "1 2" "4 5" "7 8"
# [5,] "2 2" "5 5" "8 8"
# [6,] "3 2" "6 5" "9 8"
# [7,] "1 3" "4 6" "7 9"
# [8,] "2 3" "5 6" "8 9"
# [9,] "3 3" "6 6" "9 9"
0
LMc On

Not sure if row order matters but you could also use outer:

sapply(df1, \(x) outer(x, x, paste))
#       X1.3  X4.6  X7.9 
#  [1,] "1 1" "4 4" "7 7"
#  [2,] "2 1" "5 4" "8 7"
#  [3,] "3 1" "6 4" "9 7"
#  [4,] "1 2" "4 5" "7 8"
#  [5,] "2 2" "5 5" "8 8"
#  [6,] "3 2" "6 5" "9 8"
#  [7,] "1 3" "4 6" "7 9"
#  [8,] "2 3" "5 6" "8 9"
#  [9,] "3 3" "6 6" "9 9"