【问题标题】:How to calculate moving averages in R?如何计算R中的移动平均线?
【发布时间】: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 &lt;- lapply(seq(...), function(year) {...}),函数只返回较小的帧,然后在完成后使用do.call(rbind, frmlst)
  • 如果你的数据不是完美/均匀分布的(也许你错过了一两年),那么另一种方法是使用data.table::foverlaps,它允许按年加入,之后你可以总结(尽管如果没有演示,它可能看起来更晦涩)。
  • 我刚刚添加了一些示例数据

标签: r loops moving-average


【解决方案1】:

假设您的数据没有空白,

set.seed(42)
x <- data.frame(year = 2000:2010, val = sort(runif(11)))

x$rollavg <- zoo::rollmean(x$val, k=3, fill=NA, align="center")
x$rollavg2 <- zoo::rollapply(x$val, FUN=mean, width=3, align="center", partial=TRUE)
x
#    year       val   rollavg  rollavg2
# 1  2000 0.1346666        NA 0.2104031
# 2  2001 0.2861395 0.2928493 0.2928493
# 3  2002 0.4577418 0.4209924 0.4209924
# 4  2003 0.5190959 0.5395277 0.5395277
# 5  2004 0.6417455 0.6059446 0.6059446
# 6  2005 0.6569923 0.6679342 0.6679342
# 7  2006 0.7050648 0.6995485 0.6995485
# 8  2007 0.7365883 0.7573669 0.7573669
# 9  2008 0.8304476 0.8272807 0.8272807
# 10 2009 0.9148060 0.8941097 0.8941097
# 11 2010 0.9370754        NA 0.9259407

其中rollavg 是标准滚动平均值,当可用数据太少时不提供统计信息。如果您想要不完整的平均值,则提供rollavg2

【讨论】:

  • 谢谢。我也要试试这个。但是你看到我的代码中的错误了吗?此外:我的数据确实存在差距。这就是我在汇总命令中使用 na.rm = TRUE 的原因。我没有错过几年,但几年来对变量“学校”的观察都没有。
猜你喜欢
  • 2020-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-18
相关资源
最近更新 更多