我有一个数据帧和一些列有NA值。

我如何将这些NA值替换为零?


当前回答

我想添加一个使用流行的Hmisc包的下一个解决方案。

library(Hmisc)
data(airquality)
# imputing with 0 - all columns
# although my favorite one for simple imputations is Hmisc::impute(x, "random")
> dd <- data.frame(Map(function(x) Hmisc::impute(x, 0), airquality))
> str(dd[[1]])
 'impute' Named num [1:153] 41 36 12 18 0 28 23 19 8 0 ...
 - attr(*, "names")= chr [1:153] "1" "2" "3" "4" ...
 - attr(*, "imputed")= int [1:37] 5 10 25 26 27 32 33 34 35 36 ...
> dd[[1]][1:10]
  1   2   3   4   5   6   7   8   9  10 
 41  36  12  18  0*  28  23  19   8  0* 

可以看到,所有的imputation元数据都被分配为属性。因此它可以在以后使用。

其他回答

DPLYR >= 1.0.0

在dplyr的新版本中:

Across()取代了一系列“作用域变量”,如summarise_at()、summarise_if()和summarise_all()。

df <- data.frame(a = c(LETTERS[1:3], NA), b = c(NA, 1:3))

library(tidyverse)

df %>% 
  mutate(across(where(anyNA), ~ replace_na(., 0)))

  a b
1 A 0
2 B 1
3 C 2
4 0 3

这段代码将强制0为第一列中的字符。要根据列类型替换NA,您可以使用类似呜呜声的公式,其中:

df %>% 
  mutate(across(where(~ anyNA(.) & is.character(.)), ~ replace_na(., "0")))

另一个与tidyrmethod replace_na兼容的dplyr管道选项,适用于多个列:

require(dplyr)
require(tidyr)

m <- matrix(sample(c(NA, 1:10), 100, replace = TRUE), 10)
d <- as.data.frame(m)

myList <- setNames(lapply(vector("list", ncol(d)), function(x) x <- 0), names(d))

df <- d %>% replace_na(myList)

你可以很容易地限制到例如数字列:

d$str <- c("string", NA)

myList <- myList[sapply(d, is.numeric)]

df <- d %>% replace_na(myList)

dplyr例子:

library(dplyr)

df1 <- df1 %>%
    mutate(myCol1 = if_else(is.na(myCol1), 0, myCol1))

注意:这适用于每个选定的列,如果我们需要对所有列都这样做,请参阅@reidjax的答案使用mutate_each。

这并不是一个新的解决方案,但是我喜欢编写内联lambdas来处理我无法让包完成的事情。在这种情况下,

df %>%
   (function(x) { x[is.na(x)] <- 0; return(x) })

因为R不像你在Python中可能看到的那样“通过对象传递”,所以这个解决方案不会修改原始变量df,因此与大多数其他解决方案一样,但是不需要对特定包的复杂知识有太多的要求。

注意函数定义周围的括号!虽然对我来说这似乎有点多余,因为函数定义是用花括号括起来的,但对于magrittr,需要在括号内定义内联函数。

一个简单的方法是用if_na from hablar:

library(dplyr)
library(hablar)

df <- tibble(a = c(1, 2, 3, NA, 5, 6, 8))

df %>% 
  mutate(a = if_na(a, 0))

返回:

      a
  <dbl>
1     1
2     2
3     3
4     0
5     5
6     6
7     8