R-sapply для стандартного отклонения возвращает столбец NA - PullRequest
0 голосов
/ 25 октября 2018

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

Вот как я создал вектор и как он выглядит:

 Returns_Close_exp<-diff(log(Data_new$Close_exp), lag=1)
 Returns_Close_exp<-append(Returns_Close_exp,"",0)
 Returns_Close_exp<-as.numeric(Returns_Close_exp)

Голова вектора:

dput(head(Returns_Close_exp))
c(NA, 0, 0.00121876921624686, -0.00121876921624686, -0.00122025634730871, 
-0.00981602975444584)

Что я пытался получить стандартные отклоненияэто:

vol_close_exp<-sapply(Returns_Close_exp,sd)

Но я получаю столбец NA.Кто-нибудь знает, что не так и как это исправить?Спасибо

1 Ответ

0 голосов
/ 25 октября 2018

Есть несколько способов сделать это;используя sapply() для вектора индексов (по существу, в виде цикла), или используя какую-то функцию прокрутки, например, с RcppRoll::roll_sd:

vec <- c(NA, 0, 0.00121876921624686, -0.00121876921624686, -0.00122025634730871,
         -0.00981602975444584)
# Solution with base R
sapply(1:(length(vec)-1), function(i) sd(c(vec[i], vec[i+1])))
#> [1]          NA 8.61800e-04 1.72360e-03 1.05156e-06 6.07813e-03
# Solution with RcppRoll (recommended when performance is key)
RcppRoll::roll_sd(vec, 2)
#> [1]          NA 8.61800e-04 1.72360e-03 1.05156e-06 6.07813e-03

То, что вы делали вначале, это применение функции *От 1006 * до каждого числа в вашем векторе, а sd() одного числа всегда NA.

Обновление: контрольные показатели

Я упомянул RcppRollбыло рекомендовано, когда производительность является ключевым фактором.Давайте посмотрим, насколько быстрее решение RcppRoll:

vec <- c(NA, 0, 0.00121876921624686, -0.00121876921624686, -0.00122025634730871,
         -0.00981602975444584)
# Benchmarks:
library(microbenchmark)
microbenchmark(base = sapply(1:(length(vec)-1), function(i) sd(c(vec[i], vec[i+1]))),
               rcpproll = RcppRoll::roll_sd(vec, 2))
#> Unit: microseconds
#>      expr      min       lq      mean   median        uq       max neval
#>      base 1042.251 1083.269 1264.2698 1133.120 1287.4990 10036.937   100
#>  rcpproll  124.930  133.654  161.4393  145.947  168.3785   286.695   100
#>  cld
#>    b
#>   a
# Let's benchmark with bigger data:
set.seed(123)
vec <- rnorm(1e4)
microbenchmark(base = sapply(1:(length(vec)-1), function(i) sd(c(vec[i], vec[i+1]))),
               rcpproll = RcppRoll::roll_sd(vec, 2))
#> Unit: milliseconds
#>      expr        min          lq       mean      median          uq
#>      base 1966.86067 2063.439484 2141.24892 2134.337090 2198.671640
#>  rcpproll    3.55177    3.701657    4.01187    3.786363    3.904616
#>         max neval cld
#>  2525.95089   100   b
#>    20.71965   100  a
all.equal(sapply(1:(length(vec)-1), function(i) sd(c(vec[i], vec[i+1]))),
          RcppRoll::roll_sd(vec, 2))
#> [1] TRUE
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...