Bagaimana Cara Memeriksa apakah Suatu Tanggal Ada dalam Daftar Interval di R?

Saya memiliki dua bingkai data (tibbles) dengan masing-masing 2 variabel:

  • df.POS: ID (variabel ID); TANGGAL (Tanggal tes lab positif)
  • df.NEG: ID (variabel ID); data (Tanggal tes lab negatif (lebih dari 1 tes).

Harap dicatat bahwa data adalah variabel daftar, dibuat dengan fungsi nest() dari paket rapir.

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

Saya ingin mengetahui tes positif mana yang juga tes negatif hingga 2 hari setelah hasil tes positif. Saya sudah mencoba menggunakan fungsi map2() dari paket purrr

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

Sayangnya, kode saya tidak berfungsi. Variabel RESULT harus logis dan mengembalikan TRUE jika hasil tes negatif hingga 2 hari setelah tes positif. Sebaliknya itu adalah daftar dan mengembalikan 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>

Adakah yang bisa membantu?

Saya sangat menghargai bantuan. Terima kasih banyak sebelumnya!


person Norbert Köhler    schedule 24.11.2018    source sumber


Jawaban (1)


Pertama, perhatikan bahwa Anda dapat menguji apakah elemen apa pun dari vektor tanggal "negatif" termasuk dalam interval "positif" seperti ini:

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

Ini menyarankan pendekatan berikut menggunakan map2 -- atau lebih berguna, 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 

Terima kasih kepada @ubutun untuk memperbaiki jawabannya.

person Weihuang Wong    schedule 24.11.2018
comment
Bukankah map2_lgl(data, TIME, ~ any(.x$DATE %within% y)) lebih jelas? Pokoknya - jawaban yang bagus, terima kasih atas informasi berharganya. - person utubun; 24.11.2018
comment
@utubun: Ah, benar -- lebih lugas. Saya akan mengedit untuk mencerminkan saran Anda. - person Weihuang Wong; 24.11.2018
comment
Terima kasih banyak. Itu hebat! :-) - person Norbert Köhler; 24.11.2018
comment
@NorbertKöhler: Selamat datang di SO, dan senang membantu. Jika jawaban ini menyelesaikan pertanyaan Anda, harap tandai sebagai diterima. - person Weihuang Wong; 24.11.2018