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



我的数据是随着时间的流逝(个人出生,个人死亡),因此所有个人都与他人重叠不同的时间。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

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

在这里指出了一些表面上类似的工作,其中FoverLaps功能,但是此功能以及我在其他问题中看到的类似问题的所有相关文档似乎都处理了涉及两个数据表的问题。基本概念公认是相似的,在不同数据之间找到共同的日期,但是我看不到如何使用FoverLaps函数编码一些问题来解决我的问题(在所有可能的个体中找到CONSONG范围,在单个表格中)。我考虑过要进行某种重复的循环,但这会很麻烦,并且随着数据表的变化而变得更加困难。

foverlaps()不需要。相反,使用A non-equi自加入(类似于combn()的功能),并且使用pmin()pmax()进行计算,每个ID彼此进行比较。

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)]
   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

请注意,OP的预期结果有所不同。包括主对角线,其中包含每个人的年龄。我相信这是比较核心时间时的宝贵信息。

数据

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

请注意,单个4已经离开了小组10个月。

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)]
   i.ID    1    2    3    4
1:    1 32.4 20.7 19.4 15.2
2:    2   NA 20.7 18.8 14.6
3:    3   NA   NA 19.4 15.2
4:    4   NA   NA   NA 15.8

请注意,主对角不再表示年龄,而是个人与该组的总隶属关系。

相关内容

  • 没有找到相关文章

最新更新