关于 r:用列内类的平均值替换缺失值

Replace missing value with mean of class within column

我有一个包含一些缺失值 (NA) 的大型数据集。我希望将这些值替换为列均值,但按类别,即 k 类中的项目在 j 列中有缺失值,该值将替换为类别中项目的 J 列中值的平均值?。此外,我想只使用基本 R 或 dplyr。

与这里已经回答的众所周知的问题相比,类方面带来了一个额外的问题:用列均值替换缺失值。

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

1
2
3
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\\' 中。)

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

在我的例子中,数据框是按类排序的(即首先是 A,然后是 B,然后是 C,...),我希望保持这种状态。

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


我们可以使用 zoo

中的 na.aggregate

1
2
3
4
5
library(dplyr)
library(zoo)
DF %>%
  group_by(class) %>%
  mutate_at(vars(-group_cols()), na.aggregate)

如果我们需要 base R

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


Base R 解决方案:

1
2
3
4
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)
  }))


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

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

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

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