Поведение dplyr в case_when и lag - PullRequest
0 голосов
/ 01 января 2019

У меня есть набор данных, в котором есть studyid, год и два флага: инцидент и распространенность.Мне бы хотелось, чтобы преобладающая переменная была TRUE (1) для всех лет после того, как флаг инцидента имеет значение true (а переменная инцидента может быть истинной только один раз).case_when и lag кажутся идеальной комбинацией, но если для инцидента установлено значение 1 в году N, то для распространенности устанавливается значение ИСТИНА только в N + 1, и наоборот, в 0 в N + 1.Это не было ожидаемым поведением.

Вот пример кода:

library(tidyverse)

# make a fake dataset
testdat <- tribble(
  ~studyid, ~datestring, ~incident,
  "1", "2000-01-01", 0,
  "1", "2001-01-01", 1,
  "1", "2002-01-01", 0,
  "1", "2003-01-01", 0,
  "2", "2003-01-01", 0,
  "2", "2004-01-01", 1,
  "2", "2005-01-01", 0,
  "2", "2006-01-01", 0
) %>% mutate(
  prevalent = 0,
  date = lubridate::ymd(datestring)
) %>% group_by(studyid) %>% 
  arrange(studyid, date) %>% 
  mutate(prevalent = case_when(
    #logic is, if prevalent in year N-1, the prevalent in year N
    # if incident in year N-1, then prevalent in year N
    # otherwise not prevalent (because never incident)
    dplyr::lag(prevalent, 1L)==1 ~1,
    dplyr::lag(incident, 1L)==1 ~1,
    TRUE ~ 0
  ) #close case_when
  ) #close mutate
testdat

Вывод:

# A tibble: 8 x 5
# Groups:   studyid [2]
  studyid datestring incident prevalent date      
  <chr>   <chr>         <dbl>     <dbl> <date>    
1 1       2000-01-01        0         0 2000-01-01
2 1       2001-01-01        1         0 2001-01-01
3 1       2002-01-01        0         1 2002-01-01
4 1       2003-01-01        0         0 2003-01-01
5 2       2003-01-01        0         0 2003-01-01
6 2       2004-01-01        1         0 2004-01-01
7 2       2005-01-01        0         1 2005-01-01
8 2       2006-01-01        0         0 2006-01-01
> 

Желаемый вывод:

studyid=1, year=2003  prevalent ==1 (not 0)
studyid=2, year=2006  prevalent ==1 (not 0)

Я подозреваю, что это связано с тем, как case_when взаимодействует с dplyr :: lag.Как я могу улучшить логику / синтаксис для получения необходимых результатов?

Большое спасибо,

1 Ответ

0 голосов
/ 02 января 2019

Вы ищете что-то вроде последнего перенесенного наблюдения, например, zoo::na.locf или tidyr::fill, но я буду использовать что-то простое, например:

library(dplyr)
testdat %>% 
   mutate(date = lubridate::ymd(datestring)) %>% group_by(studyid) %>% 
   arrange(studyid, date) %>% mutate(prevalent=cumsum(lag(incident,default = 0)==1))

# A tibble: 8 x 5
# Groups:   studyid [2]
  studyid datestring incident date       prevalent
  <chr>   <chr>         <dbl> <date>         <int>
1 1       2000-01-01        0 2000-01-01         0
2 1       2001-01-01        1 2001-01-01         0
3 1       2002-01-01        0 2002-01-01         1
4 1       2003-01-01        0 2003-01-01         1
5 2       2003-01-01        0 2003-01-01         0
6 2       2004-01-01        1 2004-01-01         0
7 2       2005-01-01        0 2005-01-01         1
8 2       2006-01-01        0 2006-01-01         1
...