我经常需要根据定义为"事件"的时间间隔来计算时间序列数据集中许多参数的均值。在第二个数据集中。
下面的示例代码说明了我当前的方法,它可以很好地工作。
虽然我的数据集会增加,但我想知道是否有更有效的方法(例如在我的电脑上运行约30秒)。
保持在dplyr / tidyverse内是很重要的(数据表格方式很受欢迎,但是真的很有帮助)。
library(tidyverse)
#generate time series data
data <- bind_cols(
data_frame(td=seq(from = as.POSIXct("2010-01-01 00:00"),
to = as.POSIXct("2010-12-31 23:59"),
by = 60)),
as_data_frame(replicate(20,runif(525600))))
#generate events
events <- data_frame(
event = as.character(1:669),
start_cet = seq(from = as.POSIXct("2010-01-01 00:00"),
to = as.POSIXct("2010-12-01 00:00"),
by = 43200),
stop_cet = seq(from = as.POSIXct("2010-01-01 02:00"),
to = as.POSIXct("2010-12-01 02:00"),
by = 43200)
)
#calculate means of data columns within event intervals
system.time(
means <- events %>%
rowwise() %>%
mutate(s = list(data %>% select(td) %>% filter(td >= start_cet & td < stop_cet))) %>%
unnest() %>%
select(event,td) %>%
left_join(.,data) %>%
group_by(event) %>%
summarise_at(vars(V1:V20),funs(mean=mean)) %>%
ungroup()
)
答案 0 :(得分:1)
这是一种使用data.table
(1.9.7+)版library(data.table)
setDT(data); setDT(events)
data[events, on = .(td >= start_cet, td <= stop_cet), lapply(.SD, mean), by = .EACHI]
执行此操作的有效方法,运行OP示例大约需要10毫秒:
const router = require('express').Router(),
form = require('../api/form');
router.post('/api/submit', (req, res) => {
form.submit(req, res);
});
module.exports = router;
答案 1 :(得分:0)
大约3年后对自己的答案...
上述dplyr解决方案中的mutate
步骤不必要地复杂,正如JDLong的评论中所述。我现在使用
means2 <- events %>%
rowwise() %>%
mutate(td = list(seq(start_cet, stop_cet - 60, "min"))) %>%
unnest() %>%
select(event,td) %>%
left_join(.,data) %>%
group_by(event) %>%
summarise_at(vars(V1:V20),funs(mean=mean)) %>%
ungroup()
,比上面的旧dplyr
解决方案快25倍。
dt
解决方案仍然比此dplyr
链快约5倍。但是,输出有点混乱。而不是包含事件的列,我得到了两列td
,分别是事件的开始和结束时间。一些dt
专家知道如何解决此问题?