如何在R数据框中将NA值替换为零?

961

我有一个数据框,其中一些列具有NA值。

我该如何用零替换这些NA值?


16
对 https://dev59.com/SGw05IYBdhLWcg3wXQwh 进行了小修改(我是通过搜索“[r] replace NA with zero”找到的)。 - Ben Bolker
@psychonomics,你的评论和最佳答案有什么区别? - user2110417
1
@svp - 可能什么都没有?我看不到我的评论。我是否已经删除了它,而你仍然可以查看? - psychonomics
30个回答

3

这个简单的函数从Datacamp中提取出来,可以帮助:

replace_missings <- function(x, replacement) {
  is_miss <- is.na(x)
  x[is_miss] <- replacement

  message(sum(is_miss), " missings replaced by the value ", replacement)
  x
}

那么

replace_missings(df, replacement = 0)

2

替换数据框中的is.na和NULL。

  1. 具有列的数据框

A $ name [is.na(A $ name)] <- 0

A $ name [is.na(A $ name)] <- "NA"

  1. 对于整个数据框

df [is.na(df)] <- 0

  1. 替换数据框中的na为空白

df [is.na(df)] <-“”

  1. 将NULL替换为NA

df [is.null(df)] <- NA


1
另一个选择是使用 collapse::replace_NA。默认情况下,replace_NA 会用0替换 NAs。
library(collapse)
replace_NA(df)

只针对某些列:

replace_NA(df, cols = c("V1", "V5")) 
#Alternatively, one can use a function, indices or a logical vector to select the columns

它也比其他任何答案都要快(请参见此答案进行比较):

set.seed(42) # to recreate the exact dataframe
dfN <- as.data.frame(matrix(sample(c(NA, as.numeric(1:4)), 1e7*10, replace = TRUE),
                            dimnames = list(NULL, paste0("var", 1:10)), 
                            ncol = 10))

microbenchmark(collapse = replace_NA(dfN))

# Unit: milliseconds
#      expr      min      lq     mean  median       uq     max neval
#  collapse 508.9198 621.405 751.3413 714.835 859.5437 1298.69   100

0

我想添加一个新的解决方案,使用一个流行的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* 

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


0

另一种选项是使用sapply将所有的NA替换为零。以下是一些可重现的代码(数据来自@aL3xa):

set.seed(7) # for reproducibility
m <- matrix(sample(c(NA, 1:10), 100, replace = TRUE), 10)
d <- as.data.frame(m)
d
#>    V1 V2 V3 V4 V5 V6 V7 V8 V9 V10
#> 1   9  7  5  5  7  7  4  6  6   7
#> 2   2  5 10  7  8  9  8  8  1   8
#> 3   6  7  4 10  4  9  6  8 NA  10
#> 4   1 10  3  7  5  7  7  7 NA   8
#> 5   9  9 10 NA  7 10  1  5 NA   5
#> 6   5  2  5 10  8  1  1  5 10   3
#> 7   7  3  9  3  1  6  7  3  1  10
#> 8   7  7  6  8  4  4  5 NA  8   7
#> 9   2  1  1  2  7  5  9 10  9   3
#> 10  7  5  3  4  9  2  7  6 NA   5
d[sapply(d, \(x) is.na(x))] <- 0
d
#>    V1 V2 V3 V4 V5 V6 V7 V8 V9 V10
#> 1   9  7  5  5  7  7  4  6  6   7
#> 2   2  5 10  7  8  9  8  8  1   8
#> 3   6  7  4 10  4  9  6  8  0  10
#> 4   1 10  3  7  5  7  7  7  0   8
#> 5   9  9 10  0  7 10  1  5  0   5
#> 6   5  2  5 10  8  1  1  5 10   3
#> 7   7  3  9  3  1  6  7  3  1  10
#> 8   7  7  6  8  4  4  5  0  8   7
#> 9   2  1  1  2  7  5  9 10  9   3
#> 10  7  5  3  4  9  2  7  6  0   5

2023年1月15日创建,使用reprex v2.0.2生成。


请注意:自 R 4.1.0 起,您可以使用 \(x) 替代 function(x)

0

这并不是一个全新的解决方案,但我喜欢编写内联lambda函数来处理那些我无法通过包来完成的事情。在这种情况下,

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

因为 R 不像 Python 一样“按对象传递”,所以这个解决方案不会修改原始变量 df,因此与大多数其他解决方案相比,需要的特定包的复杂知识要少得多。

请注意函数定义周围的括号!虽然对我来说似乎有点多余,因为函数定义被花括号包围,但是内联函数必须在括号中定义,以便使用 magrittr


0

这是一种更灵活的解决方案。它适用于您的数据框有多大,或者使用0zero或任何其他表示零的方式。

library(dplyr) # make sure dplyr ver is >= 1.00

df %>%
    mutate(across(everything(), na_if, 0)) # if 0 is indicated by `zero` then replace `0` with `zero`

0
如果您想在更改特定列(在此情况下为V3列)中的NAs后分配新名称,则可以像这样操作。
my.data.frame$the.new.column.name <- ifelse(is.na(my.data.frame$V3),0,1)

-1

我个人使用过,效果很好:

players_wd$APPROVED_WD[is.na(players_wd$APPROVED_WD)] <- 0

2
你的回答可以通过添加更多关于代码的信息以及它如何帮助提问者来改进。 - Tyler2P

-1

在 data.frame 中,不需要通过 mutate 创建新列。

library(tidyverse)    
k <- c(1,2,80,NA,NA,51)
j <- c(NA,NA,3,31,12,NA)
        
df <- data.frame(k,j)%>%
   replace_na(list(j=0))#convert only column j, for example
    

结果

k   j
1   0           
2   0           
80  3           
NA  31          
NA  12          
51  0   

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接