用列内 class 的平均值替换缺失值

Replace missing value with mean of class within column

我有一个包含一些缺失值 (NA) 的大型数据集。我正在寻找用列方法替换这些值,但是 by class,也就是说,class k 中的项目在 j 列中缺少值,对于 class k 中的项目,该值将被 J 列中的值的平均值替换。 此外,我只想使用 base R 或 dplyr 来执行此操作。

与此处已经回答的众所周知的问题相比,class 方面带来了一个额外的问题:Replace missing values with column mean

事实上,我可以将其中一个解决方案改编成一个笨拙的解决方案来解决我的问题:

NA2mean <- function(x){replace(x, is.na(x), mean(x, na.rm = TRUE))}
DF %>% filter(DF$class=="A") -> A
A <- lapply(A,NA2mean)

(其中数据框是 DF,我假设该因子存储在 'class' 列中。)

然后每隔 class(例如 B、C、D、E、F)重复此操作。最后,您可以使用 DF <- rbind(A,B,C,D,E,F) 将旧数据框替换为更正后的数据框。

我的数据帧按 class 排序(即首先是 A,然后是 B,然后是 C,...),我想保持这种方式。

有什么方法可以更有效地做到这一点?

使用 dplyr,您可以 group_by Class 并为每一列应用 NA2mean

library(dplyr)
DF %>% group_by(class) %>% mutate_all(NA2mean)

在较新版本的 dplyr 中,您可以这样做 across

DF %>% group_by(class) %>% mutate(across(everything(), NA2mean))

基础 R 解决方案:

df[, sapply(df, is.numeric)] <-
  do.call("rbind", lapply(split(df[, sapply(df, is.numeric)], df$class), function(x) {
    x <- ifelse(is.na(x), mean(x, na.rm = TRUE), x)
  }))

我们可以使用 na.aggregatezoo

library(dplyr)
library(zoo)
DF %>%
  group_by(class) %>%
  mutate_at(vars(-group_cols()), na.aggregate)

如果我们需要base R

nm1 <- setdiff(names(DF), "class")
DF[nm1] <- lapply(DF[nm1], function(vec) ave(vec, class, FUN = NA2mean))