Мне нужна помощь в написании более эффективного кода.У меня есть следующий набор данных.
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
Есть ли лучший / более эффективный способ сделать то, что я делал в цикле for выше в tidyverse
?
Спасибо.