我想获取一个数据帧(一个数字)的一列的每个元素,将其乘以一个向量以得到一个向量,然后将其乘以一个数据帧中的每一行,将其核心化为一个向量。
代码如下:
df = data.frame(matrix(rexp(1441*100, rate=.1), ncol=100))
out_vec <- c()
for (i in 1:nrow(df)) {
out_vec[i]<- sum(df[i, 5:100] * (1 + abs(df$X1[i])/100) ^ -(0:95 / 12))
}
我如何向量化此代码?我尝试过
out_vec_alt <- rowSums(df[, 5:100] * (1 + abs(df$X1)/100) ^ -(0:95 / 12))
但未产生预期的结果:
all(out_vec_alt == out_vec) #FALSE
答案 0 :(得分:3)
第二部分需要使用outer
完成。您可以以向量化方式使用a^b
,但不会将操作应用于a
的第一个元素,而不是b
的所有元素,a
的第二个元素与b
等所有元素的比较,例如在这种情况下它只会给出c(a[1]^b[1], a[2]^b[2], ..., a[n]^b[n])
。
out_vec2 <- rowSums(df[5:100] * outer(1 + abs(df$X1)/100, -(0:95)/12, `^`))
all.equal(out_vec, out_vec2)
# [1] TRUE
显然这会更快,但令我惊讶的是,此示例的速度(中位数时间)快了200倍以上
loop <- function(){
out_vec <- c()
for (i in 1:nrow(df)) {
out_vec[i]<- sum(df[i, 5:100] * (1 + abs(df$X1[i])/100) ^ -(0:95 / 12))
}
out_vec
}
vect <- function() rowSums(df[5:100] * outer(1 + abs(df$X1)/100, -(0:95)/12, `^`))
library(microbenchmark)
microbenchmark(loop(), vect(), times = 10)
# Unit: milliseconds
# expr min lq mean median uq max neval
# loop() 12065.34780 12756.12062 13095.97435 12892.87818 13460.56978 15030.0197 10
# vect() 35.73011 41.36212 60.57327 54.40029 79.25182 104.0453 10