R 按因子和时间间隔计算发生次数
我目前有一个单一的数据框(数据,nrow=10248),其中包含2013年7月1日至2013年10月3日期间标记的动物信息,包括日期(日期)、识别标签(id)、标记和释放动物的指定组(trip),以及是否检测到它们(存在;0=否,1=是)。请参见下面的示例:R 按因子和时间间隔计算发生次数,r,count,group-by,R,Count,Group By,我目前有一个单一的数据框(数据,nrow=10248),其中包含2013年7月1日至2013年10月3日期间标记的动物信息,包括日期(日期)、识别标签(id)、标记和释放动物的指定组(trip),以及是否检测到它们(存在;0=否,1=是)。请参见下面的示例: > data date id trip presence 26 2013-07-01 9360 1 1 27 2013-07-01 9361 1 1 28
> 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年3月10日李>
- “第二次旅行”中的所有动物都贴上了标签 2013年7月6日,允许漫游至2013年10月3日
- 所有“旅行”组的开始日期不同,但最终于2013年3月10日结束
是否有人有任何建议,例如使用
xts
或zoo
软件包或为每次“旅行”创建单独的数据帧?如果您需要更多信息,请告诉我 这也许是你的一个开始。不过,可能有更优雅的方式来实现这一点。我在回答中使用包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)
请注意,在此解决方案中,我假设每次行程的开始日期是任何行程组中出现的第一个日期(不考虑presenece是1还是0,但如果需要,可以轻松调整)
还请注意,对于每个跳闸
组,仅显示这些时间间隔,其中发生频率>=1
最后但并非最不重要的一点是,您可以通过将变量intrvl
更改为任何其他数字来轻松更改时间间隔
按OP在注释后编辑:
下一行
mutate(interval = floor((as.numeric(date - min(date)))/intrvl)+1) %.%
首先创建一个新列interval
,然后计算每个trip
组的最小最小日期(例如,第一个组为2013-07-01)与当前行中的日期条目之间的差值,这将转换为数字。例如,如果差值为3,则3除以intrvl(5),即3/5,介于0和1之间。然后,floor
函数将该数字向下舍入到小于当前值的下一个整数,因此它是0。最后添加1,这是该行的间隔组(第一个间隔组在您的示例中从2013-07-01运行到2013-07-05)。您可以通过从代码中删除最后一个%。%select(-interval)
来检查这一点。使用聚合,使用cut.Date
创建存储桶:
aggregate(presence ~ trip + cut(as.Date(date), breaks='5 day'), data=data, FUN=sum)
## trip cut(as.Date(date), breaks = "5 day") presence
## 1 1 2013-07-01 7
## 2 1 2013-07-06 5
## 3 2 2013-07-06 4
## 4 3 2013-07-06 2
这并不是我们想要的,因为第三次旅行的开始日期应该是2013-07-08。通过trip
拆分数据帧,执行相同的计算(但无需在trip
上进行聚合)并重新组合,得出:
(d <- do.call(rbind,
by(data, data$trip,
FUN=function(x) aggregate(presence ~ cut(as.Date(date), breaks='5 day'),
data=x, FUN=sum)
)
))
## cut(as.Date(date), breaks = "5 day") presence
## 1.1 2013-07-01 7
## 1.2 2013-07-06 5
## 2 2013-07-06 4
## 3 2013-07-08 2
(谢谢你的推荐!我对dplyr
的实验还不够,但它似乎很简单。你能进一步解释一下突变(间隔=下限((as.numeric(date-min(date))/intrvl)+1)这一行中发生了什么吗%.%
?@ccapizzano我已经为这一行添加了一个解释。非常好,我能够配置一些代码,以输出每个间隔的唯一发射机数量。感谢您的帮助!这个解决方案很好,因为它非常紧凑。我只想知道为什么行程3的日期是2013-07-06。正如我理解的OP,时间间隔(例如5天)与每组的“开始日期”无关。好的捕获,@初学者。这可以通过将trip
的每个值作为一个单独的数据框来实现。更新+1(仍然是一个非常紧凑的解决方案)感谢您提供使用base
code的替代解决方案,非常感谢。我将很快试用!
aggregate(presence ~ trip + cut(as.Date(date), breaks='5 day'), data=data, FUN=sum)
## trip cut(as.Date(date), breaks = "5 day") presence
## 1 1 2013-07-01 7
## 2 1 2013-07-06 5
## 3 2 2013-07-06 4
## 4 3 2013-07-06 2
(d <- do.call(rbind,
by(data, data$trip,
FUN=function(x) aggregate(presence ~ cut(as.Date(date), breaks='5 day'),
data=x, FUN=sum)
)
))
## cut(as.Date(date), breaks = "5 day") presence
## 1.1 2013-07-01 7
## 1.2 2013-07-06 5
## 2 2013-07-06 4
## 3 2013-07-08 2
d$trip <- gsub('[.].*$', '', rownames(d))
d
## cut(as.Date(date), breaks = "5 day") presence trip
## 1.1 2013-07-01 7 1
## 1.2 2013-07-06 5 1
## 2 2013-07-06 4 2
## 3 2013-07-08 2 3