Reputation: 11686
Suppose I have the following column
**CurrentStatus**
Current
NoChange
NoChange
NoChange
NoChange
Late
I want to mutate it so that if the value is "NoChange" it uses the prior value.
I tried:
myDF %>% mutate(CurrentStatus = ifelse(CurrentStatus == "NoChange", lag(CurrentStatus), CurrentStatus)
That doesn't seem to work -- I think it's because it does a vectorized calculation so it looks at all the lags at the same time. I need it to "roll forward". I was wondering what's the most efficient way to do this without a for loop. I specifically want to avoid a for loop as there are some grouping variables not shown that I need to be mindful of.
Thanks!
Upvotes: 5
Views: 652
Reputation: 287
You could use something like this:
rfwd<-function(value,trigger)
{
c("",value)[cummax(seq_along(value)*(trigger))+1]
}
and your answer would be rfwd(CurrentStatus,CurrentStatus!="NoChange")
> rfwd(LETTERS,seq_along(LETTERS)%%10==0)
[1] "" "" "" "" "" "" "" "" "" "J" "J" "J" "J" "J" "J" "J" "J" "J" "J" "T" "T" "T" "T" "T" "T" "T"
Upvotes: 0
Reputation: 887153
We can replace the 'NoChange' to NA
and then use fill
library(tidyverse)
myDF %>%
mutate(CurrentStatus = replace(CurrentStatus, CurrentStatus == "NoChange", NA)) %>%
fill(CurrentStatus)
# CurrentStatus
#1 Current
#2 Current
#3 Current
#4 Current
#5 Current
#6 Late
Or another option is na.locf
from zoo
library(zoo)
myDF$CurrentStatus <- with(myDF, na.locf(replace(CurrentStatus,
CurrentStatus == "NoChange", NA)))
Upvotes: 9