R - неожиданный результат при использовании фоверлапса с датами - PullRequest
1 голос
/ 18 апреля 2020

У меня есть две таблицы данных с миллионами строк, в которых есть пары IDs с частичным перекрытием даты. Ниже приведен очень короткий пример:

library(data.table)
dt1 <- data.table(ID=720,
                  startdate=as.IDate("2000-01-01"),
                  enddate=as.IDate("2017-10-09"))
dt2 <- data.table(ID=720,
                  startdate=as.IDate("2000-06-08"),
                  enddate=as.IDate("2020-04-12"))

Я бы хотел найти перекрывающийся период времени между двумя наборами данных. Я пытаюсь сделать это, используя foverlaps:

setkey(dt1, ID, startdate, enddate)
setkey(dt2, ID, startdate, enddate)

foverlaps(dt1, dt2, by.x=c("ID", "startdate", "enddate"),
          by.y=c("ID", "startdate", "enddate"), type='within', nomatch = 0L)

Empty data.table (0 rows and 5 cols): ID,startdate,enddate,i.startdate,i.enddate

Приведенный выше код возвращает пустую таблицу данных, поскольку диапазон дат в dt1 не является полностью в пределах диапазона дат в dt2.

Однако я ожидал, что таблица данных с любым диапазоном дат является общей для двух наборов данных, который будет:

       ID  startdate    enddate
  1: 720  2000-06-08 2017-10-09

Есть ли в любом случае, чтобы достичь этого с помощью foverlaps? Если нет, есть ли альтернатива, которая бы работала так же быстро для миллионов строк?

1 Ответ

2 голосов
/ 19 апреля 2020

Я думаю, вам сначала нужно изменить type='within' на type = 'any'

. within означает, что диапазон дат в dt1 находится в пределах dt2

. После этого вы можете Вам нужно найти перекрывающийся диапазон дат самостоятельно (что довольно просто). Как и foverlaps, join.

library(data.table)
dt1 <- data.table(ID=720,
                  startdate=as.IDate("2000-01-01"),
                  enddate=as.IDate("2017-10-09"))
dt2 <- data.table(ID=720,
                  startdate=as.IDate("2000-06-08"),
                  enddate=as.IDate("2020-04-12"))


setkey(dt1, ID, startdate, enddate)
setkey(dt2, ID, startdate, enddate)

result <- foverlaps(dt1, dt2, by.x=c("ID", "startdate", "enddate"),
          by.y=c("ID", "startdate", "enddate"), type='any', nomatch = 0L)
result
#>     ID  startdate    enddate i.startdate  i.enddate
#> 1: 720 2000-06-08 2020-04-12  2000-01-01 2017-10-09

result[,`:=`(overlapping_start=fifelse(i.startdate>=startdate,i.startdate,startdate),
            overlapping_end = fifelse(i.enddate<=enddate,i.enddate,enddate))]

result[,.(ID,overlapping_start,overlapping_end)]
#>     ID overlapping_start overlapping_end
#> 1: 720        2000-06-08      2017-10-09

Создано в 2020-04-19 пакетом Представить (v0.3.0)

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