【问题标题】:Cut time series into specific bins and label each chunk将时间序列切割成特定的箱子并标记每个块
【发布时间】:2021-03-01 12:06:31
【问题描述】:

我在房间里有一些关于 CO2 值的实验数据,这些数据带有时间和日期戳。我想根据每个实验发生时间的实验列表将其分解为一系列“实验”。 例如

数据

df<-data.frame(CO2.ppm.=runif(10), Date.time.=as.POSIXct(" 2019-2-08 07:00:00") + runif(n=10, min=0, max=3600))

具有开始和停止时间的实验列表:

ExpertimentList<- data.frame(StartTime=c("2019-2-08 07:10:00", "2019-2-08 07:15:00", "2019-2-08 08:30:00"), StopTime=c("2019-2-08 07:12:00","2019-2-08 07:16:00","2019-2-08 08:15:00"),ExptID=c(1,2,3))

请注意,有时会测量 CO2,但没有进行任何实验。例如。 07:12:00 到 07:15:00 之间。

我想将df$Date.time. 拆分为ExperimentListStartTimeStopTime

到目前为止,我已将所有内容都转换为整数

df$Date.time.<-as.integer(df$Date.time.)
ExperimentList$StartTime<-as.integer(ExperimentList$StartTime
ExperimentList$StopTime<-as.integer(ExperimentList$StopTime)

然后看cut

breakz<-dplyr::arrange(paste(Experiment_List$StartTime,Experiment_List$StopTime)%>%as_tibble())

cut(df$Dev.Date.Time,breaks=unique(breakz$value))

但是当没有进行实验时,我无法过滤掉数据。任何想法都非常感谢。

预期输出:

set.seed(143)
data.frame(CO2.ppm.=runif(10), Date.time.=sort(as.POSIXct(" 2019-2-08 07:00:00") + runif(n=10, min=0, max=3600)),ExptID=c(NA,NA,NA,1,NA,NA,NA,NA,NA,NA))

回答:

我发现@Ronak 的回答会耗尽内存,所以我将 data.frame 分块为 10000 个行段:

df<-split(df, (as.numeric(rownames(df))-1) %/% 10000)

然后根据@Ronak 的回答,我将代码弹出到一个函数中,并使用了并行包中的 mclapply。

#进行左连接以删除任何不属于实验的行

fuzzyJoinFunction<-function(a){
  a<-fuzzy_left_join(a, Experiment_List, 
                       by = c('Dev.Date.Time' = 'StartTime', 'Dev.Date.Time'= 'StopTime'), 
                       match_fun = c(`>=`, `<=`))
  a
}

df<-rbindlist(mclapply(X=df,FUN=fuzzyJoinFunction,mc.cores=4))

【问题讨论】:

  • 您能否包含共享数据的预期输出?
  • 您好 Ronak,感谢您对此进行调查。我添加了一个预期的输出来提供帮助。还添加了一个 set.seed 并对时间进行排序,否则它会有所不同。但是根据它生成的值,我只在列表中的实验中找到了 1 个 CO2 值。

标签: r dplyr


【解决方案1】:

我们可以使用fuzzyjoin::fuzzy_inner_join 只保留范围内的行。

library(dplyr)
library(fuzzyjoin)

#All the datetime values should be of type POSIXct.
ExpertimentList %>%
  mutate(across(c(StartTime, StopTime), lubridate::ymd_hms)) -> ExpertimentList


fuzzy_inner_join(df, ExpertimentList, 
                 by = c('Date.time.' = 'StartTime', 'Date.time.'= 'StopTime'), 
                 match_fun = c(`>=`, `<=`))

要在最终输出中使用NA 获取所有df 值,对于ExptID,请使用fuzzy_left_join

【讨论】:

  • 哇,真快!甚至在我写完上面的评论之前!
  • 我发现我的 R 会话运行了大约 30 分钟,然后崩溃了。我在 data.frame 上的一个小块(1000 行)上尝试了它,它运行良好,但随后在较大的集合(5E6 行)上崩溃。您认为最好的前进方式是什么?
  • 我将尝试将其分块,然后在最后进行绑定。
猜你喜欢
  • 2013-02-23
  • 1970-01-01
  • 2015-09-15
  • 2021-08-31
  • 2020-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多