Reputation: 47
I have some longitudinal data and need to impute missing values by some rules:
If a person’s first follow-up data is missing, then add the value of the next row;
If a person's non-first follow-up data is missing, then add the value of the previous row;
If multiple consecutive follow-up data are missing, then add the value of the previous non-missing row.
Here is an example,
dat<-data.frame(id=c(1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3),b6=c(NA,1,1,1,1,1,1,1,1,1,NA,3,NA,NA,5,5,5,5,3,NA,NA))
dat_imputed<-data.frame(id=c(1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3),b6=c(1,1,1,1,1,1,1,1,1,1,1,3,3,5,5,5,5,5,3,3,3))
Thanks for any suggestions!
Upvotes: 1
Views: 816
Reputation: 2718
Group by id, fill values downwards, then fill upwards. I think this is what you need.
library(dplyr)
library(tidyr)
res <- dat %>%
group_by(id) %>%
fill(b6, .direction = "down") %>%
fill(b6, .direction = "up")
Upvotes: 1
Reputation: 39717
You can use approxfun
to add missing values inside ave
for grouping like:
dat$b6 <- ave(dat$b6, dat$id, FUN=function(x)
approxfun(x, method = "constant", rule=2)(seq_along(x)))
identical(dat, dat_imputed)
#[1] TRUE
Upvotes: 1