首页 > 解决方案 > 用 'x[is.na(x)]=0' 将 NA 替换为 0 会替换整个数据帧,而不仅仅是 NA?

问题描述

我有点困惑。我在列表中的数据框 包含 NA 值,我想将其替换为 0。在单个数据帧上,我可以通过 轻松实现这一点df[is.na(df)]=0,并且在应用于单个 data.frame 时效果很好。但是,当应用于列表 ( lapply(l, function(x) x[is.na(x)]=0)) 时,这会生成仅包含 0 的数据帧


虚拟数据:

df1<-data.frame(class = rep("BO", 3),
                a = c(NA,2,3))
df2<-data.frame(class = rep("BS", 3),
                a = c(5,NA,7))

l<-list(df1, df2)

# Convert NA to 0
l2<-lapply(l, function(x) x[is.na(x)]=0)

结果是:

[[1]]
[1] 0

[[2]]
[1] 0

但我怎么能得到这个?

[[1]]
  class  a
1    BO  0
2    BO  2
3    BO  3

[[2]]
  class  a
1    BS  5
2    BS  0
3    BS  7

标签: rna

解决方案


我们需要返回'x'。在这里,我们只返回赋值 0。数据集x来自 lambda 函数调用

lapply(l, function(x) {x[is.na(x)] <- 0
                       x})

这可以在带有包装器的单个语句中完成replace(它在内部进行分配并返回'x'

lapply(l, function(x) replace(x, is.na(x), 0))

replace在哪里

function (x, list, values) {
   x[list] <- values
   x
 }

除了base R, 选项,我们也可以这样tidyverse

library(tidyverse)
map(l, ~ .x %>%
            mutate_all(replace_na, 0))

由于我们仅将数字列缺失值替换为 0,因此我们可以使用mutate_if

map(l, ~ .x %>%
            mutate_if(is.numeric, replace_na, 0))

推荐阅读