I have a sequence of treatments, one per day (binary), say:
trt <- c(0, 0, 1, 0, 0, 0, 1, 0, 0)
I want to create a vector, days_since
, that:
trt
is 1So, the output days_since
should be:
days_since <- c(NA, NA, 0, 1, 2, 3, 0, 1, 2)
How would I do this in R? To get days_since
, I basically need to lag by one element and add 1, but resetting every time the original vector (trt
) is 1. If this is doable without a for-loop, that would be ideal, but not absolutely necessary.
Maybe you can try the code below
v <- cumsum(trt)
replace(ave(trt,v,FUN = seq_along)-1,v<1,NA)
which gives
[1] NA NA 0 1 2 3 0 1 2
Explanation
cumsum
over trt
to group the treatments> v <- cumsum(trt)
> v
[1] 0 0 1 1 1 1 2 2 2
ave
helps to add sequential indices within each group> ave(trt,v,FUN = seq_along)-1
[1] 0 1 0 1 2 3 0 1 2
NA
before the first treatment, it means all the value before v == 1
appears should be replaced by NA
. Thus we use replace
, and the index logic follows v < 1
> replace(ave(trt,v,FUN = seq_along)-1,v<1,NA)
[1] NA NA 0 1 2 3 0 1 2