在R语言中为含数字与字符的列创建区间分类
R语言数据框新增列的代码优化方案
问题背景
现有如下数据框df:
df <- data.frame(a= 1:14, b= c(-1,-10,-2,0,0,2,1,4,10,12,6, "apple", "apple", "Orange"))
需要新增列c,规则为:
- 若
b是数值(正负或0),则分为<0、0、0-3、>3四类; - 若
b是字符,c直接取b的原值。
目标结果如下:
df2 a b c 1 1 -1 <0 2 2 -10 <0 3 3 -2 <0 4 4 0 0 5 5 0 0 6 6 2 0-3 7 7 1 0-3 8 8 4 >3 9 9 10 >3 10 10 12 >3 11 11 6 >3 12 12 apple apple 13 13 apple apple 14 14 Orange Orange
原尝试代码存在逻辑和语法问题,以下是优化建议:
原代码的问题
- 逻辑错误:
b %in% grepl("apple|orange", b)写法完全错误,grepl返回布尔向量,b是字符/混合类型,两者无法匹配; - 语法错误:
case_when的第一个条件后多了一个右括号,导致代码无法运行; - 局限性强:仅判断特定字符(apple/orange),如果后续出现其他字符值会失效;
- 极值不灵活:用
-999和999作为极值,可能遗漏超出范围的数值; - 类型不一致:
cut返回因子类型,和字符值混合会导致列c类型混乱。
优化后的代码
library(dplyr) df %>% mutate( c = case_when( # 识别无法转换为数值的行,直接返回原值 is.na(as.numeric(b)) ~ b, # 对数值型数据进行分组 TRUE ~ cut( as.numeric(b), breaks = c(-Inf, 0, 1, 4, Inf), labels = c("<0", "0", "0-3", ">3"), right = FALSE ) %>% as.character() ) )
优化说明
- 通用的数值判断:用
is.na(as.numeric(b))识别所有非数值型内容,不管是apple还是其他字符都能适配; - 全覆盖的区间:用
-Inf和Inf替代固定极值,确保任何数值都能被分到对应组; - 正确的区间规则:
right = FALSE设定左闭右开区间,完美匹配需求:(-Inf, 0)→<0[0, 1)→0[1, 4)→0-3[4, Inf)→>3
- 统一类型:将
cut返回的因子转为字符型,保证列c整体为字符类型,避免混合类型问题; - 代码可读性:调整缩进,让逻辑层级更清晰。
内容的提问来源于stack exchange,提问作者Mathica
相关产品推荐
相关产品推荐

