r - 计算按变量分组的两个日期之间的差异
问题描述
我正在寻找一些帮助来编写更有效的代码。我有以下数据集。
Report| ReportPeriod|ObsDate
1 | 15 |2017-12-31 00:00:00
1 | 15 |2017-12-31 06:00:00
1 | 15 |2017-12-31 12:30:00
2 | 11 |2018-01-01 07:00:00
2 | 11 |2018-01-01 13:00:00
2 | 11 |2018-01-01 16:30:00
第一列是“报告”,它是特定报告的唯一标识符。在数据集中,只有两个报告(1 和 2)。第二列是“ReportPeriod”,这对于特定报告是相同的。报告 1 为 15 小时,报告 2 为 11 小时。第三列“ObsDate”是特定报告中的不同观察结果。
问题:我需要找出按“报告”分组的观察之间的时间差。我用下面的代码做到了。
example<- data.frame(Report=c(1,1,1,2,2,2), ReportPeriod=c(15,15,15,11,11,11),
ObsDate=c(as.POSIXct("2017-12-31 00:00:00"), as.POSIXct("2017-12-31 06:00:00"),
as.POSIXct("2017-12-31 12:30:00"), as.POSIXct("2018-01-01 07:00:00"),
as.POSIXct("2018-01-01 13:00:00"), as.POSIXct("2018-01-01 16:30:00")))
example<- example %>% group_by(Report) %>%
mutate(DiffPeriod= (ObsDate-lag(ObsDate)))
输出是:
Report| ReportPeriod|ObsDate |DiffPeriod
1 | 15 |2017-12-31 00:00:00|NA
1 | 15 |2017-12-31 06:00:00|6.0
1 | 15 |2017-12-31 12:30:00|6.5
2 | 11 |2018-01-01 07:00:00|NA
2 | 11 |2018-01-01 13:00:00|6.0
2 | 11 |2018-01-01 16:30:00|3.5
现在“报告”的前两个条目是 NA。这些值应该是从总报告期间“ReportPeriod”中减去的 DiffPeriod 的总和。
我使用以下代码做到了这一点。
xyz<- data.frame()
for (i in unique(example$Report)) {
df<- example %>% filter(Report==i)
hrs<- sum(df$DiffPeriod, na.rm = TRUE)
tot<- df$ReportPeriod[1]
bal<- tot-hrs
df$DiffPeriod[1]<- bal
xyz<- xyz %>% bind_rows(df)
}
最终输出是:
Report| ReportPeriod|ObsDate |DiffPeriod
1 | 15 |2017-12-31 00:00:00|2.5
1 | 15 |2017-12-31 06:00:00|6.0
1 | 15 |2017-12-31 12:30:00|6.5
2 | 11 |2018-01-01 07:00:00|1.5
2 | 11 |2018-01-01 13:00:00|6.0
2 | 11 |2018-01-01 16:30:00|3.5
有没有更好/更有效的方法来做我在上面的 for 循环中所做的事情tidyverse
?
谢谢。
解决方案
假设ReportPeriod
总是以小时为单位,我们可以首先得到和之间的差异ObsDate
,lag(ObsDate)
然后通过取每个组的第一个值之间的差异(),replace
NA
这只是第一行。ReportPeriod
sum
DiffPeriod
Report
library(dplyr)
example %>%
group_by(Report) %>%
mutate(DiffPeriod= difftime(ObsDate, lag(ObsDate), units = "hours"),
DiffPeriod = replace(DiffPeriod, is.na(DiffPeriod),
ReportPeriod[1] - sum(DiffPeriod, na.rm = TRUE)))
# Report ReportPeriod ObsDate DiffPeriod
# <dbl> <dbl> <dttm> <time>
#1 1 15 2017-12-31 00:00:00 2.5 hours
#2 1 15 2017-12-31 06:00:00 6.0 hours
#3 1 15 2017-12-31 12:30:00 6.5 hours
#4 2 11 2018-01-01 07:00:00 1.5 hours
#5 2 11 2018-01-01 13:00:00 6.0 hours
#6 2 11 2018-01-01 16:30:00 3.5 hours
推荐阅读
- packet - Packet Tracer 几个版本中扩展 acl 的问题
- javascript - 我正在寻找让按钮(当前居中)动画到左上角onClick,我已经有一个连接到这个元素的函数
- parsing - 语法中的reduce-reduce、shift-reduce冲突
- xml - 如何使用 XML 和 VBA 登录网站
- embedded-linux - 如何调试 Linux 启动时崩溃 (PetaLinux 2020.1)
- vb.net - 添加计时器,根据用户输入设置时间并使其成为冷却时间
- javascript - useState 不反映变化
- angular - Angular RouterTestingModule 测试不在路由器插座中呈现组件
- java - 在读取文件时让我的 Java 可执行文件查找动态文件路径(并保存它)的最佳方法是什么?
- vba - MS Access 自动填写表格不填写货币