Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ajax/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
基于data.frame高效地从矩阵中减去向量_R_Matrix_Vector - Fatal编程技术网

基于data.frame高效地从矩阵中减去向量

基于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的答案,因

我有一个矩阵X,两个数据帧a和B,以及向量向量vec_a和vec_B。A和B各包含一个索引变量,其中的值对应于vec_A和vec_B中的值。除此之外,A和B包含的值与X中的列数量相同:

请注意,我们必须在循环解决方案中转换为数值,否则,当我们从矩阵中减去data.frame时,X将丢失类矩阵。我的解决方案很好用,直到你需要对许多矩阵,比如A和B,以及数百万的观测值这样做。是否有一种解决方案不依赖于在所有行上循环

编辑

谢谢,这两个答案都大大提高了代码的速度。我选择了StupidWolf的答案,因为它比使用数据更有效。表:

这种方法使用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
希望这对于非常大的矩阵来说会非常快

此方法使用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