用 'x[is.na(x)]=0' 将 NA 替换为 0 会替换整个数据框,而不仅仅是 NA?

Replace NA by 0 by 'x[is.na(x)]=0' replaces whole data frame, not just NAs?

我有点困惑。我的 列表中的数据帧 包含 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

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

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

这可以在带有包装器 replace 的单个语句中完成(它在内部进行赋值,return '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))