Вторая часть должна быть сделана с 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