用列均值替换缺失值

Nik*_*ita 40 r missing-data imputation

我不知道如何循环每列以用列均值替换NA值.当我尝试使用以下代码替换一列时,它运行良好.

Column1[is.na(Column1)] <- round(mean(Column1, na.rm = TRUE))
Run Code Online (Sandbox Code Playgroud)

循环列的代码不起作用:

for(i in 1:ncol(data)){
    data[i][is.na(data[i])] <- round(mean(data[i], na.rm = TRUE))
}
Run Code Online (Sandbox Code Playgroud)

值不会被替换.有人可以帮我这个吗?

Tho*_*mas 56

对代码进行相对简单的修改可以解决问题:

for(i in 1:ncol(data)){
  data[is.na(data[,i]), i] <- mean(data[,i], na.rm = TRUE)
}
Run Code Online (Sandbox Code Playgroud)

  • 那你应该问这个问题 (2认同)

G. *_*eck 45

如果DF是数字列的数据框:

library(zoo)
na.aggregate(DF)
Run Code Online (Sandbox Code Playgroud)

添加:

仅使用R的基数定义一个函数,该函数为一列执行,然后为每列提供lapply:

NA2mean <- function(x) replace(x, is.na(x), mean(x, na.rm = TRUE))
replace(DF, TRUE, lapply(DF, NA2mean))
Run Code Online (Sandbox Code Playgroud)

如果可以覆盖输入,则可以用以下代码替换最后一行:

DF[] <- lapply(DF, NA2mean)
Run Code Online (Sandbox Code Playgroud)


zac*_*ack 13

dplyrmutate_allmutate_at可能是有用的位置:

library(dplyr)                                                             

set.seed(10)                                                               
df <- data.frame(a = sample(c(NA, 1:3)    , replace = TRUE, 10),           
                 b = sample(c(NA, 101:103), replace = TRUE, 10),                            
                 c = sample(c(NA, 201:203), replace = TRUE, 10))                            

df         

#>     a   b   c
#> 1   2 102 203
#> 2   1 102 202
#> 3   1  NA 203
#> 4   2 102 201
#> 5  NA 101 201
#> 6  NA 101 202
#> 7   1  NA 203
#> 8   1 101  NA
#> 9   2 101 203
#> 10  1 103 201

df %>% mutate_all(~ifelse(is.na(.x), mean(.x, na.rm = TRUE), .x))          

#>        a       b        c
#> 1  2.000 102.000 203.0000
#> 2  1.000 102.000 202.0000
#> 3  1.000 101.625 203.0000
#> 4  2.000 102.000 201.0000
#> 5  1.375 101.000 201.0000
#> 6  1.375 101.000 202.0000
#> 7  1.000 101.625 203.0000
#> 8  1.000 101.000 202.1111
#> 9  2.000 101.000 203.0000
#> 10 1.000 103.000 201.0000

df %>% mutate_at(vars(a, b),~ifelse(is.na(.x), mean(.x, na.rm = TRUE), .x))

#>        a       b   c
#> 1  2.000 102.000 203
#> 2  1.000 102.000 202
#> 3  1.000 101.625 203
#> 4  2.000 102.000 201
#> 5  1.375 101.000 201
#> 6  1.375 101.000 202
#> 7  1.000 101.625 203
#> 8  1.000 101.000  NA
#> 9  2.000 101.000 203
#> 10 1.000 103.000 201
Run Code Online (Sandbox Code Playgroud)


A5C*_*2T1 11

要添加替代方案,使用@ akrun的示例数据,我会执行以下操作:

d1[] <- lapply(d1, function(x) { 
  x[is.na(x)] <- mean(x, na.rm = TRUE)
  x
})
d1
Run Code Online (Sandbox Code Playgroud)


sta*_*007 7

还有一个使用imputeTS软件包的快速解决方案:

library(imputeTS)
na_mean(yourDataFrame)
Run Code Online (Sandbox Code Playgroud)

  • 老实说,我认为这是最好的答案。知道另一个包中必须有一些函数来完成这项常见任务。 (2认同)

小智 7

使用tidyr 的 replace_na 的单行

library(tidyr)
replace_na(mtcars,as.list(colMeans(mtcars,na.rm=T)))
Run Code Online (Sandbox Code Playgroud)

如果您的df列是非数字列,则这比单行列需要更多的工作。

mean_to_fill <- select_if(ungroup(df), is.numeric) %>%
 colMeans(na.rm=T)

bind_cols(select(df, group1, group2, group3),
          select_if(ungroup(df), is.numeric) %>% 
            tidyr::replace_na(as.list(mean_to_fill))
          ) 
Run Code Online (Sandbox Code Playgroud)


akr*_*run 6

你也可以尝试:

 cM <- colMeans(d1, na.rm=TRUE)
 indx <- which(is.na(d1), arr.ind=TRUE)
 d1[indx] <- cM[indx[,2]]
 d1  
Run Code Online (Sandbox Code Playgroud)

数据

set.seed(42)
d1 <- as.data.frame(matrix(sample(c(NA,0:5), 5*10, replace=TRUE), ncol=10))
Run Code Online (Sandbox Code Playgroud)


Ist*_*sta 6

lapply可以代替for循环使用。

d1[] <- lapply(d1, function(x) ifelse(is.na(x), mean(x, na.rm = TRUE), x))
Run Code Online (Sandbox Code Playgroud)

与for循环相比,这实际上没有任何优势,尽管如果您也具有非数字列,则可能会更容易,在这种情况下

d1[sapply(d1, is.numeric)] <- lapply(d1[sapply(d1, is.numeric)], function(x) ifelse(is.na(x), mean(x, na.rm = TRUE), x))
Run Code Online (Sandbox Code Playgroud)

几乎一样容易。


par*_*ari 6

简单地使用 Zoo,它将简单地用列值的平均值替换所有 NA 值:

library(zoo)
na.aggregate(data) 
Run Code Online (Sandbox Code Playgroud)