在按组首次出现事件之前选择行

时间:2014-06-26 22:41:44

标签: r aggregate data.table

我有一系列的观察结果描述了动物是否以及何时被发现在特定区域。以下样本表确定白天何时(status == 1)或(status == 0)看到某种动物。

   id       date status
1   1 2014-06-20      1
2   1 2014-06-21      1
3   1 2014-06-22      1
4   1 2014-06-23      1
5   1 2014-06-24      0
6   2 2014-06-20      1
7   2 2014-06-21      1
8   2 2014-06-22      0
9   2 2014-06-23      1
10  2 2014-06-24      1
11  3 2014-06-20      1
12  3 2014-06-21      1
13  3 2014-06-22      0
14  3 2014-06-23      1
15  3 2014-06-24      0
16  4 2014-06-20      1
17  4 2014-06-21      0
18  4 2014-06-22      0
19  4 2014-06-23      0
20  4 2014-06-24      1

使用data.table包裹,我可以确定在该地区不再看到动物的第一天:

library(data.table)
dt <- as.data.table(df)
dt[status == 0, .SD[1], by = id]
  id       date status
1:  1 2014-06-24      0
2:  2 2014-06-22      0
3:  3 2014-06-22      0
4:  4 2014-06-21      0

虽然上表很有用,但我想知道如何操作该函数以在动物第一次出现之前找到日期。换句话说,我想知道每只动物在临时离开前的最后一天。

我的实际数据集根据情况将这些存在/不存在观察结果分成不同的时间长度(例如,每隔3小时存在/不存在,6小时等)。因此,访问前一行更容易,而不是从每个值中减去时间间隔,因为它总是在变化。我想要的输出如下:

  id       date status
1:  1 2014-06-23      1
2:  2 2014-06-21      1
3:  3 2014-06-21      1
4:  4 2014-06-20      1

请随时使用base代码或其他套餐(即dplyr)来回答这个问题,我总是想要一些新的东西。谢谢你的时间!

2 个答案:

答案 0 :(得分:9)

尝试以下方法:

dt[dt[status == 0, .I[1] - 1, by = id]$V1]
#   id       date status
#1:  1 2014-06-23      1
#2:  2 2014-06-21      1
#3:  3 2014-06-21      1
#4:  4 2014-06-20      1

顺便提一下,此方法(使用.I代替.SD)也会快得多。有关详情,请参阅this post

答案 1 :(得分:4)

以下是dplyr的方法:

df %>% 
  group_by(id) %>%
  mutate(status_change = status - lead(status)) %>%
  filter(status_change == 1)
  id       date status status_change
1  1 2014-06-23      1             1
2  2 2014-06-21      1             1
3  3 2014-06-21      1             1
4  3 2014-06-23      1             1
5  4 2014-06-20      1             1

这利用status作为数字变量。 lead()访问下一个值;当动物消失时,变化为1。