I have a large dataframe that has this general format
week1 <- c("2.30", "14.10", "5.60")
week2 <- c("NA", "13.95", "NA")
week3 <- c("NA", "14.15", "5.30")
week4 <- c("2.30", "NA", "5.60")
week5 <- c("2.25", "14.10", "5.55")
week6 <- c("2.00", "14.00", "NA")
week7 <- c("1.95", "14.15", "5.60")
df <- data.frame(week1, week2, week3, week4, week5, week6, week7)
Now I'm trying to find a way to fill the NAs by using a row-wise moving averages, where I want the average to be based on 4 observations at a time, without use of a loop. Preferably, I would be able to do this working from left to right and vice versa (in a second operation).
I am pretty new to coding, I appreciate all the help I can get!
this is a bit of hacky way to do it. I am not sure if your data is numeric or like characters as you have put in your weeks but this will work none the less. There is a warning you will get in the mutate(value = as.numeric(value))
but you can ignore it/shouldnt have this issue if your data is actually numeric.
df %>%
rownames_to_column("id_col") %>%
gather(week, value, -1) %>%
mutate(value = as.numeric(value)) %>%
group_by(id_col) %>%
mutate(value_no_na = zoo::rollapply(value, na.rm=TRUE, FUN="mean", width=4, fill=NA, align = "center")) %>%
tidyr::fill(value_no_na, .direction = "up") %>%
tidyr::fill(value_no_na, .direction = "down") %>%
ungroup() %>%
mutate(value = ifelse(is.na(value), value_no_na, value)) %>%
select(-value_no_na) %>%
spread(week, value) %>%
select(-id_col)
For reverse order you can do
df %>%
select(ncol(df):1) %>%
rownames_to_column("id_col") %>%
gather(week, value, -1) %>%
mutate(value = as.numeric(value)) %>%
group_by(id_col) %>%
mutate(value_no_na = zoo::rollapply(value, na.rm=TRUE, FUN="mean", width=4, fill=NA, align = "center")) %>%
tidyr::fill(value_no_na, .direction = "up") %>%
tidyr::fill(value_no_na, .direction = "down") %>%
ungroup() %>%
mutate(value = ifelse(is.na(value), value_no_na, value)) %>%
select(-value_no_na) %>%
spread(week, value) %>%
select(-id_col)
Finally you can play around with the alignment in rollapply
to decide whether you want the moving averages to be left, right or center aligned.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.