如何仅为新行计算移动平均值

时间:2019-02-06 10:56:47

标签: r

我有一个巨大的数据框,需要花费40多分钟来计算几列上的简单移动平均线(SMA)。问题是我无法找到一种方法来单独计算新添加的行的SMA。

我实现的解决方法是手动计算每个SMA,但是我敢肯定有一种方法可以使用roll_mean或类似方法来实现。

这是一个脚本,可让您重现我拥有的内容:

library(RcppRoll)

SMALen = c(18, 20, 22, 81, 90, 99, 135, 150, 165)
startDate <-  as.Date("1900-01-01")
endDate <- as.Date("2018-12-31")
numDays <- endDate - startDate + 1
myData <- data.frame(Date=seq(startDate, endDate, 1),
                     UVI=sample(1:10, numDays, rep=TRUE))

for (i in 1:length(SMALen)) {
    SMAValues <- roll_mean(myData$UVI,
                           SMALen[i],
                           na.rm=TRUE,
                           fill=NA,
                           align='right')
    myData <- cbind(myData, SMAValues)
    colName <- paste0("SMA", SMALen[i])
    names(myData)[ncol(myData)] = colName
}    

head(myData, 25)
tail(myData, 25)

现在,我再添加几行(在下面的代码中,还有7天):

startDate <-  as.Date("2019-01-01")
endDate <- as.Date("2019-01-07")
numDays <- endDate - startDate + 1
newData <- data.frame(Date=seq(startDate, endDate, 1),
                      UVI=sample(1:10, numDays, rep=TRUE))
for(i in 1:length(SMALen)) {
    newData <- cbind(newData, NA)
    colName <- paste0("SMA", SMALen[i])
    names(newData)[ncol(newData)] = colName
}
numRows <- nrow(myData)
myData <- rbind(myData, newData)
tail(myData, 25)

这是我要用roll_mean或类似代码替换的代码:

for(i in 1:nrow(newData)) {
    for(j in 1:length(SMALen)) {
        colName <- paste0("SMA", SMALen[j])
        endDate <- newData$Date[i]
        startDate <- endDate - SMALen[j] + 1
        SMA <- mean(myData$UVI[(myData$Date >= startDate) & (myData$Date <= endDate)])
        myData[numRows + i, j + 2] <- SMA

    }    
}
tail(myData, 25)

1 个答案:

答案 0 :(得分:0)

一种方法是从旧数据(仅日期和UVI)中获取最后(最大窗口大小)165行,并使用rbind添加新数据(日期和UVI),然后在您循环时将roll_mean应用于新数据框在您的第一个循环中做了。添加SMA值后,请使用旧数据和SMA值重新添加数据框。