【问题标题】:R make a more efficient rolling varianceR 做出更有效的滚动方差
【发布时间】:2018-12-07 06:18:23
【问题描述】:

我有一个名为 features 的数据表,其中包含 nightNo、HR、motion 和 angle 列。我想获得每晚 HR、运动和角度的前 600 点的滚动方差。为此,我提出了以下功能:

features <- data.table(nightNo=c(1,1,1,1,1,1,1,2,2,2,2,2,2,2),
                       HR=c(1,2,3,4,5,6,7,8,9,10,11,12,13,14),
                       motion=c(14,13,12,11,10,9,8,7,6,5,4,3,2,1),
                       angle=c(2,4,6,8,10,12,14,16,18,20,22,24,26,28))

# For the example I'll use a window of 6 instead of 600
window = 6
features[, c("HR_Variance", "motion_Variance", "angle_Variance") := 
       list(rollapply(HR, window, var, partial=TRUE, align = "right"), 
            rollapply(motion, window, var, partial=TRUE, align = "right"), 
            rollapply(angle, window, var, partial=TRUE, align = "right")), by=nightNo ]

#    nightNo HR motion angle HR_Variance motion_Variance angle_Variance
# 1:       1  1     14     2          NA              NA             NA
# 2:       1  2     13     4    0.500000        0.500000       2.000000
# 3:       1  3     12     6    1.000000        1.000000       4.000000
# 4:       1  4     11     8    1.666667        1.666667       6.666667
# 5:       1  5     10    10    2.500000        2.500000      10.000000
# 6:       1  6      9    12    3.500000        3.500000      14.000000
# 7:       1  7      8    14    3.500000        3.500000      14.000000
# 8:       2  8      7    16          NA              NA             NA
# 9:       2  9      6    18    0.500000        0.500000       2.000000
# 10:      2 10      5    20    1.000000        1.000000       4.000000
# 11:      2 11      4    22    1.666667        1.666667       6.666667
# 12:      2 12      3    24    2.500000        2.500000      10.000000
# 13:      2 13      2    26    3.500000        3.500000      14.000000
# 14:      2 14      1    28    3.500000        3.500000      14.000000

结果是正确的,但由于我有一个大型数据集,它会永远运行。我还制作了其他类似的功能,这些功能在每晚 600 个窗口上使用 runmeans 和 sapplys,它们在合理的时间内运行,这让我认为 rollapply 或方差函数非常慢。有没有办法让这段代码更高效,可能是通过改变 var 或 rollapply 函数?

【问题讨论】:

  • 可以使用RcppRoll::roll_var,也可以查看github.com/Rdatatable/data.table/issues/2778
  • 您的预期输出与给定数据不匹配
  • @chinsoon12 遗憾的是,roll_var 还没有实现我需要的部分。
  • @Jimbou 我错过了 6 角,感谢提醒。
  • 在调用 roll_var 时,您始终可以在前面附加 NA

标签: r data.table variance rollapply


【解决方案1】:

我不知道 rollaplly 正在做什么,但我使用可能更快的并行 tidyverse 在给定的样本数据上生成此输出

library(cumstats)
library(tidyverse)
library(furrr)

plan(multiprocess)
window <- 6

features %>% 
  nest(-nightNo) %>% 
  mutate(data=future_map(data,~mutate_at(.,vars(HR, motion,angle), 
                funs(var=cumvar(.)[c(1:window,rep(window,length(.)-length(1:window)))])))) %>% 
  unnest()
# A tibble: 14 x 7
   nightNo    HR motion angle HR_var motion_var angle_var
     <dbl> <dbl>  <dbl> <dbl>  <dbl>      <dbl>     <dbl>
 1       1     1     14     2  NA         NA        NA   
 2       1     2     13     4   0.5        0.5       2   
 3       1     3     12     6   1          1         4   
 4       1     4     11     8   1.67       1.67      6.67
 5       1     5     10    10   2.5        2.5      10   
 6       1     6      9    12   3.5        3.5      14   
 7       1     7      8    14   3.5        3.5      14   
 8       2     8      7    16  NA         NA        NA   
 9       2     9      6    18   0.5        0.5       2   
10       2    10      5    20   1          1         4   
11       2    11      4    22   1.67       1.67      6.67
12       2    12      3    24   2.5        2.5      10   
13       2    13      2    26   3.5        3.5      14   
14       2    14      1    28   3.5        3.5      14 

【讨论】:

  • 这在 6 窗口上似乎稍微快一些,但在 600 窗口上它给出错误“mutate_impl(.data, dots) 中的错误:评估错误:无效的 'times' 参数。 ”。我对使用的任何库和函数都不熟悉,知道是什么原因造成的吗?
  • @Henk 每个nightNo 600 个条目?
  • 不,大多数人有,少数人少。
  • 好的。如果窗口大小比条目长,则会产生错误。使用此方法,您必须将窗口大小设置为小于每个 nightNo 的最小条目数。我可以解决这个问题,但您必须提供一些示例数据来说明该问题。
  • 我使用了 roll_var 并按照 chinsoon12 的建议附加了 NA,然后在 NA 上使用了我原来的 rollapply。在窗口为 6 的样本上,roll_var 的速度要快 10 倍以上,并且似乎在合理的情况下使用 600 窗口来处理整个数据,所以我想我会这样做。感谢您的回复并提供修复错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-21
  • 1970-01-01
  • 2011-07-06
相关资源
最近更新 更多