r——条件滚动平均


library(data.table)
set.seed(123)
d <- data.frame(ID = rep(1:5, each = 17), yearRef = rep(1998:2014, times = 5), y = sample(1:100, 17 * 5)) 

对于每个ID,我想从1998年开始对y进行7年的滚动平均。但是条件是在每个滚动窗口中,我只选择y的前5个最高值来做平均值。例如

第一个滚动窗口是

1998-2004-只做前5个最高"y"值的平均值

1999-2005年-只计算前5个最高"y"值的平均值。.

2007-2013-只做前5个最高"y"值的平均值

2008-2014-只做前5个最高"y"值的平均值

我对使用数据感兴趣。能够实现这一点。不过也对其他建议持开放态度。以下是我尝试的

d = setDT(d)
d[, avg.Y := frollmean(y, 7), by = ID]

如何输入另一个参数,即对于每个滚动的7年窗口,我只选择前5个最高的y值来计算平均值?

编辑

我也可能遇到这样的情况,即一些ID可能没有至少7年的数据来进行移动平均,在这种情况下,上述函数将为我提供NA。对于这些ID,是否可以简单地取算术平均值?例如,如果ID有1998-2002年的数据,在这种情况下,我可以简单地取1998-2002年的y的平均值吗

我们可以使用zoo中的rollapplyr,并应用自定义函数来计算每个滚动窗口中前5个值的mean

library(data.table)
library(zoo)
setDT(d)
d[, avg.Y:= rollapplyr(y, 7,function(x) mean(tail(sort(x), 5)), fill = NA), by = ID]

对于观察次数可能少于窗口大小的情况,我们可以进行

d[, avg.Y:= if (.N > 6) 
rollapplyr(y, 7,function(x) mean(tail(sort(x), 5)), fill = NA)  
else mean(y), by = ID]

第一次使用frollapply(),但这似乎有效:

get_mean_top5 <- function(x) mean(-sort(-x, partial = 1:5)[1:5])
d[, test := frollapply(y, 7, FUN = get_mean_top5), by = ID]

函数get_mean_top5()过滤掉前5个最高值,然后取平均值。其他更可读的形式是:

get_mean_top5 <- function(x) mean(mean(x[order(x, decreasing=TRUE)[1:5]]))

更多的步骤和一点重复的基本R解决方案:

df$seven_year_group <-  paste0(ave(as.integer(as.factor(df$yearRef)) %% 7,
as.integer(as.factor(df$yearRef)) %% 7,
FUN = seq.int), 
"_",
df$ID)
seven_year_averages <- data.frame(avg_y = do.call("rbind", lapply(split(df, df$seven_year_group),
function(x){mean(tail(x[order(x$y), "y"], 5))})))

seven_year_averages$seven_year_group <- row.names(seven_year_averages)
df <- merge(df, seven_year_averages, by = "seven_year_group", all.x = TRUE)

数据:

set.seed(2019)
df <- data.frame(ID = rep(1:5, each = 17), yearRef = rep(1998:2014, times = 5), y = sample(1:100, 17 * 5))

最新更新