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))
从1998年开始,我想为每个ID做y
的7年滚动平均值。但是,条件是在每个滚动窗口中,
我只选择y的前5个最高值进行平均。例如。
第一个滚动窗口为
1998-2004年-仅对前5个最高“ y”值进行平均
1999-2005年-仅对前5个最高“ y”值进行平均 。
2007-2013年-仅对前5个最高的“ y”值进行平均
2008-2014年-仅对前5个最高的“ y”值进行平均
我对使用data.table实现这一目标很感兴趣。但是也有其他建议。这是我尝试过的
d = setDT(d)
d[, avg.Y := frollmean(y, 7), by = ID]
如何输入另一个参数,其中对于每个滚动的7年窗口,我仅选择前5个最高y值来计算均值?
我还可能会遇到这样的情况,即某些ID现在可能至少需要7年的数据才能进行移动平均,在这种情况下,上述函数会给我NA。对于这些ID,是否可以简单地采用算术平均值?例如如果某个ID拥有1998-2002年的数据,在这种情况下,我可以简单地获取1998-2002年y
的平均值
答案 0 :(得分:2)
首次使用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]]))
答案 1 :(得分:2)
我们可以使用rollapplyr
中的zoo
并应用自定义函数来计算每个滚动窗口中前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]
答案 2 :(得分:1)
更多步骤和一些重复的基本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))