计算R中的动物核心时间,即二元重叠日期范围

时间:2016-12-21 02:17:28

标签: r date overlap

我的数据是动物组中的个体随着时间的推移(个体出生,个体死亡),因此所有个体在不同时间段内与其他人重叠。 A列是个人身份,B列是“开始日期”,“C”列是“结束日期”。

我想创建一个表格或矩阵(后者可能更容易阅读),它显示同时在组中所有人对/活着的时间。我想在R中做到这一点。

示例数据:

ID  start.date  end.date
1   5/22/83     10/31/15
2   7/10/94     3/15/15
3   5/24/96     10/31/15
4   10/1/99     5/12/14

示例输出(数字表示重叠的大致年份):

    1   2   3   4
1   NA  21  19  15
2   NA  NA  19  15
3   NA  NA  NA  15
4   NA  NA  NA  NA

虽然我有一个特定的问题(动物核心时间),但解决方案/方法可用于计算任何类型的重叠日期范围的二元持续时间。

有一些表面上类似的工作已被指出here,具有foverlaps功能,但是这个功能以及我在其他问题中看到的类似问题的所有相关文档似乎都涉及涉及两个数据表的问题。基本概念无疑是相似的,在不同的数据中找到共同的日期,但我不知道如何使用foverlaps函数编写一些东西来解决我的问题(在单个表中查找所有可能的个体集之间的commong范围) 。我考虑过做某种重复循环,但这会很麻烦,随着数据表变大会变得更加困难。

1 个答案:

答案 0 :(得分:0)

foverlaps()不是必需的。取而代之的是,每个ID使用非等价自连接(类似于combn()进行比较),并且使用pmin()和{ {1}}。

pmax()
library(data.table)
# add dummy ID column to join on for non-equi join
DT[, join.ID := ID][
  # non-equi join to create combinations
  DT, on = .(join.ID >= join.ID)][
    # compute years of overlap
    , overlap.years := round(as.integer(
      pmin(end.date, i.end.date) - pmax(start.date, i.start.date)) / 365.25)][
        # remove negative values (no overlap)
        overlap.years > 0][
          # reshape from long to wide format
          , dcast(.SD, i.ID ~ ID)]

请注意,OP的预期结果有所不同。包括了主要的对角线,其中包含每个人的年龄。我相信这在比较置信度时间时是有价值的信息。

数据

   i.ID  1  2  3  4
1:    1 32 21 19 15
2:    2 NA 21 19 15
3:    3 NA NA 19 15
4:    4 NA NA NA 15

多次置信

如果某人离开该小组并稍后返回,则需要修改以上代码:

library(data.table)
DT <- fread(
  "ID  start.date  end.date
1   5/22/83     10/31/15
2   7/10/94     3/15/15
3   5/24/96     10/31/15
4   10/1/99     5/12/14"
)
# convert date string to class Date
cols <- c("start.date", "end.date")
DT[, (cols) := lapply(.SD, lubridate::mdy), .SDcols = cols]

请注意,个人# read dat of new case DT2 <- fread( "ID start.date end.date 1 5/22/83 10/31/15 2 7/10/94 3/15/15 3 5/24/96 10/31/15 4 10/1/99 5/12/14 4 3/20/15 5/12/16" ) cols <- c("start.date", "end.date") DT2[, (cols) := lapply(.SD, lubridate::mdy), .SDcols = cols] DT2 已离开小组10个月。

4
DT2[, join.ID := ID][
  DT2, on = .(join.ID >= join.ID), allow = TRUE][
    , overlap.years := as.integer(
      pmin(end.date, i.end.date) - pmax(start.date, i.start.date)) / 365.25][
        overlap.years > 0][
        , dcast(.SD, i.ID ~ ID, function(x) round(sum(x), 1), fill = NA)]

请注意,主对角线不再代表年龄,而是个人与该团体的总联系时间。