我正在寻找一些帮助编写更有效的代码。 我有以下数据集。
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。这些值应该是DiffPeriod的总和减去报告期间“ ReportPeriod”的总和。
我使用以下代码做到了这一点。
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
是否有更好/更有效的方法来完成我在tidyverse
的for循环中所做的工作?
谢谢。
答案 0 :(得分:2)
假设ReportPeriod
总是在几个小时内,我们首先可以得到ObsDate
和lag(ObsDate)
之间的差额,然后是replace
NA
,这仅仅是第一行通过对每个组(ReportPeriod
)取sum
的第一值与DiffPeriod
的{{1}}之间的差。
Report