#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