基于data.frame高效地从矩阵中减去向量
我有一个矩阵X,两个数据帧a和B,以及向量向量vec_a和vec_B。A和B各包含一个索引变量,其中的值对应于vec_A和vec_B中的值。除此之外,A和B包含的值与X中的列数量相同: 请注意,我们必须在循环解决方案中转换为数值,否则,当我们从矩阵中减去data.frame时,X将丢失类矩阵。我的解决方案很好用,直到你需要对许多矩阵,比如A和B,以及数百万的观测值这样做。是否有一种解决方案不依赖于在所有行上循环 编辑 谢谢,这两个答案都大大提高了代码的速度。我选择了StupidWolf的答案,因为它比使用数据更有效。表: 这种方法使用data.table以方便连接基于data.frame高效地从矩阵中减去向量,r,matrix,vector,R,Matrix,Vector,我有一个矩阵X,两个数据帧a和B,以及向量向量vec_a和vec_B。A和B各包含一个索引变量,其中的值对应于vec_A和vec_B中的值。除此之外,A和B包含的值与X中的列数量相同: 请注意,我们必须在循环解决方案中转换为数值,否则,当我们从矩阵中减去data.frame时,X将丢失类矩阵。我的解决方案很好用,直到你需要对许多矩阵,比如A和B,以及数百万的观测值这样做。是否有一种解决方案不依赖于在所有行上循环 编辑 谢谢,这两个答案都大大提高了代码的速度。我选择了StupidWolf的答案,因
library(data.table)
set.seed(111)
X <- matrix(rnorm(200),100,2)
A <- data.frame(index_a = 1:4, value1 = rnorm(4), value2 = rnorm(4))
B <- data.frame(index_b = 1:4, value1 = rnorm(4), value2 = rnorm(4))
vec_a <- sample(1:4, nrow(X), replace = T)
vec_b <- sample(1:4, nrow(X), replace = T)
setDT(A);setDT(B)
dtX <- as.data.table(cbind(1:nrow(X),X,vec_a,vec_b))
as.matrix(
dtX[A, on = .(vec_a = index_a)][B,
on = .(vec_b = index_b)][order(V1),
.(V2 - (value1 - i.value1), V3 - (value2 - i.value2))]
)
V1 V2
[1,] 0.22746 0.7069
[2,] 1.84340 -0.1258
[3,] -0.70038 1.2494
...
[98,] 2.04666 0.6767
[99,] 0.02451 1.0473
[100,] -2.72553 -0.6595
希望这对于非常大的矩阵来说会非常快 此方法使用data.table以方便连接
library(data.table)
set.seed(111)
X <- matrix(rnorm(200),100,2)
A <- data.frame(index_a = 1:4, value1 = rnorm(4), value2 = rnorm(4))
B <- data.frame(index_b = 1:4, value1 = rnorm(4), value2 = rnorm(4))
vec_a <- sample(1:4, nrow(X), replace = T)
vec_b <- sample(1:4, nrow(X), replace = T)
setDT(A);setDT(B)
dtX <- as.data.table(cbind(1:nrow(X),X,vec_a,vec_b))
as.matrix(
dtX[A, on = .(vec_a = index_a)][B,
on = .(vec_b = index_b)][order(V1),
.(V2 - (value1 - i.value1), V3 - (value2 - i.value2))]
)
V1 V2
[1,] 0.22746 0.7069
[2,] 1.84340 -0.1258
[3,] -0.70038 1.2494
...
[98,] 2.04666 0.6767
[99,] 0.02451 1.0473
[100,] -2.72553 -0.6595
希望这对于非常大的矩阵来说会非常快 您可以只匹配行:
set.seed(111)
# original data
X <- matrix(rnorm(200),100,2)
A <- data.frame(index_a = 1:4, value1 = rnorm(4), value2 = rnorm(4))
B <- data.frame(index_b = 1:4, value1 = rnorm(4), value2 = rnorm(4))
vec_a <- sample(1:4, nrow(X), replace = T)
vec_b <- sample(1:4, nrow(X), replace = T)
newX <- X - as.matrix(A[match(vec_a,A$index_a),-1]-B[match(vec_b,B$index_b),-1])
匹配应该非常快,但如果仍然太慢,您可以使用vec_A调用A的值,如[vec_A,].您可以只匹配行:
set.seed(111)
# original data
X <- matrix(rnorm(200),100,2)
A <- data.frame(index_a = 1:4, value1 = rnorm(4), value2 = rnorm(4))
B <- data.frame(index_b = 1:4, value1 = rnorm(4), value2 = rnorm(4))
vec_a <- sample(1:4, nrow(X), replace = T)
vec_b <- sample(1:4, nrow(X), replace = T)
newX <- X - as.matrix(A[match(vec_a,A$index_a),-1]-B[match(vec_b,B$index_b),-1])
匹配应该非常快,但是如果仍然太慢,您可以使用vec_A调用A的值,比如[vec_A,]
set.seed(111)
# original data
X <- matrix(rnorm(200),100,2)
A <- data.frame(index_a = 1:4, value1 = rnorm(4), value2 = rnorm(4))
B <- data.frame(index_b = 1:4, value1 = rnorm(4), value2 = rnorm(4))
vec_a <- sample(1:4, nrow(X), replace = T)
vec_b <- sample(1:4, nrow(X), replace = T)
newX <- X - as.matrix(A[match(vec_a,A$index_a),-1]-B[match(vec_b,B$index_b),-1])
for(iii in 1:nrow(X)){
X_clean <- A[which(A$index_a == vec_a[iii]),-1] - # subtract correct A value
B[which(B$index_b == vec_b[iii]),-1] # subtract correct B value
X_clean <- as.numeric(X_clean)
X[iii,] = X[iii,] - X_clean
}
all.equal(c(newX),c(X))
[1] TRUE