Заменить пропущенное значение на среднее значение в столбце - PullRequest
1 голос
/ 01 мая 2020

У меня большой набор данных с некоторыми пропущенными значениями (NA). Я пытаюсь заменить эти значения средствами столбца, но классом , то есть, если элементы в классе k имеют отсутствующее значение в столбце j, это значение будет заменено средним значением значений в столбце. J для предметов в классе k. Кроме того, я хочу сделать это только с базой R или dplyr.

Аспект класса приносит дополнительную проблему по сравнению с известным, который уже был здесь ответили: Замените пропущенные значения средним по столбцу .

Фактически я могу адаптировать одно из решений там в неуклюжее решение для моей проблемы:

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

( где датафрейм DF, и я предположил, что коэффициент хранится в столбце «класс».)

Затем вы повторите это для всех других классов (например, B, C, D, E, F ). Наконец, вы можете использовать DF <- rbind (A, B, C, D, E, F), чтобы заменить ваш старый фрейм данных на исправленный. </p>

Фрейм данных в моем случае упорядочен по классу (т.е. Сначала, потом B, потом C, ...), и я бы хотел, чтобы все было так.

Есть ли способ сделать это намного эффективнее?

Ответы [ 3 ]

1 голос
/ 01 мая 2020

База 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)
  }))
1 голос
/ 01 мая 2020

Мы можем использовать na.aggregate из zoo

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))
0 голосов
/ 01 мая 2020

Используя dplyr, вы можете group_by Class и применять NA2mean для каждого столбца.

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

В более новой версии dplyr вы можете сделать это across

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