使用case_when/ifelse处理含NA条件的R语言变量赋值问题
基于多条件创建新变量的问题排查与解决
需求说明
创建新变量NewVariable,规则如下:
- 当同时满足
KY27SOC_NA_Total == 1、is.na(KY27SOC2),且KY27SOC_Total_Adjusted取3-15之间的特定值时,替换为对应指定数值 - 其余情况保留
OldVariableScores的原始数值
初始代码与报错
尝试的代码:
Baseline_Data_V2 <- Baseline_Data_V1 %>% mutate(NewVariable = case_when(KY27SOC_NA_Total == 1 & is.na(KY27SOC2) & KY27SOC_Total_Adjusted == 3 ~ -3.711, KY27SOC_NA_Total == 1 & is.na(KY27SOC2) & KY27SOC_Total_Adjusted == 4 ~ -2.474, KY27SOC_NA_Total == 1 & is.na(KY27SOC2) & KY27SOC_Total_Adjusted == 5 ~ -1.813, KY27SOC_NA_Total == 1 & is.na(KY27SOC2) & KY27SOC_Total_Adjusted == 6 ~ -1.312, KY27SOC_NA_Total == 1 & is.na(KY27SOC2) & KY27SOC_Total_Adjusted == 7 ~ -0.88, KY27SOC_NA_Total == 1 & is.na(KY27SOC2) & KY27SOC_Total_Adjusted == 8 ~ -0.476, KY27SOC_NA_Total == 1 & is.na(KY27SOC2) & KY27SOC_Total_Adjusted == 9 ~ -0.079, KY27SOC_NA_Total == 1 & is.na(KY27SOC2) & KY27SOC_Total_Adjusted == 10 ~ 0.327, KY27SOC_NA_Total == 1 & is.na(KY27SOC2) & KY27SOC_Total_Adjusted == 11 ~ 0.757, KY27SOC_NA_Total == 1 & is.na(KY27SOC2) & KY27SOC_Total_Adjusted == 12 ~ 1.227, KY27SOC_NA_Total == 1 & is.na(KY27SOC2) & KY27SOC_Total_Adjusted == 13 ~ 1.77, KY27SOC_NA_Total == 1 & is.na(KY27SOC2) & KY27SOC_Total_Adjusted == 14 ~ 2.475, KY27SOC_NA_Total == 1 & is.na(KY27SOC2) & KY27SOC_Total_Adjusted == 15 ~ 3.754, .default = OldVariableScores))
运行时出现两个问题:
- 报错:
could not find function "%>%" - 即使暂时跳过报错,生成的
NewVariable列全为NA
问题排查与解决
关于
%>%报错:
该运算符属于dplyr包(或tidyverse集合包),需要先加载对应包:library(dplyr) # 或加载整个tidyverse:library(tidyverse)关于新变量全为NA:
经排查是变量本身存在错误(比如变量名拼写错误、变量类型不匹配、KY27SOC_Total_Adjusted的取值不符合预期等),修正变量相关问题后,原代码可正常运行。
代码优化建议
原代码重复书写了相同的前置条件,冗余度较高。可以通过提取映射表+if_else+recode的方式简化代码,提升可读性和维护性:
library(dplyr) # 定义分数映射关系,便于后续修改 score_mapping <- c( "3" = -3.711, "4" = -2.474, "5" = -1.813, "6" = -1.312, "7" = -0.88, "8" = -0.476, "9" = -0.079, "10" = 0.327, "11" = 0.757, "12" = 1.227, "13" = 1.77, "14" = 2.475, "15" = 3.754 ) Baseline_Data_V2 <- Baseline_Data_V1 %>% mutate(NewVariable = if_else( # 共同触发条件 KY27SOC_NA_Total == 1 & is.na(KY27SOC2), # 匹配映射值,未匹配到则保留原分数 recode(as.character(KY27SOC_Total_Adjusted), !!!score_mapping, .default = OldVariableScores), # 不满足条件时直接保留原分数 OldVariableScores ))
内容的提问来源于stack exchange,提问作者Stats Iliterate
相关产品推荐
相关产品推荐

