计算进入和退出之间的持续时间-代码优化

时间:2019-03-23 01:56:31

标签: r

我有一些数据:

  • 唯一标识符
  • 动作(进入或退出)
  • 时间戳
  • 建筑物ID 和其他一些列。

我正在尝试根据入口,出口,建筑物ID和唯一标识符(车号)来计算花费在建筑物中的时间。

现在,我按唯一ID对数据框进行排序,然后对日期进行排序,然后应用此算法:

    For each row {
        if row.type = 'entry' and nextRow.type = 'exit' and row.uid = nextRow.uid {
        Calculate time difference and add this data to another df.
        }
    }

尽管我只有6000行,但仍需要一些时间来运行... 我对R不太熟悉,我认为有很多方法可以加快速度...

代码如下:

# Sort rows: 
BldActivity <- BldActivity[order(BldActivity$UniqueId, BldActivity$DateOfEvent),]


df = data.frame(NULL)
DurationOfStay <- data.frame(NULL) 

for(i in 1:nrow(BldActivity)) {
    row <- BldActivity[i,]
    # do stuff with row
    if(row$Type == 'entry') {
        rowNext <- BldActivity[i+1,] 
        if(!is.na(rowNext$Type)) {
            if(rowNext$Type == 'exit' && row$UniqueId == rowNext$UniqueId)
            {
                        newRow <- data.frame( Entry_DateOfEvent = row$DateOfEvent,
                                        Exit_DateOfEvent  = rowNext$DateOfEvent,

                                        BuildingID = row$BuildingID,
                                        BuildingName = row$`Building Name`,
                                        UniqueId = row$UniqueId,
                                        DurationOfStay = difftime(rowNext$DateOfEvent, row$DateOfEvent, units="mins")
                                        )

                    DurationOfStay <- rbind(DurationOfStay,newRow)
            }
        }
    }
}

能否请您指出可能的改进之处?

这是一个输入示例:

DateOfEvent Type    UniqueId    BuildingID  Building Name
2019/03/22 09:15:43 entry   04352e5b6051c311048a5803f8716700    1e98f5c0e699    Building 2
2019/03/22 09:51:45 exit    04352e5b6051c311048a5803f8716700    1e98f5c0e699    Building 2
2019/03/22 10:31:28 entry   066b9a3995acd495318ad70e0d876f00    062e933d6b9f    Building 1
2019/03/22 11:15:02 exit    066b9a3995acd495318ad70e0d876f00    062e933d6b9f    Building 1
2019/03/22 11:11:42 entry   0e027aba359aaecbe8fe3eaf5a1bbb00    062e933d6b9f    Building 1
2019/03/22 14:44:27 exit    0e027aba359aaecbe8fe3eaf5a1bbb00    062e933d6b9f    Building 1
2019/03/22 09:55:03 entry   1747dbaef11176b9ab90f2cfbf056210    1e98f5c0e699    Building 2
2019/03/22 18:13:08 exit    1747dbaef11176b9ab90f2cfbf056210    1e98f5c0e699    Building 2
2019/03/21 14:23:53 entry   3e0d2c4b1b159a24f4dc5fa084b59f00    1e98f5c0e699    Building 2
2019/03/21 15:36:31 exit    3e0d2c4b1b159a24f4dc5fa084b59f00    1e98f5c0e699    Building 2

输出只是IN / OUT和计算的持续时间的列值。

谢谢

菲利普

2 个答案:

答案 0 :(得分:0)

library(data.table)
setDT(BldActivity)
DurationOfStay <- dcast(BldActivity, UniqueId + BuildingID + `Building Name` ~ Type, value.var = "DateOfEvent")
DurationOfStay[, DurationOfStay := difftime(exit, entry, units="mins"), ]

答案 1 :(得分:0)

感谢您的代码,它看起来很有希望。 我确实有2个问题:

首先,聚合函数出现问题,引发错误:

  

聚合函数应采用矢量输入并返回单个值(长度= 1)。

我通过添加聚合函数解决了这个问题

fun.aggregate = function(x) { 
   lubridate::as_datetime(ifelse(Type == 'entry', min(x), max(x)))
}

我还添加了一个标识符,用于根据唯一ID,建筑物ID和类型(进入/退出)对进入/退出进行分组

这是新代码:

setDT(BldActivity)
BldActivity[, ID_Stay := seq_len(.N), by=list(UniqueId, BuildingID, Type)]
DwellTime <- dcast(BldActivity, UniqueId + BuildingID + `Building Name` ~ Type, value.var = "DateOfEvent", 
fun.aggregate = function(x) {
    lubridate::as_datetime(ifelse(Type == 'entry', min(x), max(x)))},
  fill = 0)
DurationOfStay[, DurationOfStay := difftime(exit, entry, units="mins"), ]

但是我有非常奇怪的值...原因是,如果我有2个条目并且中间没有出口,那么整个序列就搞砸了。

这里是一个示例: example

谢谢

菲利普