изменить первую запись сгруппированных данных на основе последующих записей

#r #dplyr

#r #dplyr

Вопрос:

Используя приведенный ниже набор данных:

 df <- structure(list(test = c("1st", "2nd", "3rd", "1st", "2nd", "3rd", "1st", "2nd", "3rd"),
                 id = c("PID1", "PID1", "PID1", "PID2", "PID2", "PID2", "PID3", "PID3", "PID3"),
                 date = c("2020-01-01", "2020-01-13", "2020-01-17", "2020-01-01", "2020-01-13", "2020-01-20", "2020-01-01", "2020-01-14", "2020-01-18"),
                 status_1 = c("Symp", "Symp", "uninfected", "Asymp", "Symp", "uninfected", "Asymp", "Asymp", "uninfected"),
                 status_2 = c("Symp", "Symp", "uninfected", "pre-Symp", "Symp", "uninfected", "Asymp", "Asymp", "uninfected")),
            class = "data.frame",
            row.names = c(NA, -9L)
            )
  

Я хотел бы определить лиц, status_1 является Asymp первым test и проверить, являются ли они в течение 14 дней Symp .

У таких пользователей должно быть status_2 изменение на pre-Symp , в противном случае их статус должен оставаться прежним, например, у человека с идентификатором PID3 .

  • Этот пользователь Asymp после первого теста и не переходит к Symp в течение 14 дней, поэтому его статус остается Asymp

Вот код, который я пытался собрать, но я продолжаю сталкиваться с ошибками:

 df <- df %>% 
  mutate(status_2 = case_when(test == "1st" amp; 
                                status_1 == "Asymp" amp; 
                                status_1[date   14] != "Symp" ~ "pre-Symp",
                              TRUE ~ status_1))
  

Ответ №1:

Вы можете создать свою собственную пользовательскую функцию, которая проверяет состояние в течение этого временного интервала.

 library(dplyr)

check_status <- function(x, date) {
  if(first(x) == 'Asymp' amp; any(x == 'Symp')) {
    if (date[which.max(x == 'Symp')] - first(date) < 14)
      x[1] <- 'pre-Symp'
  }
  return(x)
}
  

Теперь примените эту функцию по группам :

 df %>%
  mutate(date = as.Date(date)) %>%
  group_by(id) %>%
  mutate(status_2 = check_status(status_1, date))

# test  id    date       status_1   status_2  
#  <chr> <chr> <date>     <chr>      <chr>     
#1 1st   PID1  2020-01-01 Symp       Symp      
#2 2nd   PID1  2020-01-13 Symp       Symp      
#3 3rd   PID1  2020-01-17 uninfected uninfected
#4 1st   PID2  2020-01-01 Asymp      pre-Symp  
#5 2nd   PID2  2020-01-13 Symp       Symp      
#6 3rd   PID2  2020-01-20 uninfected uninfected
#7 1st   PID3  2020-01-01 Asymp      Asymp     
#8 2nd   PID3  2020-01-14 Asymp      Asymp     
#9 3rd   PID3  2020-01-18 uninfected uninfected