使用“cumsum”、“difftime”和“lag”

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

我的数据集中有三列用于解决这个问题。

第一列称为缓冲区,显示动物的 GPS 点是否在缓冲区内(是/否值)。第二个是动物 GPS 点的日期时间,第三个是在缓冲区内花费的时间 (dt1)。

我想做的是,如果缓冲区列中有一个“是”行,在两个“否”行之间,我想计算这个 GPS 点与前一个 GPS 点之间的时间差并将其打印在 dt1 上,我成功了。

问题是当我在查看多个连续的“是”行时尝试计算第一个和最后一个“是”行之间的时间差时,这意味着动物在缓冲区中停留的时间更长,因此连续的 GPS 点是在缓冲区内。

在这里你可以看到我的代码。问题在于,它为跟随其他“是”行的“是”行返回“NA”,基本上是任何未隔离的“是”行。我正在尝试获取“是行”系列中最后“是”行的总体时间差。

trips_with_buffer_2016_df <- trips_with_buffer_2016_df %>%
  group_by(tripID) %>%
  mutate(
    dt1 = ifelse(buffer == 'yes', 
                 ifelse(lag(buffer, default = 'no') == 'no', 
                        difftime(DateTime, lag(DateTime), units = "mins"),
                        cumsum(as.numeric(difftime(DateTime, lag(DateTime,), units = "mins")))
                 ), 
                 NA_real_)
  )

“tripID”列按之前识别的行程对 GPS 点进行分组。

我知道问题出在 cumsum 线上,但我无法让它工作。 The two rows with the problem showing 提前非常感谢!

r datetime dplyr cumsum difftime
2个回答
0
投票

如果您有唯一的行程 ID,我认为您不需要使用嵌套的 ifelse,您应该能够总结并获取每次行程的最小/最大时间,并据此计算 difftime。

trips_with_buffer_2016_df <- trips_with_buffer_2016_df %>%
  group_by(tripID, buffer) %>%
  summarise(MIN_TIME=min(DateTime), MAX_TIME=max(DateTime)) %>%
    mutate(dt1=difftime(MAX_TIME, MIN_TIME, units="mins"))

0
投票

您可以使用

rle
简化缓冲区内或缓冲区外的索引, 这里 0 = 出,1 = 入,但也可以是“是”、“否”

buffer = c(1,0,0,0,1,1,1,1,0,0,0,0,1,0,0,1,1,1,1,1,0,0)
rle(buffer)
Run Length Encoding
  lengths: int [1:8] 1 3 4 4 1 2 5 2
  values : num [1:8] 1 0 1 0 1 0 1 0

end = cumsum(rle(buffer)$lengths)
end
[1]  1  4  8 12 13 15 20 22
start = end - rle(buffer)$lengths +1
start
[1]  1  2  5  9 13 14 16 21

inbuf = which(rle(buffer)$values == 1)
inbuf
[1] 1 3 5 7

start[inbuf]
[1]  1  5 13 16

end[inbuf]
[1]  1  8 13 20

time = seq(5, 110, 5)

sum(diff(time[start[inbuf][2]:end[inbuf][2]]))
[1] 15

另一种思考方式,当事情几乎被遗忘并弹出错误时,可能更容易看到将来发生的事情。

© www.soinside.com 2019 - 2024. All rights reserved.