R语言删除数据框指定列NA值 修复lm线性回归报错
问题背景
执行以下R代码做线性回归时,触发报错:
Error in lm.fit(x, y, offset = offset, singular.ok = singular.ok, ...) : NA/NaN/Inf dans 'y'
原始问题代码:
annee_N <- cbind(df_amb$A, df_amb$B, df_amb$C/df_amb$A, rep("2021", nrow(df_amb))) annee_N1 <- cbind(df_amb$A, df_amb$B, df_amb$C/df_amb$A, rep("2020", nrow(df_amb))) annee_N2 <- cbind(df_amb$A, df_amb$B, df_amb$C/df_amb$A, rep("2019", nrow(df_amb))) reg_spé_amb <- data.frame(rbind(annee_N, annee_N1, annee_N2)) colnames(reg_spé_amb) <- c("A", "B", "C", "année") lm_amb <- lm(reg_spé_amb[,3] ~ reg_spé_amb[,2] + reg_spé_amb[,1] + reg_spé_amb[,4])
输出的reg_spé_amb数据框结构示例:
A B C anes 10 500 2019 chir 11 600 2019 anes 9 450 2020
尝试用以下两种方法删除第三列NA值时,分别报colonnes non définies sélectionnées和can't subset columns that don't exist错误:
library(tidyr) reg_spé_amb %>% drop_na(reg_spé_amb[,3]) reg_spé_amb[!is.na(reg_spé_amb[,3])]
报错原因
- 核心数据构造错误:
cbind()拼接不同类型向量时会将所有列强制转换为统一的字符类型,后续转成data.frame后A/B/C三列都是字符型而非数值型,传入lm函数时会被解析为NA/NaN,触发拟合报错。 - 去值代码语法错误:
drop_na()需要传入裸列名或列位置,不能直接传入整列向量作为参数- data.frame行筛选时需要在方括号内逗号前写行筛选逻辑,原有筛选语句没有加逗号,实际是在做列筛选,因此触发列不存在的报错
- 额外风险点:计算
C = df_amb$C/df_amb$A时,如果df_amb$A存在0值,会生成Inf值,同样会触发lm.fit的报错。
修复步骤
- 重构数据框,避免cbind强制类型转换,直接按列构造data.frame:
# 分年度构造数据,直接指定列,避免类型被强制转换 annee_N <- data.frame( A = df_amb$A, B = df_amb$B, C = df_amb$C/df_amb$A, année = rep("2021", nrow(df_amb)) ) annee_N1 <- data.frame( A = df_amb$A, B = df_amb$B, C = df_amb$C/df_amb$A, année = rep("2020", nrow(df_amb)) ) annee_N2 <- data.frame( A = df_amb$A, B = df_amb$B, C = df_amb$C/df_amb$A, année = rep("2019", nrow(df_amb)) ) # 合并数据 reg_spé_amb <- rbind(annee_N, annee_N1, annee_N2) # 显式转换列类型,避免字符残留 reg_spé_amb$A <- as.numeric(reg_spé_amb$A) reg_spé_amb$B <- as.numeric(reg_spé_amb$B) reg_spé_amb$C <- as.numeric(reg_spé_amb$C) reg_spé_amb$année <- as.factor(reg_spé_amb$année)
- 正确过滤异常值,同时覆盖NA、NaN、Inf三类会触发拟合错误的值,二选一即可:
# 方法1:基础R语法行筛选,注意逗号位置 reg_spé_amb_clean <- reg_spé_amb[is.finite(reg_spé_amb$A) & is.finite(reg_spé_amb$B) & is.finite(reg_spé_amb$C), ] # 方法2:tidyverse系列函数正确写法 library(tidyr) library(dplyr) reg_spé_amb_clean <- reg_spé_amb %>% drop_na(A, B, C, année) %>% filter(is.finite(A), is.finite(B), is.finite(C))
- 运行线性回归,推荐直接在lm中指定data参数,用列名写公式,避免列索引引用出错:
lm_amb <- lm(C ~ B + A + année, data = reg_spé_amb_clean)
- 提示:如果
df_amb$A存在0值,建议在计算C列前先做过滤,避免生成无意义的Inf值。
内容的提问来源于stack exchange,提问作者user19304348
相关产品推荐
相关产品推荐

