【问题标题】:How to Check if a Date is Within a List of Intervals in R?如何检查日期是否在 R 的区间列表内?
【发布时间】:2019-04-26 21:17:33
【问题描述】:

我有两个数据框(tibbles),每个数据框有 2 个变量:

  • df.POS:ID(ID 变量); DATE(实验室检测呈阳性的日期)
  • df.NEG:ID(ID 变量);数据(阴性实验室测试的日期(超过 1 次测试)。

请注意,data 是一个列表变量,由 tidyr 包的 nest() 函数创建。

library(tidyverse)
library(lubridate)

# negative tests
dates.neg <- ymd(c('2018-02-01', '2018-02-06', '2018-02-10', 
             '2018-02-21', '2018-04-05'))
df.NEG <- tibble(ID = paste0('ID_', rep(1, 5)),
          DATE = dates.neg) %>%
       group_by(ID) %>% 
          nest()
df.NEG

## # A tibble: 1 x 2
##   ID    data            
##   <chr> <list>          
## 1 ID_1  <tibble [5 × 1]>


dates.pos <- ymd(c('2018-02-07', '2018-02-12', '2018-02-13', 
             '2018-02-20', '2018-02-21', '2018-03-18'))

df.POS <- tibble(ID = paste0('ID_', rep(1, 6)),
           DATE = dates.pos)
df.POS

## # A tibble: 6 x 2
##   ID    DATE      
##   <chr> <date>    
## 1 ID_1  2018-02-07
## 2 ID_1  2018-02-12
## 3 ID_1  2018-02-13
## 4 ID_1  2018-02-20
## 5 ID_1  2018-02-21
## 6 ID_1  2018-03-18

我想知道在阳性检测结果后的 2 天内,哪些阳性检测也有阴性检测。我试过使用 purrr 包的 map2() 函数

df.TOTAL <- df.POS %>%
  left_join(df.NEG, by = 'ID') %>%
    mutate(TIME = interval(DATE, DATE + days(2)),
           RESULT = map2(data, "DATE", TIME, ~ .x %within% .y)) 

不幸的是,我的代码不起作用。 RESULT 变量应该是逻辑的,并且在阳性测试后最多 2 天的阴性测试结果的情况下返回 TRUE。相反,它是一个列表并返回 NULL。

df.TOTAL

## # A tibble: 6 x 5
##   ID    DATE       data             TIME                           RESULT
##   <chr> <date>     <list>           <S4: Interval>                 <list>
## 1 ID_1  2018-02-07 <tibble [5 × 1]> 2018-02-07 UTC--2018-02-09 UTC <NULL>
## 2 ID_1  2018-02-12 <tibble [5 × 1]> 2018-02-12 UTC--2018-02-14 UTC <NULL>
## 3 ID_1  2018-02-13 <tibble [5 × 1]> 2018-02-13 UTC--2018-02-15 UTC <NULL>
## 4 ID_1  2018-02-20 <tibble [5 × 1]> 2018-02-20 UTC--2018-02-22 UTC <NULL>
## 5 ID_1  2018-02-21 <tibble [5 × 1]> 2018-02-21 UTC--2018-02-23 UTC <NULL>
## 6 ID_1  2018-03-18 <tibble [5 × 1]> 2018-03-18 UTC--2018-03-20 UTC <NULL>

谁能帮忙?

我将不胜感激。提前非常感谢!

【问题讨论】:

    标签: r list date tidyr purrr


    【解决方案1】:

    首先,请注意,您可以测试“负”日期向量中的任何元素是否落在“正”区间内,如下所示:

    any(dates.neg %within% interval(dates.pos[1], dates.pos[1] + days(2)))
    # [1] FALSE
    

    这建议使用map2 的以下方法——或者更有用的是map2_lgl

    df.TOTAL <- df.POS %>%
      left_join(df.NEG, by = 'ID') %>%
        mutate(TIME = interval(DATE, DATE + days(2)),
               RESULT = map2_lgl(data, TIME, ~any(.x$DATE %within% .y)))
    # # A tibble: 6 x 5
    #   ID    DATE       data             TIME                           RESULT
    #   <chr> <date>     <list>           <S4: Interval>                 <lgl> 
    # 1 ID_1  2018-02-07 <tibble [5 x 1]> 2018-02-07 UTC--2018-02-09 UTC FALSE 
    # 2 ID_1  2018-02-12 <tibble [5 x 1]> 2018-02-12 UTC--2018-02-14 UTC FALSE 
    # 3 ID_1  2018-02-13 <tibble [5 x 1]> 2018-02-13 UTC--2018-02-15 UTC FALSE 
    # 4 ID_1  2018-02-20 <tibble [5 x 1]> 2018-02-20 UTC--2018-02-22 UTC TRUE  
    # 5 ID_1  2018-02-21 <tibble [5 x 1]> 2018-02-21 UTC--2018-02-23 UTC TRUE  
    # 6 ID_1  2018-03-18 <tibble [5 x 1]> 2018-03-18 UTC--2018-03-20 UTC FALSE 
    

    感谢@ubutun 改进答案。

    【讨论】:

    • map2_lgl(data, TIME, ~ any(.x$DATE %within% y)) 不是更不言自明吗?无论如何 - 很好的答案,感谢您提供宝贵的信息。
    • @utubun:啊,没错——更直接。我会修改以反映您的建议。
    • 非常感谢。那太棒了! :-)
    • @NorbertKöhler:欢迎来到 SO,很乐意为您提供帮助。如果此答案解决了您的问题,请将其标记为已接受。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-06
    • 2022-11-26
    • 2020-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-21
    相关资源
    最近更新 更多