Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace NA in all columns of a dplyr chain

Tags:

r

dplyr

tidyverse

The question replace NA in a dplyr chain results into the solution

dt %.% group_by(a) %.% mutate(b = ifelse(is.na(b), mean(b, na.rm = T), b))

with dplyr. I want to impute all colums with dplyr chain. There is no single column to group by, rather I want all numeric columns to have all NAs replaced by the means such as column means.

What is the most elegant way to replace all NAs with column means with tidyverse/dp?

like image 575
hhh Avatar asked Jan 02 '18 10:01

hhh


1 Answers

We can use mutate_all with ifelse

dt %>%
   group_by(a) %>% 
   mutate_all(funs(ifelse(is.na(.), mean(., na.rm = TRUE), .)))

If we want a compact option, then use the na.aggregate from zoo which by default replace NA values with mean

dt %>% 
   group_by(a) %>% 
   mutate_all(zoo::na.aggregate)

If we don't have a grouping variable, then remove the group_by and use mutate_if (just to be cautious about having some non-numeric column)

dt %>%
   mutate_if(is.numeric, zoo::na.aggregate)

If all the columns are numeric, even

zoo::na.aggregate(dt)

data

set.seed(42)
dt <- data.frame(a = rep(letters[1:3], each = 3),
                 b= sample(c(NA, 1:5), 9, replace = TRUE), 
                 c = sample(c(NA, 1:3), 9, replace = TRUE))
like image 96
akrun Avatar answered Sep 19 '22 09:09

akrun