使用lapply替换列表中数据框的NA为0时,为何仅返回全0值?
如何将列表中数据框的NA值替换为0?
你的问题出在匿名函数的返回值上:R中赋值语句x[is.na(x)] = 0的返回值是被赋予的0,而不是修改后的整个数据框。所以lapply会把每个函数执行后的返回值(也就是那个单个的0)收集起来,最终得到全是0的列表。
要解决这个问题,只需要在函数里完成赋值后,明确返回修改后的整个数据框即可,下面是两种常用的实现方法:
方法1:基础R原生实现
在匿名函数中先完成NA替换的赋值操作,再返回修改后的完整数据框:
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) # 正确的NA替换写法 l2 <- lapply(l, function(x) { x[is.na(x)] <- 0 # 完成NA替换赋值 x # 一定要返回修改后的完整数据框 }) # 查看最终结果 l2
执行后就能得到你期望的输出:
[[1]] class a 1 BO 0 2 BO 2 3 BO 3 [[2]] class a 1 BS 5 2 BS 0 3 BS 7
方法2:tidyverse风格实现(更严谨)
如果日常使用tidyverse工具链,可以针对性地只替换数值型列的NA(避免误修改字符型列的风险):
library(dplyr) l2 <- lapply(l, function(x) { x %>% mutate(across(where(is.numeric), ~replace_na(., 0))) })
这个方法会自动识别数据框中的数值型列,仅将这些列里的NA替换为0,字符型列(比如你的class列)会保持原样,适合结构更复杂的场景。
内容的提问来源于stack exchange,提问作者maycca
相关产品推荐
相关产品推荐

