Как добавить новую колонку в один фрейм данных на основе временных интервалов в другом фрейме данных

#r

#r

Вопрос:

У меня есть два фрейма данных. Один из них (df1) суммировал, когда рыба была обнаружена в определенной области. Другой суммирует периоды, в которые были дайверы в этой конкретной области. В качестве примера:

 datetime<- c("2016-08-01 06:00:02","2016-08-01 09:31:27","2016-08-01 13:34:02","2016-08-01 16:45:15","2016-08-02 09:07:12","2016-08-02 11:25:02","2016-08-02 17:25:02","2016-08-02 21:50:00")
df1<-data.frame(datetime)
df1$datetime<- as.POSIXct(df1$datetime, format = "%Y-%m-%d %H:%M:%S")
start<- c("2016-08-01 07:00:00","2016-08-01 08:30:00","2016-08-01 10:30:00","2016-08-01 16:00:00","2016-08-02 10:00:00","2016-08-02 16:00:00")
end<- c("2016-08-01 08:30:00","2016-08-01 10:00:00","2016-08-01 12:00:00","2016-08-01 17:30:00","2016-08-02 11:30:00","2016-08-02 17:30:00")
divers<-c(6,2,8,12,8,7)
df2<-data.frame(start,end,divers)
df2$start<- as.POSIXct(df2$start, format = "%Y-%m-%d %H:%M:%S")
df2$end<- as.POSIXct(df2$end, format = "%Y-%m-%d %H:%M:%S")

df1
        datetime
1 2016-08-01 06:00:02
2 2016-08-01 09:31:27
3 2016-08-01 13:34:02
4 2016-08-01 16:45:15
5 2016-08-02 09:07:12
6 2016-08-02 11:25:02
7 2016-08-02 17:25:02
8 2016-08-02 21:50:00

df2 # Notice there are four periods with divers on 2016-08-01 and only two on 2016-08-02.

            start               end         divers
1 2016-08-01 07:00:00 2016-08-01 08:30:00      6
2 2016-08-01 08:30:00 2016-08-01 10:00:00      2
3 2016-08-01 10:30:00 2016-08-01 12:00:00      8
4 2016-08-01 16:00:00 2016-08-01 17:30:00     12
5 2016-08-02 10:00:00 2016-08-02 11:30:00      8
6 2016-08-02 16:00:00 2016-08-02 17:30:00      7
  

Я хотел бы добавить информацию о присутствии дайверов в новый столбец в моем фрейме данных df1. В этом новом столбце в df1, давайте назовем его «дайверы», я хотел бы показать количество дайверов, присутствующих на момент обнаружения рыбы. Если, когда рыба присутствовала в соответствии с df1, в районе не было дайверов в соответствии с df2, тогда добавьте 0 к «df1 $ divers». Если, когда рыба присутствовала в соответствии с df1, было 5 дайверов, добавьте 5 к «df1 $ divers». В качестве примера того, что я ожидал бы:

 datetime<- c("2016-08-01 06:00:02","2016-08-01 09:31:27","2016-08-01 13:34:02","2016-08-01 16:45:15","2016-08-02 09:07:12","2016-08-02 11:25:02","2016-08-02 17:25:02","2016-08-02 21:50:00")
divers<- c(0,2,0,12,0,8,7,0)
result<-data.frame(datetime,divers)
result$datetime<- as.POSIXct(result$datetime, format = "%Y-%m-%d %H:%M:%S")

result
             datetime divers
1 2016-08-01 06:00:02      0
2 2016-08-01 09:31:27      2
3 2016-08-01 13:34:02      0
4 2016-08-01 16:45:15     12
5 2016-08-02 09:07:12      0
6 2016-08-02 11:25:02      8
7 2016-08-02 17:25:02      7
8 2016-08-02 21:50:00      0

  

Ответ №1:

Используя базовый R, мы могли бы использовать столбец sapply over datetime в df1 и выяснить время, которое лежит между start и end временем df2 , получить соответствующие divers и sum их.

 df1$divers <- sapply(df1$datetime, function(x) 
                     sum(with(df2, divers[x >= start amp; x <= end])))

df1
#             datetime divers
#1 2016-08-01 06:00:02      0
#2 2016-08-01 09:31:27      2
#3 2016-08-01 13:34:02      0
#4 2016-08-01 16:45:15     12
#5 2016-08-02 09:07:12      0
#6 2016-08-02 11:25:02      8
#7 2016-08-02 17:25:02      7
#8 2016-08-02 21:50:00      0
  

Мы могли бы достичь того же, используя dplyr / purrr альтернативу с map_dbl

 library(dplyr)
library(purrr)

df1 %>%
mutate(divers = map_dbl(datetime, ~ sum(with(df2, divers[. >= start amp; . <= end]))))
  

В примере OP нет необходимости делать sum of divers , поскольку нет перекрытия по start и end времени, но в случае, если есть перекрытие, лучше иметь sum который добавил бы все дайверы за этот период времени.