用 data.table 的同一列的平均值替换 NA
Replace NAs with mean of the same column of a data.table
我想用同一列的平均值替换 DATA TABLE 列中的 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
当 NA 应该是其余值(4.9、4.7、4.6、5.0)的平均值时,为什么我用 NaN 代替 NA?
如果此语法有问题,有什么替代方法可以实现此目的?
我想要数据的语法 table。
它没有取整个 Sepal.Length 列的平均值;只有您选择的第 1 列。
而是使用:
ww[is.na(Sepal.Length) , Sepal.Length:= mean(ww$Sepal.Length, na.rm=TRUE)]
在基数 R 中:
ww$Sepal.Length[is.na(ww$Sepal.Length)] <- mean(ww$Sepal.Length, na.rm = T)
您尝试首先对 table 进行子集化,选择
> ww[is.na(Sepal.Length)]
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1:
NA 3.5 1.4 0.2 setosa
所以任何进一步的操作只能 'see' 这些行 - 即 Sepal.Length
只能看到一个 NA
.
您想要的 data.table
解决方案如下 - 它查看整个 table 并使用 ifelse
.[=17 的方法替换 NA
s =]
ww[, Sepal.Length := ifelse(is.na(Sepal.Length), mean(Sepal.Length, na.rm = TRUE), Sepal.Length)]
na.aggregate
在 zoo 包中将 NAs 替换为同一列中非 NAs 的平均值:
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
虽然它与动物园的相比可能看起来更大,但它的性能是高效的,因为所有步骤都是使用 通过引用更新 :=
进行的。
它也可以很容易地调整为按组用均值替换 NA,只需使用 data.table 中的 by
参数。
tidyr
有一个内置函数,replace_na
你可以使用它:
library(tidyr)
ww %>% replace_na(list(Sepal.Length = mean(.$Sepal.Length, na.rm = TRUE)))
我想用同一列的平均值替换 DATA TABLE 列中的 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
当 NA 应该是其余值(4.9、4.7、4.6、5.0)的平均值时,为什么我用 NaN 代替 NA?
如果此语法有问题,有什么替代方法可以实现此目的?
我想要数据的语法 table。
它没有取整个 Sepal.Length 列的平均值;只有您选择的第 1 列。
而是使用:
ww[is.na(Sepal.Length) , Sepal.Length:= mean(ww$Sepal.Length, na.rm=TRUE)]
在基数 R 中:
ww$Sepal.Length[is.na(ww$Sepal.Length)] <- mean(ww$Sepal.Length, na.rm = T)
您尝试首先对 table 进行子集化,选择
> ww[is.na(Sepal.Length)]
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1:
NA 3.5 1.4 0.2 setosa
所以任何进一步的操作只能 'see' 这些行 - 即 Sepal.Length
只能看到一个 NA
.
您想要的 data.table
解决方案如下 - 它查看整个 table 并使用 ifelse
.[=17 的方法替换 NA
s =]
ww[, Sepal.Length := ifelse(is.na(Sepal.Length), mean(Sepal.Length, na.rm = TRUE), Sepal.Length)]
na.aggregate
在 zoo 包中将 NAs 替换为同一列中非 NAs 的平均值:
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
虽然它与动物园的相比可能看起来更大,但它的性能是高效的,因为所有步骤都是使用 通过引用更新 :=
进行的。
它也可以很容易地调整为按组用均值替换 NA,只需使用 data.table 中的 by
参数。
tidyr
有一个内置函数,replace_na
你可以使用它:
library(tidyr)
ww %>% replace_na(list(Sepal.Length = mean(.$Sepal.Length, na.rm = TRUE)))