我有一个巨大的数据框,需要花费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)
答案 0 :(得分:0)
一种方法是从旧数据(仅日期和UVI)中获取最后(最大窗口大小)165行,并使用rbind添加新数据(日期和UVI),然后在您循环时将roll_mean应用于新数据框在您的第一个循环中做了。添加SMA值后,请使用旧数据和SMA值重新添加数据框。