r - 按因素和时间间隔计算发生次数

标签 r count group-by

我目前有一个数据框(数据,nrow = 10248),它是从 7/1/2013 到 10/3/2013 的标记动物的信息,包括日期(date),识别标签(id),分配的组动物被标记和释放(旅行)的地方,以及是否检测到它们(存在;0 = 否,1 = 是)。请参见下面的示例:

> data
            date   id trip presence
26    2013-07-01 9360    1        1
27    2013-07-01 9361    1        1
28    2013-07-02 9362    1        0
29    2013-07-02 9363    1        0
30    2013-07-03 9364    1        1
2349  2013-07-03 9343    1        1
2350  2013-07-04 9344    1        0
2351  2013-07-04 9345    1        1
2352  2013-07-05 9346    1        1
2353  2013-07-05 9347    1        1
2354  2013-07-06 9360    1        1
7102  2013-07-06 9416    2        1
7103  2013-07-06 9417    2        1
7104  2013-07-07 9360    1        1
7105  2013-07-07 9419    2        1
7106  2013-07-07 9420    2        1
7107  2013-07-08 9360    1        1
11102 2013-07-08 9386    3        0
11103 2013-07-08 9387    3        0
11104 2013-07-09 9360    1        1
11105 2013-07-09 9343    1        1
11106 2013-07-09 9390    3        1
11107 2013-07-09 9391    3        1

另一个重要信息是每个“行程”组都有不同的开始日期。例如:

  • 2013 年 7 月 1 日标记为“旅行 1”的所有动物都被允许漫游 2013 年 10 月 3 日之前免费。
  • “trip 2”中的所有动物都被标记在 7/6/2013 并允许漫游至 10/3/2013。
  • 所有“旅行”组都有不同的开始日期,但最终都在 2013 年 10 月 3 日结束。

我的总体目标是计算在指定时间间隔(例如 5 天)内通过因素“旅行”检测到的动物数量(唯一 ID,存在 = 1)。

我想要的输出如下(频率值与上表示例无关):

trip         interval   frequency
   1    07/01 - 07/05          5
   1    07/06 - 07/10          4
   1    07/11 - 07/15          4
   2    07/06 - 07/10          5
   2    07/11 - 07/15          4
   2    07/16 - 07/20          3
   3    07/08 - 07/12          6
   3    07/13 - 07/17          6
   3    07/18 - 07/22          5

*请注意旅行的不同开始日期。

有没有人有任何建议,例如使用 xtszoo 包或为每个“旅行”创建单独的数据帧?如果您需要更多信息,请告诉我!

最佳答案

这对您来说可能是一个开始。不过,可能有更优雅的方法来做到这一点。我在我的回答中使用包 dplyr 并假设你的 data.frame 被称为 dd

dd$date <- as.Date(dd$date, format="%Y-%m-%d")

intrvl <- 5

require(dplyr)

result <- dd %.%
  group_by(trip) %.%
  mutate(interval = floor((as.numeric(date - min(date)))/intrvl)+1) %.%
  filter(presence == 1) %.%
  group_by(interval, add = TRUE) %.%
  summarize(startDate = min(date),
            endDate = as.Date(startDate + intrvl -1, origin = "1970-01-01"),
            frequency = n()) %.%
  select(-interval)

根据您的示例数据,结果将是:

> result
#  trip  startDate    endDate frequency
#1    1 2013-07-01 2013-07-05         7
#2    1 2013-07-06 2013-07-10         5
#3    2 2013-07-06 2013-07-10         4
#4    3 2013-07-09 2013-07-13         2

请注意,在此解决方案中,我假设每次旅行的开始日期是出现在任何 trip 组中的第一个日期(不考虑 presenece 是 1 还是 0,但可以如果需要可以很容易地调整)。

另请注意,对于每个 trip 组,只会显示出现频率 >=1 的那些时间间隔。

最后但同样重要的是,您可以通过将变量 intrvl 更改为任何其他数字来轻松改变时间间隔。

OP评论后编辑:

下一行

mutate(interval = floor((as.numeric(date - min(date)))/intrvl)+1) %.%

首先创建一个新列 interval 然后计算每个 trip 组的最小日期(例如第一组为 2013-07-01)和当前行中的日期条目,这将转换为数字。例如,如果差值为 3,则 3 除以 intrvl (5),得到介于 0 和 1 之间的 3/5。然后,floor 函数将此数字向下舍入为下一个小于当前值的整数,所以它是 0。最后你加 1,这是你的间隔组该行(第一个间隔组在你的例子中运行从 2013-07-01 到 2013-07-05)。您可以通过从代码中删除最后一个 %.% select(-interval) 来检查这一点。

关于r - 按因素和时间间隔计算发生次数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23889563/

相关文章:

r - 使用 mapply() 为多个参数留出一个?

.net - 使用 Linqdatasource 和 groupby 属性

Mysql:行分组时提供的值有多可靠?

r - 有没有办法缩短一系列 colClasses

重新编码字符串时,Car 包中的重新编码返回意外符号

c++ - VexCL:计算 vector 中高于最小值的值的数量

java - hibernate native 查询,计数

php - MYSQL:如何找出未装备元素的数量?

mysql - 如何解决联合查询中记录数差异的问题

r - 排序表唯一参数