【发布时间】:2020-05-27 17:25:21
【问题描述】:
我有一个矩阵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)
我想要实现的是:对于X 中的每一行iii,根据向量@ 中的元素iii 从A 和B 中获取值value1 和value2 987654341@ 和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,因为我们从matrix 中减去data.frame。我的解决方案运行良好,直到您需要对许多矩阵(如 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
【问题讨论】: