Операция векторизации R - PullRequest
       2

Операция векторизации R

0 голосов
/ 13 декабря 2018

Я хотел бы взять каждый элемент столбца кадра данных (число), объединить его в вектор, умножив его на вектор, чтобы получить вектор, а затем умножив его на каждую строку в кадре данных.

Код выглядит следующим образом:

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

1 Ответ

0 голосов
/ 13 декабря 2018

Вторая часть должна быть сделана с 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...