R 计算输入和输出之间的持续时间-代码优化
我有以下方面的数据: 唯一标识符 进入或退出的动作 时间戳 建筑物ID 和其他一些专栏。 我试图根据入口、出口、建筑id和唯一标识符(车号)计算进入建筑的时间 现在,我按照唯一ID对数据帧进行排序,然后是日期,然后应用以下算法:R 计算输入和输出之间的持续时间-代码优化,r,R,我有以下方面的数据: 唯一标识符 进入或退出的动作 时间戳 建筑物ID 和其他一些专栏。 我试图根据入口、出口、建筑id和唯一标识符(车号)计算进入建筑的时间 现在,我按照唯一ID对数据帧进行排序,然后是日期,然后应用以下算法: For each row { if row.type = 'entry' and nextRow.type = 'exit' and row.uid = nextRow.uid { Calculate time differenc
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)
}
}
}
}
输出只是输入/输出的列值和计算的持续时间
谢谢
Philippe谢谢你的代码,看起来很有希望。
library(data.table)
setDT(BldActivity)
DurationOfStay <- dcast(BldActivity, UniqueId + BuildingID + `Building Name` ~ Type, value.var = "DateOfEvent")
DurationOfStay[, DurationOfStay := difftime(exit, entry, units="mins"), ]
但我确实有两个问题:
首先,引发错误的聚合函数存在问题:
聚合函数应采用向量输入,并返回一个长度为1的值
我通过添加聚合函数解决了这个问题
fun.aggregate = function(x) {
lubridate::as_datetime(ifelse(Type == 'entry', min(x), max(x)))
}
我还添加了一个标识符,以根据唯一id、建筑id和类型入口/出口对入口/出口进行分组
以下是新代码:
SETDTBLD活性
BldActivity[,ID_Stay:=seq_len.N,by=listUniqueId,BuildingID,Type]
你能不能加上一个可复制的例子以及基于此的预期输出?嗨,Ronak,我刚刚加了一个输入的例子。不过只有10排。谢谢,谢谢你。这真的很酷,但我遇到了下一个答案中解释的另一个问题。
fun.aggregate = function(x) {
lubridate::as_datetime(ifelse(Type == 'entry', min(x), max(x)))
}