问题描述
我正在尝试获取特定列中每第三(或第二)行的滚动平均值。更准确地说,我希望将滚动平均值存储在现有数据框中的新变量中。
我尝试使用此功能:
w %>%
mutate(rmean = roll_meanl(SWI_001,3)) %>%
filter(between(date,2,4)) %>%
select(-date)
我想要变量 SWI_001 的每第三行的滚动平均值。带有数据的新变量应该是 roll_mean1。
但我不知道如何正确过滤它。
我的数据框 (w) 看起来像这样,但是总共有 255 行和近 50 列:
Date ASS_SUB ASS_TOP SWI_001 SWI_005 SWI_010 SWI_100 B1_005 B1_015 B1_025 B1_035 B1_045 B1_055 B1_065
1: 06.11.2018 17.37 14.16 15.54 NA 15.57 NA NA NA NA NA NA NA NA
2: 07.11.2018 17.32 13.90 15.21 NA 15.51 NA 14.4 14.8 14.8 14.8 14.8 14.8 14.8
3: 08.11.2018 17.29 13.77 14.75 NA 15.39 NA 14.2 14.8 14.8 14.8 14.8 14.8 14.8
4: 09.11.2018 17.27 13.64 15.05 NA 15.38 NA 14.0 14.8 14.8 14.8 14.8 14.8 14.8
5: 10.11.2018 17.24 13.64 14.89 NA 15.30 NA 13.9 14.8 14.8 14.8 14.8 14.8 14.8
---
最后,我需要的不仅仅是一列的滚动均值,但一开始我很高兴能朝正确的方向推动。
解决方法
有很多不同的方法来做到这一点:
- 您可以使用
zoo
包 (rollmean
) 中的滚动均值/最大值/中位数函数 - 在
MovingAverages
中使用TTR
- 在
ma
中使用forecast
另见此处:Calculating moving average
对于下一个问题,如果您可以使用 dput()
将数据包含在您列出的代码中,那就太好了 - 我尝试快速重新创建它:
library(tidyverse)
tibble::tribble(
~Date,~ASS_SUB,~ASS_TOP,~SWI_001,~SWI_005,~SWI_010,~SWI_100,~B1_005,~B1_015,~B1_025,~B1_035,~B1_045,~B1_055,~B1_065,"06.11.2018",17.37,14.16,15.54,NA,15.57,"07.11.2018",17.32,13.90,15.21,15.51,14.4,14.8,"08.11.2018",17.29,13.77,14.75,15.39,14.2,"09.11.2018",17.27,13.64,15.05,15.38,14.0,"10.11.2018",17.24,14.89,15.30,13.9,14.8
) -> w
对于您的示例,我将使用 rollmean
包中的 zoo
。我们使用 fill = NA
选项来指示没有 3 个值(一个之前,一个之后)的值应该是 NA
。这意味着您不必过滤数据。您当然可以修改它 - 使用 ?na.fill
查看更多信息。
library(zoo)
w %>%
mutate(rmean = rollmean(SWI_001,3,fill = NA))
如果要将其应用于大量列,可以使用 across()
包中的 dplyr
命令:
w %>%
mutate(across(.cols = c(SWI_001,SWI_010),.fns = ~rollmean(.,fill = NA),.names = "{.col}_rmean"))
甚至对于所有数字列:
w %>%
mutate(across(.cols = where(is.numeric),.names = "{.col}_rmean"))
关于过滤的更多信息:
我不确定 1:
、2:
等是您的 Date
变量(下面的案例 1)还是只是行号(案例 2)的一部分。但无论如何,我建议使用以下任一方法将列转换为 Date
格式:
案例 1:
w %>%
mutate(Date = gsub("[0-9]: ","",Date),Date = as.Date(Date,format = "%d.%m.%Y"))
情况 2:
w %>%
mutate(Date = as.Date(Date,format = "%d.%m.%Y"))
一旦你有了这个,你就可以轻松地使用(并从上面组合):
w %>%
mutate(Date = gsub("[0-9]: ",format = "%d.%m.%Y")) %>%
mutate(across(.cols = c(SWI_001,.names = "{.col}_rmean")) %>%
filter(between(Date,as.Date("2018-11-07"),as.Date("2018-11-09")))