【发布时间】:2019-10-29 22:43:49
【问题描述】:
我想计算重叠世代的移动平均值。例如。 1915年的值应该包括1900-1930年的平均值,1916年的值应该包括1901-1931年的平均值等等。我在下面写了以下函数和循环:
calc_mean = function(data_frame, yr, time_generation){
df_MM = data_frame %>%
filter(yr >= year & yr < year + time_generation) %>%
summarize(school_mean = mean(school, na.rm = TRUE)) %>%
mutate(year = year + gen_interval/2)
return(df_MM)
}
time_generation = 30;
# Preallocation
df_mean = data.frame()
for(year in seq(from = 1900, to = 1960, by = 1)){
df_MM = calc_mean(df_school, yr = year, time_generation)
df_mean = rbind(df_mean, df_MM)
}
remove(df_MM)
但是,如果我对一个小样本进行交叉检查,我会得到错误的值。你看到我的错误了吗?
让我给你一个小样本,让你自己检查:
set.seed(2)
df_school <- data.frame(year = 1900:1960, val = sort(runif(61)))
【问题讨论】:
-
缺少示例数据,很难给你好的代码,但试试
zoo::rollmean(data_frame$school, k=31, fill=NA, align="center")。顺便说一句:使用for循环和rbind迭代地构建一个框架对于一些小事情来说可以正常工作,但是它的扩展性可怕:每次调用rbind时,它都会生成一个完整的副本所有数据,所以如果这不是很小的,它会慢一点。最好使用frmlst <- lapply(seq(...), function(year) {...}),函数只返回较小的帧,然后在完成后使用do.call(rbind, frmlst)。 -
如果你的数据不是完美/均匀分布的(也许你错过了一两年),那么另一种方法是使用
data.table::foverlaps,它允许按年加入,之后你可以总结(尽管如果没有演示,它可能看起来更晦涩)。 -
我刚刚添加了一些示例数据
标签: r loops moving-average