合并R中的开始和停止事件之间的时间

时间:2016-09-29 22:59:14

标签: r merge

我正在尝试合并两个数据集,其中一个数据集包含日期时间变量(dataA),另一个数据集包含开始和停止时间(dataB)。我想在开始和停止时间之间取所有日期时间。我想出了一个简单的解决方案,但是对于一个观察数据大约有一百万的数据集需要3个多小时。有人可以提供更快的解决方案吗?以下是我的解决方案的示例;它适用于小样本量,但减少secBetwMeas会大大增加计算时间(设置secBetwMeas=5需要近40秒)。

secBetwMeas <- 5*60
dataA <- data.frame(id=c(rep("A",length(seq(as.POSIXct("2014-01-01 01:00:00", format="%Y-%m-%d %H:%M:%S"),as.POSIXct("2014-01-02 04:00:00", format="%Y-%m-%d %H:%M:%S"), by=secBetwMeas))),
                         rep("B",length(seq(as.POSIXct("2014-06-01 04:00:00", format="%Y-%m-%d %H:%M:%S"),as.POSIXct("2014-06-02 05:00:00", format="%Y-%m-%d %H:%M:%S"), by=secBetwMeas)))),
                    dataDtTm=c(seq(as.POSIXct("2014-01-01 01:00:00", format="%Y-%m-%d %H:%M:%S"),
                                 as.POSIXct("2014-01-02 04:00:00", format="%Y-%m-%d %H:%M:%S"), by=secBetwMeas),
                               seq(as.POSIXct("2014-06-01 04:00:00", format="%Y-%m-%d %H:%M:%S"),
                                   as.POSIXct("2014-06-02 05:00:00", format="%Y-%m-%d %H:%M:%S"), by=secBetwMeas)))
dataB <- data.frame(id=rep(c("A","B"),each=2),
                    startDtTm=c(as.POSIXct("2014-01-01 01:10:00", format="%Y-%m-%d %H:%M:%S"),
                                as.POSIXct("2014-01-02 03:05:00", format="%Y-%m-%d %H:%M:%S"),
                                as.POSIXct("2014-06-01 04:30:00", format="%Y-%m-%d %H:%M:%S"),
                                as.POSIXct("2014-06-01 22:10:00", format="%Y-%m-%d %H:%M:%S")),
                    endDtTm=c(as.POSIXct("2014-01-01 08:30:00", format="%Y-%m-%d %H:%M:%S"),
                              as.POSIXct("2014-01-02 07:05:00", format="%Y-%m-%d %H:%M:%S"),
                              as.POSIXct("2014-06-01 08:30:00", format="%Y-%m-%d %H:%M:%S"),
                              as.POSIXct("2014-06-02 04:05:00", format="%Y-%m-%d %H:%M:%S")))


### Trying to optimize this solution: ###
dataA$endDtTm <- dataA$startDtTm <- as.POSIXct(NA)
for(i in 1:NROW(dataA)){
  index <- (dataA$id[i]==dataB$id & dataA$dataDtTm[i] >= dataB$startDtTm & dataA$dataDtTm[i] <= dataB$endDtTm)
  stopifnot(sum(index)==0 || sum(index)==1)
  if(any(index)){
    dataA$startDtTm[i] <- dataB$startDtTm[index]
    dataA$endDtTm[i] <- dataB$endDtTm[index]
  }
}
dataA <- na.omit(dataA)
head(dataA)  #This is the dataset I want to see

1 个答案:

答案 0 :(得分:1)

这有用吗?

dataC <- merge(dataA,dataB, by="id")
dataC[dataC$dataDtTm >= dataC$startDtTm & dataC$dataDtTm <= dataC$endDtTm,]