我有一个看起来像这样的数据集:
data <- data.frame( date = rep(c(1:10),5), obs = c(1:50) )
其中一列中有日期,另一列中我有一个变量obs
.我想使用dplyr
计算每行变量的平均值,obs
在date
值的 2 天内进行观测,不包括当前的date
行。
13
行中的date = 3
,我想获取date
等于 1、2、3、4 和 5 的所有行,并取这些行obs
值的平均值,不包括第13
行中的obs
值。这将产生:
mean(c(1:5, 11, 12, 14, 15, 21:25, 31:35, 41:45))
# 23.41667
在那里你可以看到我采取了1
到5
之间的日期的所有观测值,但我省略了第13
行的观测值。
理想情况下,我想在任何日期进行:我的数据集没有连续的日期,或者同一天可能有多个观测值。因此,如果数据集如下所示:
data <- data.frame( date = c(rep(c(1:10),5), 3), obs = c(1:51) )
如果日期3
重复两次,我想在第13
行中获得以下平均值:
mean(c(1:5, 11, 12, 14, 15, 51, 21:25, 31:35, 41:45))
# 24.52
第51
行中的以下含义:
mean(c(1:5, 11:15, 21:25, 31:35, 41:45))
# 23
基本上,对于每一行,我希望在该特定行中日期的 2 天(+- 2 天(内发生列obs
的所有other
观测值的平均值。
如果我们想获得 4 个值的平均值,即上面 2 个值,下面 2 个不包括该值,请使用循环
sapply(seq_len(nrow(data)), function(i)
mean(data$obs[pmax(0, setdiff((i-2):(i+2), i))], na.rm = TRUE))
或者将rollapply
与partial = TRUE
一起使用
library(zoo)
library(dplyr)
data %>%
mutate(avg = (rollapply(obs, width = 5, FUN = "sum", align = "center",
fill = NA, partial = TRUE) - obs)/rep(c(2:4, 3:2), c(1, 1, n()-4, 1, 1)))
使用dplyr
:
解决方案 1 是从实际日期的下方 2 行和上方 2 行计算平均值:
data %>%
mutate(temp1 = lag(obs, 1),
temp2 = lag(obs, 2),
temp3 = lead(obs, 1),
temp4 = lead(obs, 2)) %>%
mutate(mean = rowMeans(cbind(temp1,temp2, temp3, temp4), na.rm = TRUE)) %>%
select(date, obs, mean)
解决方案 2 是从实际日期的下方 2 行和上方 2 行计算平均值,但考虑日期的所有出现:
data %>%
mutate(temp1 = lag(obs, 1),
temp2 = lag(obs, 2),
temp3 = lead(obs, 1),
temp4 = lead(obs, 2)) %>%
group_by(date) %>%
mutate(n = n(),
mean = sum(temp1, temp2, temp3, temp4, na.rm = TRUE)/(4*n)) %>%
ungroup() %>%
select(date, obs, mean)