我想计算15天的滚动平均值(向后和向前)。下面是一个测试帧:
date_list = seq(ymd('2000-01-15'),ymd('2010-09-18'),by='day')
testframe = data.frame(Date = date_list)
testframe$Day = substr(testframe$Date, start = 6, stop = 10)
testframe$V1 = runif(3900, 2.0, 35.0)
testframe$V2 = runif(3900, 5.0, 40.0)
testframe$V3 = runif(3900, -10.0, 10.0)
testframe$V4 = seq(from = 5, to = 45, length.out = 3900)
我知道如何计算每一列的值:
library(zoo)
rollmean(testframe$V4, 31)
rollapply(testframe$V4, 31, mean)
但是我如何才能一次对每一列执行此操作呢?我想我必须为此排除Day和Date列,但是我如何在命令中做到这一点呢?我如何才能在使用NAs的旧测试帧中获得前15天和最后15天的结果?
我试过这个:
testframe[paste0("new_col",1:4)] <- lapply(testframe[,3:6], rollapply, FUN = mean, width = 31)
但是它不起作用!
发布于 2019-06-12 14:11:15
rollmean和rollapply的默认操作是对每一列执行操作。请查看?rollapply
。
library(zoo)
rollmeanr(BOD, 2, fill = NA)
给出了将滚动平均值应用于内置BOD的每一列的如下内容:
Time demand
[1,] NA NA
[2,] 1.5 9.30
[3,] 2.5 14.65
[4,] 3.5 17.50
[5,] 4.5 15.80
[6,] 6.0 17.70
如果您只想将平均值应用于某些列,则指定:
if (exists("BOD", .GlobalEnv)) rm(BOD)
BOD[1:2] <- rollmeanr(BOD[1:2], 2, fill = NA)
请注意,如果您拥有除索引列之外的所有数值列,那么只使用zoo对象会比尝试强制将所有内容都拟合到data.frames中要容易得多,因为这对时间序列不起作用。
if (exists("BOD", .GlobalEnv)) rm(BOD)
z <- read.zoo(BOD)
rollmeanr(z, 2)
发布于 2019-06-12 14:17:34
虽然@G.Grothendieck的答案在很多方面都更好,但这里有一些在你的案例中可能出现问题的上下文:
testframe[paste0("new_col",1:4)] <- lapply(testframe[,3:6], rollapply, FUN = mean, width = 31)
# Error in mean.default(X[[i]], ...) : 'trim' must be numeric of length one
这在一定程度上是因为您传递的是FUN=
,但这也是lapply
参数的名称,因此它在那里得到了有效的使用:
testframe[paste0("new_col",1:4)] <- lapply(testframe[,3:6], function(a) mean(a, trim=rollapply, width = 31))
mean
的第二个参数是trim=
,在本例中,它被传递给了函数rollapply
,显然是不正确的。
下一步将是
testframe[paste0("new_col",1:4)] <- lapply(testframe[,3:6], function(a) rollapply(a, FUN = mean, width = 31))
# Error in `[<-.data.frame`(`*tmp*`, paste0("new_col", 1:4), value = list( :
# replacement element 1 has 3870 rows, need 3900
这是因为单个rollapply
没有返回第一个/最后15个值(导致少了30个观察值)。您可以使用fill=NA
修复此问题
testframe[paste0("new_col",1:4)] <- lapply(testframe[,3:6], function(a) rollapply(a, FUN = mean, width = 31, fill = NA))
# (no warnings/errors)
https://stackoverflow.com/questions/56564132
复制