Ответ 1
na.aggregate
в пакете zoo заменяет NAs средним значением не-NA в одном столбце:
library(zoo)
ww[, Sepal.Length := na.aggregate(Sepal.Length)]
Я хочу заменить 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)?
Какова альтернатива для этого, если что-то не так с этим синтаксисом?
Я хочу синтаксис таблицы данных.
na.aggregate
в пакете zoo заменяет NAs средним значением не-NA в одном столбце:
library(zoo)
ww[, Sepal.Length := na.aggregate(Sepal.Length)]
В то время как ответ 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
в таблице данных.
В базе R:
ww$Sepal.Length[is.na(ww$Sepal.Length)] <- mean(ww$Sepal.Length, na.rm = T)
Ваша попытка сначала подсекретировала таблицу, выбрав
> 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)]
Он не принимает значение всего столбца Sepal.Length; только 1 столбец, который вы выбрали.
Скорее используйте:
ww[is.na(Sepal.Length) , Sepal.Length:= mean(ww$Sepal.Length, na.rm=TRUE)]
tidyr
имеет встроенную функцию replace_na
, которую вы можете использовать для этого:
library(tidyr)
ww %>% replace_na(list(Sepal.Length = mean(.$Sepal.Length, na.rm = TRUE)))