The below reprex mimics my data: for each person, I have different values of 'res' at different times. I need an indicator variable ('flag') to tell me each time that 'res' changes from 1 to 0 within a given person, and I want 'flag' to equal 1 at the first time (and the first time only) that 'res'= 0 after 'res' = 1. Lastly, I want to count the number of times 'flag' = 1 for each person.
My code has two problems:
- It flags every time after 'res'= 1 that 'res' = 0 (but I need 'flag'= 1 only the first time 'res'=0).
- Counting the number of times 'flag' = 1 does not work.
Note: The last 'res_next_time' is inevitably NA. By definition in my data, I would never have 'flag'=1 here, so it's okay that it defaults to 0.
Thanks for your help!
#Load packages
library(Hmisc)
#> Loading required package: lattice
#> Loading required package: survival
#> Loading required package: Formula
#> Loading required package: ggplot2
#>
#> Attaching package: 'Hmisc'
#> The following objects are masked from 'package:base':
#>
#> format.pval, units
library(dplyr)
#> Warning: package 'dplyr' was built under R version 4.0.4
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:Hmisc':
#>
#> src, summarize
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
library(tidyr)
#> Warning: package 'tidyr' was built under R version 4.0.5
#Create data set
person <- c(1, 1, 1, 2, 3, 3, 3, 3, 3, 3)
time <- c(1, 2, 3, 1, 2, 1, 2, 3, 4, 5)
res <- c(1, 0, 1, 1, 1, 0, 0, 1, 0, 1)
#Populate data frame
d <- cbind(person, time, res)
d <- as.data.frame(d)
#Create new variable equal to 'res' at the person's next time point
d$res_next_time <- Lag(d$res, -1)
#Group times by person
d %>%
group_by(person) %>%
#Create a new variable 'flag' = 1 when a person's 'res' changes from 1 to 0, and 'flag' = 0 otherwise
mutate(flag = case_when(res_next_time < 1 ~ 1, TRUE ~ 0)) %>%
#Because 'flag'= 1 is at the time of 'res'= 1 before 'res'= 0, we lag it to have 'flag' = 1 at 'res' = 0
mutate(flag_res0 = Lag(flag, +1)) %>%
#Replace the NAs in 'flag_res0' with 0
replace_na(list(flag_res0 = 0)) %>%
#mutate(flag_res0 = as.numeric(flag_res0 & cumsum(flag_res0) <= 1)) %>%
#Count number of flags per person
mutate(mig_freq = sum(flag_res0)) %>%
#Limit the data to only include the final indicator
select('person', 'time', 'res', 'flag_res0')
#> # A tibble: 10 x 4
#> # Groups: person [3]
#> person time res flag_res0
#> <dbl> <dbl> <dbl> <dbl>
#> 1 1 1 1 0
#> 2 1 2 0 1
#> 3 1 3 1 0
#> 4 2 1 1 0
#> 5 3 2 1 0
#> 6 3 1 0 1
#> 7 3 2 0 1
#> 8 3 3 1 0
#> 9 3 4 0 1
#> 10 3 5 1 0
Created on 2021-04-15 by the reprex package (v0.3.0)
