I have a matrix of size 2000 X 700.
I want to subtract all possible pairs of rows.
If x_i
represent a row then I want to compute: x_1-x_2, x_1-x_3, ..., x_2-x_3,...
Example:
mat
1 2 3
5 3 2
1 1 6
My output should be
x_1 - x_2: -4 -1 1
x_1 - x_3: 0 1 -3
x_2 - x_3: 4 2 -4
I tried using a loop, but it takes too long. Is there an efficient way to compute this?
CodePudding user response:
Perhaps use combn
combn(row.names(m1), 2, function(x) m1[x[1],] - m1[x[2],])
CodePudding user response:
A relatively fast approach would be to pre-define an index list and then use it on the data, set to data.table
.
library(data.table)
setDT(mat)
rows <- nrow(mat)
idx <- as.matrix(rbindlist(lapply(1:(rows - 1), function(x)
rbindlist(lapply((x 1):rows, function(y) list(x, y)))))) # takes approx. 6 secs on my crappy system for 2000 x 2000 combinations
idx
V1 V2
[1,] 1 2
[2,] 1 3
[3,] 2 3
mat[idx[, 1], ] - mat[idx[, 2], ] # takes approx. 0.2 - 1 secs
V1 V2 V3
1: -4 -1 1
2: 0 1 -3
3: 4 2 -4
Data
mat <- structure(list(V1 = c(1L, 5L, 1L), V2 = c(2L, 3L, 1L), V3 = c(3L,
2L, 6L)), class = "data.frame", row.names = c(NA, -3L))
CodePudding user response:
Another use of combn
(along with asplit
)
> t(combn(asplit(mat, 1), 2, function(x) do.call(`-`, x)))
[,1] [,2] [,3]
[1,] -4 -1 1
[2,] 0 1 -3
[3,] 4 2 -4