如何计算数据帧中不同行中事件的持续时间?

问题描述 投票:1回答:2

我正在处理一个带有处理过的GPS位置的数据框架。我有三个变量。id对应于每个人的标识符。TimeStamp表示gps信号的时刻,和。perimeter 表示信号是否发生在给定的周界内。我想建立一个表格,按照正确的发生顺序列出在给定周界内或外花费的时间。

这是一个可重复的例子。

df <- data.frame(id=rep(1, 10),
                 TimeStamp=seq(as.POSIXct("2020-01-01 12:00:00"), 
                               as.POSIXct("2020-01-01 16:30:00"), 
                               length.out = 10),
                 perimeter=c(NA, NA, NA, "p1", "p1", "p1", NA, NA, "p2", "p2"))

我想要的输出结果是这样的

id perimeter time
1  NA        1.5
1  "p1"      1.5
1  NA        1
1  "p2"      1

我已经接近了一个解决方案,使用 rle() 函数。

df[is.na(df$perimeter),]$perimeter <- "OUT"

data.frame(perimeter=rle(df$perimeter)$value,
           time=(rle(df$perimeter)$length*30)/60)

然而,它是根据向量中重复序列的长度来估计时间的,由于我有缺失的值,所以从最后一个重复序列中减去第一个重复序列的TimeStamp会更准确。

r dataframe dplyr gps
2个回答
0
投票

一个dplyr的解决方案。

df %>% 
  mutate(perimeter = forcats::fct_explicit_na(df$perimeter),
         visit = cumsum(perimeter != lag(perimeter) | is.na(lag(perimeter)))) %>% 
  group_by(id, visit, perimeter) %>% 
  summarise(time = difftime(max(TimeStamp) + 1800, min(TimeStamp), unit = "hour")) %>%
  ungroup() %>% select(-visit)

#> # A tibble: 4 x 3
#>      id perimeter time     
#>   <dbl> <fct>     <drtn>   
#> 1     1 (Missing) 1.5 hours
#> 2     1 p1        1.5 hours
#> 3     1 (Missing) 1.0 hours
#> 4     1 p2        1.0 hours


0
投票

这里有一个... data.table 解决办法。

library(data.table)
setDT(df)
df[, nextTimeStamp := shift(TimeStamp, -1L), by = id]
df[, .( unclass(nextTimeStamp[.N] - TimeStamp[1L]) / 60^2), by = .(id, rleid(perimeter))]

#    id rleid  V1
# 1:  1     1 1.5
# 2:  1     2 1.5
# 3:  1     3 1.0
# 4:  1     4  NA
© www.soinside.com 2019 - 2024. All rights reserved.