Как и в вопросе, опубликованном здесь , я хочу вычислить количество перекрывающихся дней между двумя периодами при условии третьей переменной (местоположения).
Для каждого наблюдения основного набора данных (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.