我有一个矩阵X
,两个数据框A
和B
索引vec_a
和的向量vec_b
。A
并且B
每个都包含一个索引变量,其中的值对应于vec_a
和中的值vec_b
。除此之外,A
并且B
包含的值与中的列数一样多X
:
# original data
X <- matrix(rnorm(200),100,2)
# values to substract in data.frames
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))
# indices, which values to substract (one for each row of X)
vec_a <- sample(1:4, nrow(X), replace = T)
vec_b <- sample(1:4, nrow(X), replace = T)
我要实现的目标如下:对于每行iii
中X
的值value1
,分别value2
从A
和B
基于iii
向量vec_a
和中的元素vec_b
。然后,从中的相应行中减去这些值X
。听起来可能有些混乱,但是我希望以下解决方案可以使目标更加明确:
# iterate over all rows of X
for(iii in 1:nrow(X)){
# get correct values
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
# this intermediate step is necessary, otherwise we substract a data.frame from a matrix
X_clean <- as.numeric(X_clean)
# subtract from X
X[iii,] = X[iii,] - X_clean
}
请注意,我们必须numeric
在循环解中转换为,否则X
会matrix
因为data.frame
从中减去a而丢失类matrix
。我的解决方案效果很好,直到您需要对A
和B
以及数百万个观测值的许多矩阵执行此操作为止。是否有不依赖于遍历所有行的解决方案?
编辑
谢谢,两个答案都大大提高了代码的速度。我选择了StupidWolf的答案,因为它比使用data.table
以下方法更有效:
Unit: microseconds
expr min lq mean median uq max neval cld
datatable 5557.355 5754.931 6052.402 5881.729 5975.386 14154.040 100 b
stupid.wolf 818.529 1172.840 1311.784 1187.593 1221.164 4777.743 100 a
loop 111748.790 115141.149 116677.528 116109.571 117085.048 156497.999 100 c
您可以匹配以下行:
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
匹配应该很快,但是如果仍然太慢,则可以只调用A
using的值vec_a
,例如A[vec_a,]
..
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句