R语言中如何对单列数值编码分类生成新变量并解决if语句警告
报错原因
你触发的警告本质是R语言逻辑判断机制导致的:
基础if()函数仅能接收长度为1的单个逻辑值作为判断条件,但你传入的my_data$new_icccmain < 20是和数据框行数等长的逻辑向量(每一行对应一个独立的TRUE/FALSE结果)。此时R只会提取向量的第一个元素做判断,再把判断得到的赋值统一赋给所有行,最终生成的新列所有取值都会和第一行的判断结果一致,完全不符合分档预期。
另外你原有的判断逻辑存在边界疏漏:比如将IV组的判断上限设为49、V组仅判断==50的情况,会导致41-49、50-60区间的大量编码漏判,全部被归入最后的XII组。
可行实现方案
所有方案都修正了原有逻辑的边界问题,覆盖11-122的全部编码范围,不会触发长度相关的警告。
方案1:用向量化基础函数ifelse()
不需要安装额外包,直接逐行完成嵌套判断:
my_data$maindiagnosticgr <- ifelse( my_data$new_icccmain >= 11 & my_data$new_icccmain <= 20, "I", ifelse(my_data$new_icccmain >= 21 & my_data$new_icccmain <= 30, "II", ifelse(my_data$new_icccmain >= 31 & my_data$new_icccmain <= 40, "III", ifelse(my_data$new_icccmain >= 41 & my_data$new_icccmain <= 50, "IV", ifelse(my_data$new_icccmain >= 51 & my_data$new_icccmain <= 60, "V", ifelse(my_data$new_icccmain >= 61 & my_data$new_icccmain <= 70, "VI", ifelse(my_data$new_icccmain >= 71 & my_data$new_icccmain <= 80, "VII", ifelse(my_data$new_icccmain >= 81 & my_data$new_icccmain <= 90, "VIII", ifelse(my_data$new_icccmain >= 91 & my_data$new_icccmain <= 100, "IX", ifelse(my_data$new_icccmain >= 101 & my_data$new_icccmain <= 110, "X", ifelse(my_data$new_icccmain >= 111 & my_data$new_icccmain <= 120, "XI", "XII"))))))))))
方案2:用内置分箱函数cut()
由于你的分组是固定每10个编码为一档,属于等距分箱,不需要写嵌套判断,代码更简洁:
# 定义分箱断点和对应罗马组别标签 break_points <- c(10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 122) group_labels <- c("I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X", "XI", "XII") my_data$maindiagnosticgr <- cut( x = my_data$new_icccmain, breaks = break_points, labels = group_labels, include.lowest = TRUE # 开启区间闭合计数,避免边界值漏判 )
后续如果需要调整分组范围,只需要修改断点和标签向量即可,不需要调整核心逻辑。
方案3:用dplyr的case_when()处理
如果习惯用整洁数据处理流程,这个写法可读性最高,不会出现嵌套判断数错括号的问题:
# 先加载dplyr包,未安装的话需要先运行install.packages("dplyr") library(dplyr) my_data <- my_data %>% mutate( maindiagnosticgr = case_when( new_icccmain >= 11 & new_icccmain <= 20 ~ "I", new_icccmain >= 21 & new_icccmain <= 30 ~ "II", new_icccmain >= 31 & new_icccmain <= 40 ~ "III", new_icccmain >= 41 & new_icccmain <= 50 ~ "IV", new_icccmain >= 51 & new_icccmain <= 60 ~ "V", new_icccmain >= 61 & new_icccmain <= 70 ~ "VI", new_icccmain >= 71 & new_icccmain <= 80 ~ "VII", new_icccmain >= 81 & new_icccmain <= 90 ~ "VIII", new_icccmain >= 91 & new_icccmain <= 100 ~ "IX", new_icccmain >= 101 & new_icccmain <= 110 ~ "X", new_icccmain >= 111 & new_icccmain <= 120 ~ "XI", TRUE ~ "XII" # 剩余的121-122编码自动归入XII组 ) )
内容的提问来源于stack exchange,提问作者Margrietha
相关产品推荐
相关产品推荐

