r - Data.table:不规则日期范围之间的总和
问题描述
调查和火灾在不同的燃烧单位不定期发生。(srv=1 表示调查完成,fire=1 表示发生火灾)我想计算调查之间发生了多少火灾,即包括调查年份和上一次调查前一年。
nyear = 10
units = 4
set.seed(15)
DT <- data.table(
unit = rep(1:units, each=nyear),
year = 2000:(2000+nyear-1),
srv = rbinom(nyear*units, 1, 0.4),
fire = rbinom(nyear*units, 1, 0.3)
)
DT
我可以计算经过的年数,但我必须创建一个新数据集,然后将其加入原始数据集。然后我无法弄清楚日期范围之间的火灾总和。
DT1 <- DT[srv != 0] # Drop years without surveys
DT2 <- DT1[, .(year, elapsed = year - shift(year)), by = "unit"] # Use 'shift' to find years elapsed
DT3 <- DT2[DT, on=.(unit, year)] # join dataset with elapsed time to original dataset
DT3[ , sum(fire), on = .(year >= year, year < year -(elapsed-1)), by="unit"] # Doesn't work
示例输出如下,其中“nfire”是我所追求的——在没有调查的年份它是“NA”,否则它提供上次调查后的火灾数量,包括当前调查年份:
unit year elapsed srv fire nfire
1: 1 2000 NA 1 1 1
2: 1 2001 NA 0 0 NA
3: 1 2002 2 1 1 1
4: 1 2003 1 1 0 0
5: 1 2004 NA 0 0 NA
6: 1 2005 2 1 0 0
7: 1 2006 1 1 0 1
8: 1 2007 NA 0 1 NA
9: 1 2008 2 1 1 2
10: 1 2009 1 1 0 1
11: 2 2000 NA 0 0 NA
12: 2 2001 NA 1 1 NA
解决方案
r2evans 的答案有效:
DT[, grp := rev(cumsum(rev(srv == 1))), by = .(unit)][, nfire := sum(fire), by=.(unit, grp)]
调查发生的时间 (srv ==1) 以相反的顺序排列,然后累加。反向排序确保每个调查都与其之前的年份分组,并且累积求和提供分配连续编号的组列表。外部“rev”将顺序更改回其原始组织。
语句 '[, nfire := sum(fire), by=.(unit, grp)]' 的第二部分是链接的一个例子——据我所知,这只是在数据中引入更多操作的一种方式。表步骤不会弄乱语句的第一部分。里面的语法相当直观。
推荐阅读
- rust - 如何在 API 中不暴露 Rc 的情况下共享资源?
- babeljs - 无法解析 Babel 插件中的类方法装饰器
- java - 如何使用 Java 和“增强”库在 DynamoDB SDK 中限制扫描操作中的结果项
- reactjs - React Native 上的“元素类型无效”(非导入/导出错误)
- firebase - 如何通过最终列表
keepImage = [] 到下一页 - jenkins - Kubectl set image vs. apply from CI - 最佳实践
- vue.js - 当用户未授权时,在登录页面之前看到内部面板的闪烁
- java - Gitpod maven 项目 CI 中的 Headless UI 测试
- r - 在 ggpubr 中添加后层
- python - 如果数字增加 2,则数字 X 增加 1