r语言 - 优化功能:循环 rbind - 非常慢的 >5,000 行



我有一个数据帧(数据(,其中包含一个带有日期+时间和一些其他变量的变量。我想要的是一个新的数据框,其中"旧"df 的每一行都是过去 15 分钟内每个实例的摘要(例如,平均值(。

我用以下代码解决了这个问题(我将变量缩短为 1,实际上我大约有 26 个(:

#### SEE EDIT ! ###
library(lubridate)
# Make a reference df to start rbind later
chunks <- data.frame("unix_timestamp" = as.POSIXct("2018-12-01 08:47:00 CET"), 
"Var1" = NA)
# Start loop for each row in data
for (i in 1:nrow(data)) {
help <- data[as.POSIXct(data[,1]) > (as.POSIXct(data[i,1]) - minutes(xmin)) & 
as.POSIXct(data[,1]) <= as.POSIXct(data[i,1]),] # Help data frame with time frame selection

chunk <- data.frame("unix_timestamp" = as.POSIXct(data[i,1]), 
"Var1" = mean(help$Var1))
chunks <- rbind(chunks, chunk)
}
#Delete initial row
chunks <- chunks[-1,]

我对输出感到满意,当我有一个 ~500 个观察的数据帧时,速度还可以。但是,我有一些 60,000 行的数据集,这几乎永远运行。

我知道其他人也有类似的问题,但不幸的是我无法实现它!

我感谢任何帮助!

最好!

编辑:


library(lubridate)
data <- data.frame("unix_timestamp" = c("2015-05-01 14:12:57", 
"2015-05-01 14:14:57", 
"2015-05-01 14:15:57", 
"2015-05-01 14:42:57", 
"2015-05-01 14:52:57"), 
"Var1" = c(2,3,4,2,1),
"Var2" = c(0.53,0.3,0.34,0.12,0.91),
"Var3" = c(1,1,1,1,1))
pre <- vector("list", nrow(data))
data
for (i in 1:length(pre)) {
#to see progress
print(paste(i, "of", nrow(data), sep = " "))
help <- data[as.POSIXct(data[,1]) > (as.POSIXct(data[i,1]) - minutes(15)) & 
as.POSIXct(data[,1]) <= as.POSIXct(data[i,1]),] # Help data frame with time frame selection

chunk <- data.frame("unix_timestamp" = as.POSIXct(data[i,1]), 
"Var1" = mean(help$Var1),
"Var2" = mean(help$Var2),
"Var3" = sum(help$Var3))
pre[[i]] <- chunk
}
output <- do.call(rbind, pre)
output
unix_timestamp Var1  Var2 Var3
1 2015-05-01 14:12:57  2.0 0.530    1
2 2015-05-01 14:14:57  2.5 0.415    2
3 2015-05-01 14:15:57  3.0 0.390    3
4 2015-05-01 14:42:57  2.0 0.120    1
5 2015-05-01 14:52:57  1.5 0.515    2

由于您似乎需要一个滚动平均值,请考虑sapply

new_df <- data.frame(
unix_timestamp = as.POSIXct(data[,1]),
rolling_15_mean = sapply(1:nrow(data), 
function(i) mean(data$Var[as.POSIXct(data[,1]) > (as.POSIXct(data[i,1]) - 60*15)
& as.POSIXct(data[,1]) <= as.POSIXct(data[i,1])])
)
)

Rextester 演示

或者,使用vapply可以稍微加快处理速度,因为您可以定义输出向量的类型和长度。

new_df <- data.frame(
unix_timestamp = as.POSIXct(data[,1]),
rolling_15_mean = vapply(1:nrow(data), 
function(i) mean(data$Var[as.POSIXct(data[,1]) > (as.POSIXct(data[i,1]) - 60*15)
& as.POSIXct(data[,1]) <= as.POSIXct(data[i,1])]),
numeric(1)
)
)

最新更新