จะตรวจสอบว่าวันที่อยู่ในรายการช่วงเวลาใน R ได้อย่างไร

ฉันมีสองเฟรมข้อมูล (tibbles) โดยมี 2 ตัวแปรในแต่ละเฟรม:

  • df.POS: ID (ตัวแปร ID); DATE (วันที่ของการทดสอบในห้องปฏิบัติการที่เป็นบวก)
  • df.NEG: ID (ตัวแปร ID); ข้อมูล (วันที่ของการทดสอบในห้องปฏิบัติการเชิงลบ (มากกว่า 1 การทดสอบ)

โปรดทราบว่าข้อมูลเป็นตัวแปรรายการที่สร้างขึ้นด้วยฟังก์ชัน 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 วันหลังจากผลการทดสอบเป็นบวก ฉันได้ลองใช้ฟังก์ชัน map2() ของแพ็คเกจ 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)) 

น่าเสียดายที่รหัสของฉันใช้งานไม่ได้ ตัวแปร RESULT ควรเป็นตรรกะและส่งกลับค่า TRUE ในกรณีที่ผลการทดสอบเป็นลบภายใน 2 วันหลังจากการทดสอบเชิงบวก แต่เป็นรายการและส่งคืนค่า 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>

ใครสามารถช่วยได้บ้าง?

ฉันขอขอบคุณความช่วยเหลือ ขอบคุณมากล่วงหน้า!


person Norbert Köhler    schedule 24.11.2018    source แหล่งที่มา


คำตอบ (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 สำหรับการปรับปรุงคำตอบ

person Weihuang Wong    schedule 24.11.2018
comment
จะไม่อธิบายตัวเองมากกว่านี้อีก map2_lgl(data, TIME, ~ any(.x$DATE %within% y)) ใช่ไหม อย่างไรก็ตาม - คำตอบที่ดี ขอบคุณสำหรับข้อมูลอันมีค่า - person utubun; 24.11.2018
comment
@utubun: อ่าถูกต้อง - ตรงไปตรงมากว่านี้มาก ฉันจะแก้ไขเพื่อสะท้อนข้อเสนอแนะของคุณ - person Weihuang Wong; 24.11.2018
comment
ขอบคุณมาก. เยี่ยมมาก! :-) - person Norbert Köhler; 24.11.2018
comment
@ NorbertKöhler: ยินดีต้อนรับสู่ SO และยินดีที่จะช่วยเหลือ หากคำตอบนี้ช่วยตอบคำถามของคุณได้ โปรดทำเครื่องหมายว่ายอมรับแล้ว - person Weihuang Wong; 24.11.2018