Рассчитать количество перекрывающихся дней между двумя наборами дат периодов в соответствии с условием и перекрытием периодов (частично) - PullRequest
0 голосов
/ 06 декабря 2018

Как и в вопросе, опубликованном здесь , я хочу вычислить количество перекрывающихся дней между двумя периодами при условии третьей переменной (местоположения).

Для каждого наблюдения основного набора данных (DF) у меня есть дата начала и окончания, а также переменная местоположения (символа).Данные о событиях содержат информацию о месте события, дате начала и дате окончания.Допускается несколько событий в одном месте и (частично) перекрывающиеся периоды.

Таким образом, для каждого наблюдения в DF период должен сравниваться с другими периодами в наборе данных событий (События).Это означает, что подсчет перекрывающихся дней между одним (DF) и множественным периодами (событиями) должен выполняться за вычетом перекрывающихся дней между двумя (или более) периодами в наборе данных событий

Пример данныхСтруктура моих двух источников данных может быть легко воспроизведена в R с помощью этого кода (обратите внимание, что переменная местоположения была установлена ​​в целое число для простоты):

        set.seed(1)
    DF <- data.frame(
      start = sample(seq(as.Date('2018-01-01'), as.Date('2018-04-30'), by="day"), 20),
      end = sample(seq(as.Date('2018-05-01'), as.Date('2018-10-30'), by="day"), 20),
      location = sample(seq(1:5)),20)


    Events <- data.frame(
      start = sample(seq(as.Date('2018-01-01'), as.Date('2018-04-30'), by="day"), 30),
      end = sample(seq(as.Date('2018-05-01'), as.Date('2018-10-30'), by="day"), 30),
      location = sample(seq(1:5)),  30 )

В простом случае, когда данные событий уменьшаютсятолько для одного события (и нас не волнует местоположение), подсчет общих дней для каждой проблемы в DF можно легко выполнить с помощью следующего кода и dplyr: код взят из ответа Мэтью Лундберга здесь , такжеобратите внимание, что я создал другой фрейм данных с одним событием (One_event):

library(dplyr)

One_event <- data.frame(
  start = as.Date('2018-01-01'),
  end = as.Date('2018-07-30'))

DF %>%
  mutate(overlap = pmax(pmin(One_event$end, end) - pmax(One_event$start, start) + 1,0))

, что привело к:

   start        end       location X20  overlap
1  2018-02-01 2018-10-19        5  20 180 days
2  2018-02-14 2018-06-08        3  20 115 days
3  2018-03-09 2018-08-26        4  20 144 days
4  2018-04-17 2018-05-23        2  20  37 days
5  2018-01-24 2018-06-17        1  20 145 days
6  2018-04-14 2018-07-08        5  20  86 days
7  2018-04-18 2018-05-03        3  20  16 days
8  2018-03-16 2018-07-07        4  20 114 days
9  2018-03-12 2018-09-30        2  20 141 days
10 2018-01-07 2018-06-29        1  20 174 days
11 2018-01-23 2018-07-23        5  20 182 days
12 2018-01-20 2018-08-12        3  20 192 days
13 2018-04-23 2018-07-24        4  20  93 days
14 2018-02-11 2018-06-01        2  20 111 days
15 2018-03-23 2018-09-17        1  20 130 days
16 2018-02-22 2018-08-21        5  20 159 days
17 2018-04-24 2018-09-10        3  20  98 days
18 2018-04-13 2018-05-18        4  20  36 days
19 2018-02-08 2018-08-28        2  20 173 days
20 2018-03-20 2018-10-23        1  20 133 days

Теперь вернемся к первоначальной проблеме.Чтобы разрешить сравнение между периодом каждого наблюдения в данных и совпадающим событием (ями) в соответствии с наблюдением и местоположением события, я думаю, что было бы разумно использовать функцию apply, подмножество набора данных события в соответствии с местом наблюдения и, наконец,запустите функцию mutate для каждой строки и подмножества данных Events (temp):

    apply(DF, 1, function(x) {
  temp =  Events[Events$location %in% x["location"]
 x %>%
      mutate(overlap = pmax(pmin(temp$end, end) - pmax(temp$start, start) + 
1,0))
})

Существует несколько проблем с этой последней частью кода.Во-первых, не работает и выдает сообщение об ошибке:

(Error in UseMethod("mutate_") : 
  no applicable method for 'mutate_' applied to an object of class "character")

Во-вторых, он не учитывает два (или более периода) перекрытия в наборе данных Events.

1 Ответ

0 голосов
/ 06 декабря 2018

вы ищете это:

apply(DF, MARGIN = 1, function(x) {
  Events[Events$location == x["location"],] %>% mutate(overlap = pmax(pmin(.data$end,         
  x["end"]) - pmax(.data$start, x["start"])))
})

В моем случае это приводит к:

[[1]]
   start        end location X30  overlap
1 2018-02-01 2018-07-28        5  30 177 days
2 2018-04-14 2018-08-27        5  30 135 days
3 2018-01-23 2018-09-20        5  30 231 days
4 2018-02-22 2018-09-10        5  30 200 days
5 2018-04-04 2018-07-17        5  30 104 days
6 2018-02-06 2018-05-16        5  30  99 days

[[2]]
   start        end location X30  overlap
1 2018-01-24 2018-09-26        3  30 114 days
2 2018-01-07 2018-07-11        3  30 114 days
3 2018-03-23 2018-10-28        3  30  77 days
4 2018-03-20 2018-08-22        3  30  80 days
5 2018-01-26 2018-05-12        3  30  87 days
6 2018-01-31 2018-07-02        3  30 114 days

[[3]]
   start        end location X30  overlap
1 2018-03-09 2018-07-29        4  30 142 days
2 2018-03-16 2018-05-19        4  30  64 days
3 2018-04-23 2018-09-11        4  30 125 days
4 2018-04-13 2018-07-19        4  30  97 days
5 2018-03-05 2018-07-10        4  30 123 days
6 2018-02-05 2018-07-20        4  30 133 days

...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...