dplyr中的变异函数不适用于滚动平均值/移动平均值

时间:2018-08-14 00:33:03

标签: r dplyr zoo

首先,无论您是否输入内容,谢谢您抽出宝贵时间来查看我的问题。

让我分解一下我在做什么,样本数据集和错误。

我目前拥有的是几个不同ID的数据,这些数据列出了每天的分散情况。 (您将在下面看到)。我想遍历日期并将两列添加到数据中:滚动平均值列和滚动标准差列

到目前为止,我写的代码是:

library(zoo)
Testing1 <- function(dataset, k) {
ops <- data.frame()  
for (i in unique(dataset$Date)) {  
ops <- dataset %>% mutate(rolling_mean = rollmean(dataset$Dispersion,k)) %>% 
mutate(rolling_std = rollapply(dataset$Dispersion, width = k, FUN = sd))
}
Results <<- ops 
}

但是,出现以下错误:

  

mutate_impl(.data,点)中的错误:     rolling_mean列的长度必须为30(行数)或1,而不是26

我假设行差异是由于我为滚动平均值指定了5天窗,这意味着它不会为前4行计算它。但是我该如何告诉R在这些行上输入NA是可以的呢?或者,如果你们还有其他解决方案,那也可以。请帮忙。

这里有一个数据样本:

Identifier  Date    Dispersion
1000    2/15/2018   0.390
1000    2/16/2018   0.664
1000    2/17/2018   0.526
1000    2/18/2018   0.933
1000    2/19/2018   0.009
1000    2/20/2018   0.987
1000    2/21/2018   0.517
1000    2/22/2018   0.641
1000    2/23/2018   0.777
1000    2/24/2018   0.613
1001    2/15/2018   0.617
1001    2/16/2018   0.234
1001    2/17/2018   0.303
1001    2/18/2018   0.796
1001    2/19/2018   0.359
1001    2/20/2018   0.840
1001    2/21/2018   0.291
1001    2/22/2018   0.699
1001    2/23/2018   0.882
1001    2/24/2018   0.467
1002    2/15/2018   0.042
1002    2/16/2018   0.906
1002    2/17/2018   0.077
1002    2/18/2018   0.156
1002    2/19/2018   0.350
1002    2/20/2018   0.060
1002    2/21/2018   0.457
1002    2/22/2018   0.770
1002    2/23/2018   0.433
1002    2/24/2018   0.366

2 个答案:

答案 0 :(得分:1)

您会收到此错误,因为滚动平均值/标准差的长度与色散的长度不匹配。只需在您的均值/标准差向量的开头添加 k-1 NA

下面是一个有效的示例。您可以根据需要进行修改。

my_function <- function(df, k) {
  df %>%
    mutate(
      rolling_mean = c(rep(NA, k - 1), rollmean(Dispersion, k)),
      rolling_std = c(rep(NA, k - 1), rollapply(Dispersion, width = k, FUN = sd))
    )
}

例如,您可能想添加group_by来为每个标识符 计算这些值:

my_function <- function(df, k) {
  df %>%
    group_by(Identifier) %>%
    mutate(
      rolling_mean = c(rep(NA, k - 1), rollmean(Dispersion, k)),
      rolling_std = c(rep(NA, k - 1), rollapply(Dispersion, width = k, FUN = sd))
    )
}

更新跟进@G。格洛腾迪克的评论:

事实证明,软件包zoo已经具有用于NA处理的综合功能,将上述代码重构为:

my_function <- function(df, k) {
  df %>%
    mutate(
      rolling_mean = rollmeanr(Dispersion, k, fill = NA),
      rolling_std = rollapplyr(Dispersion, width = k, FUN = sd, fill = NA)
    )
}

答案 1 :(得分:0)

我来看看tibbletime

假设您的数据帧命名为mydata,而Date列是一个字符:首先转换Date,然后转换为可识别时间的小标题:

library(dplyr)
library(tibbletime)

mydata <- mydata %>% 
  mutate(Date = as.Date(Date, "%m/%d/%Y")) %>% 
  as_tbl_time(index = Date)

现在,您可以定义用于滚动均值和sd的函数:

mean_5 <- rollify(mean, window = 5) 
sd_5   <- rollify(sd,   window = 5) 

mydata %>% 
  mutate(rolling_mean = mean_5(Dispersion),
         rolling_std  = sd_5(Dispersion))

# A time tibble: 30 x 5
# Index: Date
   Identifier Date       Dispersion rolling_mean rolling_std
        <int> <date>          <dbl>        <dbl>       <dbl>
 1       1000 2018-02-15      0.39        NA          NA    
 2       1000 2018-02-16      0.664       NA          NA    
 3       1000 2018-02-17      0.526       NA          NA    
 4       1000 2018-02-18      0.933       NA          NA    
 5       1000 2018-02-19      0.009        0.504       0.342
 6       1000 2018-02-20      0.987        0.624       0.393
 7       1000 2018-02-21      0.517        0.594       0.394
 8       1000 2018-02-22      0.641        0.617       0.393
 9       1000 2018-02-23      0.777        0.586       0.367
10       1000 2018-02-24      0.613        0.707       0.182
# ... with 20 more rows