使用 data.table 删除 6 周内的重复测试

问题描述 投票:0回答:1

我有一个数据集,其中包含在不同诊所进行性传播感染测试的个人。我想让每个人在最终数据集中每 6 周只进行一次测试。

还有与此相关的类似问题 如此处所示。但是,我尝试使用此代码,但运行时间很长,因为我的数据集有超过 4000 万行。因此,我想使用 data.table,因为这通常更快。

请看一个可以使用的数据集:

library(tidyverse)
library(data.table)

date=c("2023-01-01", "2023-02-07", "2023-02-20", "2023-01-01", "2023-05-10", "2023-01-01", "2023-01-01", "2023-01-10", "2023-04-10", "2023-01-01", "2023-01-10")
ID=c("A", "A", "A", "B", "B", "C", "D", "D", "D", "E", "E")
clinic=c("clinic1", "clinic1", "clinic1", "clinic2", "clinic2", "clinic3", "clinic4", "clinic5", "clinic4", "clinic6", "clinic6")
df=as.data.frame(cbind(date, ID, clinic))

df=df %>% mutate(date=as.Date(date))
df=data.table(df)

在此示例中,我希望删除人员 A 在 2 月 7 日的测试和人员 E 在 1 月 10 日的测试。

r data.table
1个回答
0
投票

这可以通过 reduction

base::Reduce
purrr::reduce
)来完成:

df[, date := as.Date(date)] # since you have strings
df[, .SD[Reduce(function(kept, rn) c(kept, if (diff(date[c(kept[length(kept)], rn)]) >= 6*7) rn),
                seq_len(.N)[-1], init=1),], ID]
#        ID       date  clinic
#    <char>     <Date>  <char>
# 1:      A 2023-01-01 clinic1
# 2:      A 2023-02-20 clinic1
# 3:      B 2023-01-01 clinic2
# 4:      B 2023-05-10 clinic2
# 5:      C 2023-01-01 clinic3
# 6:      D 2023-01-01 clinic4
# 7:      D 2023-04-10 clinic4
# 8:      E 2023-01-01 clinic6

匿名函数有两个参数:

  • kept
    是之前要保留的“接受”位置(行索引),初始化为“1”;
  • 对于每行
    2:.N
    (在一个组内),我们确定由 kept 索引的
    last
    日期是否在
    this
    日期的 6*7 天内,ala
    date[ kept[length(kept)] ]
    是否在
    date[ rn ]
    的 42 天内;如果这是真的,那么我们将
    rn
    附加到
    kept
  • 中的前一个向量
© www.soinside.com 2019 - 2024. All rights reserved.