Замените НС средним значением того же столбца таблицы данных.

Я хочу заменить NAs, присутствующие в столбце таблицы DATA со средним значением того же столбца. Я делаю следующее. Но он не работает.

ww <- data.table(iris)

ww <- ww[1:5 , ]

ww[1,1] <- NA

   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1:           NA         3.5          1.4         0.2  setosa
2:          4.9         3.0          1.4         0.2  setosa
3:          4.7         3.2          1.3         0.2  setosa
4:          4.6         3.1          1.5         0.2  setosa
5:          5.0         3.6          1.4         0.2  setosa


ww[is.na(Sepal.Length) , Sepal.Length:= mean(Sepal.Length, na.rm = T)]

   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1:          NaN         3.5          1.4         0.2  setosa
2:          4.9         3.0          1.4         0.2  setosa
3:          4.7         3.2          1.3         0.2  setosa
4:          4.6         3.1          1.5         0.2  setosa
5:          5.0         3.6          1.4         0.2  setosa

Почему я получаю NaN вместо NA, когда он должен был быть средним остальными значениями (4.9, 4.7, 4.6, 5.0)?

Какова альтернатива для этого, если что-то не так с этим синтаксисом?

Я хочу синтаксис таблицы данных.

Ответы

Ответ 1

na.aggregate в пакете zoo заменяет NAs средним значением не-NA в одном столбце:

library(zoo)

ww[, Sepal.Length := na.aggregate(Sepal.Length)]

Ответ 2

В то время как ответ zoo довольно хорош, он требует новой зависимости.
Используя только data.table, вы можете сделать следующее.

library(data.table)

# prepare data
ww = data.table(iris[1:5,])
ww[1, Sepal.Length := NA]

# solution
ww[, Sepal.Length.mean := mean(Sepal.Length, na.rm = TRUE) # calculate mean
   ][is.na(Sepal.Length), Sepal.Length := Sepal.Length.mean # replace NA with mean
     ][, Sepal.Length.mean := NULL # remove mean col
       ][] # just prints

В то время как это может выглядеть как biggish по сравнению с зоопарком, он эффективен по эффективности, поскольку все шаги выполняются с использованием обновления по ссылке :=. Его также можно легко настроить, чтобы заменить NA средним по группе, просто используя аргумент by в таблице данных.

Ответ 3

В базе R:

ww$Sepal.Length[is.na(ww$Sepal.Length)] <- mean(ww$Sepal.Length, na.rm = T)

Ответ 4

Ваша попытка сначала подсекретировала таблицу, выбрав

> ww[is.na(Sepal.Length)]
   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1:   

    NA         3.5          1.4         0.2  setosa

поэтому любые дальнейшие операции могут "видеть" только эти строки, т.е. Sepal.Length могут видеть только один NA.

Решение data.table, которое вы хотите, ниже - оно просматривает всю таблицу и заменяет NA средствами с помощью ifelse.

ww[, Sepal.Length := ifelse(is.na(Sepal.Length), mean(Sepal.Length, na.rm = TRUE), Sepal.Length)]

Ответ 5

Он не принимает значение всего столбца Sepal.Length; только 1 столбец, который вы выбрали.

Скорее используйте:

ww[is.na(Sepal.Length) , Sepal.Length:= mean(ww$Sepal.Length, na.rm=TRUE)]

Ответ 6

tidyr имеет встроенную функцию replace_na, которую вы можете использовать для этого:

library(tidyr)
ww %>% replace_na(list(Sepal.Length = mean(.$Sepal.Length, na.rm = TRUE)))