将 NA 替换为 data.table 同一列的平均值

问题描述 投票:0回答:7

我想用同一列的平均值替换数据表列中存在的 NA。我正在做以下事情。但它不起作用。

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)的平均值?

如果此语法出现问题,实现此目的的替代方案是什么?

我想要数据表的语法。

r data.table
7个回答
21
投票
Zoo 包中的

na.aggregate
将 NA 替换为同一列中非 NA 的平均值:

library(zoo)

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

13
投票

虽然

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

虽然与动物园相比,它可能看起来更大,但它的性能效率很高,因为所有步骤都是使用通过引用更新

:=
进行的。 只需使用 data.table 中的
by
参数,也可以轻松调整以按组替换 NA 。


7
投票

您尝试首先对表进行子集化,选择

> 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)]

6
投票

在基础 R 中:

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

4
投票

它不是取整个 Sepal.Length 列的平均值;仅您选择的 1 列。

而是使用:

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

3
投票

tidyr
有一个内置功能,
replace_na
你可以使用这个:

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

0
投票

只需一行即可完成

fcoalesce
:

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

#>    Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#>           <num>       <num>        <num>       <num>  <fctr>
#> 1:          4.8         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
© www.soinside.com 2019 - 2024. All rights reserved.