我有一个大小为2000 X 700的矩阵。
我想要减去所有可能的行对。
如果x_i
代表一行,那么我想要计算:x_1-x_2, x_1-x_3, ..., x_2-x_3,...
例如:
mat
1 2 3
5 3 2
1 1 6
我的输出应该是
x_1 - x_2: -4 -1 1
x_1 - x_3: 0 1 -3
x_2 - x_3: 4 2 -4
我尝试使用循环,但是太慢了。 有没有一种更有效的计算方法?
我有一个大小为2000 X 700的矩阵。
我想要减去所有可能的行对。
如果x_i
代表一行,那么我想要计算:x_1-x_2, x_1-x_3, ..., x_2-x_3,...
例如:
mat
1 2 3
5 3 2
1 1 6
我的输出应该是
x_1 - x_2: -4 -1 1
x_1 - x_3: 0 1 -3
x_2 - x_3: 4 2 -4
我尝试使用循环,但是太慢了。 有没有一种更有效的计算方法?
或许使用combn
combn(row.names(m1), 2, function(x) m1[x[1],] - m1[x[2],])
combn
比expand.grid
、expand_grid
或outer
更快,因为后者会进行两倍数量的比较。 - akrundata.table
。对于一个2000 x 700的矩阵,整个操作应该在一分钟内完成。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. 12 secs for 700 columns, see below if there's a memory error "Error: vector memory exhausted (limit reached?)"
V1 V2 V3
1: -4 -1 1
2: 0 1 -3
3: 4 2 -4
rbindlist(apply(
cbind(unique(floor(c(1, seq(1, nrow(idx), length.out=10)[2:9] + 1))),
unique(floor(seq(1, nrow(idx), length.out=10)[2:10]))), 1, function(x)
mat[idx[x[1]:x[2], 1],] - mat[idx[x[1]:x[2], 2],]))
V1 V2 V3 V1 V2 V3 V1 V2 V3 V1
1: -4 -1 1 -4 -1 1 -4 -1 1 -4
2: 0 1 -3 0 1 -3 0 1 -3 0
3: 0 0 0 0 0 0 0 0 0 0
4: -4 -1 1 -4 -1 1 -4 -1 1 -4
5: 0 1 -3 0 1 -3 0 1 -3 0
---
1998996: 4 1 -1 4 1 -1 4 1 -1 4
1998997: 0 0 0 0 0 0 0 0 0 0
1998998: 0 -1 3 0 -1 3 0 -1 3 0
1998999: -4 -2 4 -4 -2 4 -4 -2 4 -4
1999000: -4 -1 1 -4 -1 1 -4 -1 1 -4
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))
combn
(以及 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