r - 根据过去 15 分钟计算每行大数据框的平均值
问题描述
我有一个数据框,例如:
data <- data.frame("date" = 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))
data
date Var1 Var2 Var3
1 2015-05-01 14:12:57 2 0.53 1
2 2015-05-01 14:14:57 3 0.30 1
3 2015-05-01 14:15:57 4 0.34 1
4 2015-05-01 14:42:57 2 0.12 1
5 2015-05-01 14:52:57 1 0.91 1
然而,实际上有60,000 行和 26 个变量!
我想要实现的是:
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
理论上: 根据过去 15 分钟的观察结果计算每行数据的平均值(Var1 和 Var2 以及 Var3 的总和)。
我想出了:
library(lubridate)
data <- data.frame("date" = 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))
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
...实际返回所需结果的内容。但是,对于具有 60,000 行的数据框,这不起作用或需要 100 年(不要忘记我实际上有 26 个变量)。
有谁知道我如何摆脱循环或如何调整我的功能?非常感谢!我也尝试过 sapply,但它似乎并没有快多少,或者我做错了什么。
感谢您的任何帮助!
解决方案
使用dplyr
,我们可以转换date
为POSIXct
类,使用cut
将其分解为 15 分钟间隔,然后获取各个列的累积平均值和总和。
library(dplyr)
data %>%
group_by(group = cut(as.POSIXct(date), breaks = "15 mins")) %>%
mutate_at(vars(Var1, Var2), cummean) %>%
mutate_at(vars(Var3), cumsum) %>%
ungroup() %>%
select(-group)
# date Var1 Var2 Var3
# <fct> <dbl> <dbl> <dbl>
#1 2015-05-01 14:12:57 2 0.53 1
#2 2015-05-01 14:14:57 2.5 0.415 2
#3 2015-05-01 14:15:57 3 0.39 3
#4 2015-05-01 14:42:57 2 0.12 1
#5 2015-05-01 14:52:57 1.5 0.515 2
使用mutate_at
因为有 26 个变量,所以我们可以一次将相同的函数应用于多个列。
编辑
基于@Rentrop 的评论,使用他的数据更新了答案。
library(dplyr)
library(purrr)
dat %>%
mutate(date = as.POSIXct(date),
Var1 = map_dbl(date, ~mean(Var1[date >= (.x - (15 * 60)) & date <= .x])),
Var2 = map_dbl(date, ~mean(Var2[date >= (.x - (15 * 60)) & date <= .x])),
Var3 = map_dbl(date, ~sum(Var3[date >= (.x - (15 * 60)) & date <= .x])))
# date 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:29:57 3.5 0.320 2
#4 2015-05-01 14:42:57 3.0 0.230 2
#5 2015-05-01 14:52:57 1.5 0.515 2
推荐阅读
- javascript - Error: write EPIPE while using imagemagick To write a lambda function
- ios - ios,alamofire5:需要相当于 curl --key foo.key --cert foo,pem --location --request GET 'https://bar.baz/foo"
- flutter - 类'列表
' 没有实例 getter 'title' - mysql - 使用 VBA 执行在文本框中编写的 SQL
- python - 将 datetime 变量分配给 pandas 数据框列
- php - 如何将表连接到laravel中的表
- c# - Sharepoint 2010 中的用户配置文件创建异常
- c# - Gridviewcell 显示错误的千位分隔符
- codeception - 错误 assert(): assert(sizeof($failures) == 1) failed 停止 Codeception 测试
- java - 无法关闭与 EntityManagerFactory 的 derby 连接