【问题标题】:How to subtract rolling average from each observation with multiple groups in R如何从 R 中的多个组的每个观察中减去滚动平均值
【发布时间】:2021-03-03 11:07:20
【问题描述】:

我有来自两个站点(SiteIDAB)的水温时间序列(Wtemp)测量值。我想计算 Wtemp 的中心 7 天移动平均值,然后从每个组的 Wtemp 观察值中减去该移动 7 天平均值。

这是一个示例数据框:

df <- data.frame(matrix(ncol = 3, nrow = 28))
x <- c("siteID", "Date", "Wtemp")
colnames(df) <- x
df[1:14,1] <- rep("A",14)
df[15:28,1] <- rep("B",14)
df$Date <- rep(seq(from = as.Date("2020-01-01"), to = as.Date("2020-01-14"), by = 1),2)  
set.seed(123)
df[1:14,3] <- rnorm(14, 10, 1)
df[15:28,3] <- rnorm(14, 20, 2)

理想的输出应该是这样的:

   siteID       Date Wtemp WtempMean WtempDiff
1       A 2020-01-01  8.86        NA        NA
2       A 2020-01-02 11.25        NA        NA
3       A 2020-01-03 10.43        NA        NA
4       A 2020-01-04  9.70     10.41     -0.71
5       A 2020-01-05 10.90     10.67      0.23
6       A 2020-01-06 10.88     10.57      0.31
7       A 2020-01-07 10.82     10.50      0.32
8       A 2020-01-08 10.69     10.50      0.19
9       A 2020-01-09 10.55     10.31      0.24
10      A 2020-01-10  9.94     10.09     -0.15
11      A 2020-01-11  9.69      9.94     -0.25
12      A 2020-01-12  9.62        NA        NA
13      A 2020-01-13  9.31        NA        NA
14      A 2020-01-14  9.79        NA        NA
15      B 2020-01-01 17.47        NA        NA
16      B 2020-01-02 24.34        NA        NA
17      B 2020-01-03 22.42        NA        NA
18      B 2020-01-04 17.75     20.26     -2.51
19      B 2020-01-05 19.19     20.59     -1.40
20      B 2020-01-06 19.07     20.05     -0.98
21      B 2020-01-07 21.56     19.69      1.87
22      B 2020-01-08 19.83     20.00     -0.17
23      B 2020-01-09 20.51     20.51      0.00
24      B 2020-01-10 19.94     20.58     -0.64
25      B 2020-01-11 19.91     20.79     -0.88
26      B 2020-01-12 22.74        NA        NA
27      B 2020-01-13 19.55        NA        NA
28      B 2020-01-14 23.03        NA        NA

我认为这可以使用 sapplyzoo 包中的函数 rollmean 来完成,但我不确定当有多个组时如何有效地完成(即 siteID

【问题讨论】:

    标签: r dataframe


    【解决方案1】:

    rollmean 计算每个siteID 的7 天滚动平均值,然后用Wtemp 减去该值。

    library(dplyr)
    library(zoo)
    
    df %>%
      group_by(siteID) %>%
      mutate(WtempMean = rollmean(Wtemp, 7, fill = NA), 
             WtempDiff = Wtemp - WtempMean) %>%
      ungroup
    
    #   siteID Date       Wtemp WtempMean WtempDiff
    #   <chr>  <date>     <dbl>     <dbl>     <dbl>
    # 1 A      2020-01-01  9.44      NA      NA    
    # 2 A      2020-01-02  9.77      NA      NA    
    # 3 A      2020-01-03 11.6       NA      NA    
    # 4 A      2020-01-04 10.1       10.4    -0.379
    # 5 A      2020-01-05 10.1       10.3    -0.219
    # 6 A      2020-01-06 11.7       10.3     1.43 
    # 7 A      2020-01-07 10.5       10.0     0.464
    # 8 A      2020-01-08  8.73      10.2    -1.43 
    # 9 A      2020-01-09  9.31      10.2    -0.881
    #10 A      2020-01-10  9.55      10.0    -0.453
    # … with 18 more rows
    

    PS - 我用相同的种子得到了不同的随机数。

    【讨论】:

    • 如果我想计算左侧或右侧而不是中心的 rollmean,这将如何工作?
    • 您可以在rollmean 中使用align = 'left'align = 'right'。默认为align = 'center'
    猜你喜欢
    • 2019-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-08
    相关资源
    最近更新 更多