R语言将连续数值变量分组为类别的3种方法详解
在数据处理过程中,经常需要将连续的数值数据转换为类别数据,例如将成绩划分为优、良、中、及格和不及格。本文将介绍在R语言中使用直接索引赋值、within()函数以及cut()函数进行变量分组的三种方法,并详细解析cut函数的区间控制参数与常见误区。
准备数据
首先构建一个包含学生姓名和数学成绩的示例数据框:
# 定义数据框
mathScore <- data.frame(
name = c("刘文涛","王宇翔","田思雨","徐丽娜","丁文彬",
"李志国","王智强","宋丽芳","袁芳芳","张建国"),
math = c(85, 91, 74, 100, 82, 84, 78, 100, 51, 70)
)
head(mathScore)
接下来以90、80、70和60为界,将学生的数学成绩分为优、良、中、及格和不及格五类。
方法一:对变量直接进行赋值
通过逻辑索引对新生成的列进行逐个赋值。注意,attach()虽然方便访问列名,但容易引发命名冲突,操作完毕后需用 detach() 恢复环境。
# 方法一:直接对分组变量进行赋值
attach(mathScore)
mathScore$group1[math >= 90] = "优"
mathScore$group1[math >= 80 & math < 90] = "良"
mathScore$group1[math >= 70 & math < 80] = "中"
mathScore$group1[math >= 60 & math < 70] = "及格"
mathScore$group1[math < 60] = "不及格"
detach(mathScore)
head(mathScore)
方法二:使用 within 函数组织代码
within() 函数允许在一个数据框的作用域内执行多条表达式,无需挂载整个数据集,代码更整洁且避免了命名空间污染。注意初始化新变量(如赋值为NA),确保赋值语句块正确包裹。
# 方法二:使用 within 函数对变量进行分组
mathScore <- within(mathScore, {
group2 <- NA
group2[math >= 90] = "优"
group2[math >= 80 & math < 90] = "良"
group2[math >= 70 & math < 80] = "中"
group2[math >= 60 & math < 70] = "及格"
group2[math < 60] = "不及格"
})
head(mathScore)
方法三:采用 cut 函数
cut() 是处理分箱最常用且高效的函数。其核心在于正确设置断点(breaks)、标签(labels)及区间的开闭属性。
# 方法三:采用 cut 函数
# breaks 表示分界点,Inf表示无穷大; labels表示每个类别的名称
# right=FALSE 表示左闭右开区间,例如 良为 [80, 90)
mathScore$group3 <- cut(
mathScore$math,
breaks = c(-Inf, 60, 70, 80, 90, Inf),
labels = c("不及格","及格","中","良","优"),
right = FALSE
)
关于 cut 函数参数的关键说明:
breaks:用于指定分割点的向量。right:决定区间是左闭右开还是左开右闭。
-right=TRUE(默认):左开右闭区间 (a, b]。
-right=FALSE:左闭右开区间 [a, b)。include.lowest:当设置为 TRUE 时,强制包括最小值或最大值所在的端点,解决因区间开闭导致的边界遗漏问题。
处理实际边界的注意事项
在实际数据中,若未使用无穷大作为边界,或者遇到极值恰好落在区间断点上,必须结合 include.lowest 使用,否则超出范围的值会变为 NA。
为了演示,向数据中添加极端值:
# 重新定义一下数据框
mathScore_test <- data.frame(
name = c("刘文涛","王宇翔","田思雨","徐丽娜","丁文彬",
"李志国","王智强","宋丽芳","袁芳芳","张建国","张志伟","李明"),
math = c(85, 91, 74, 100, 82, 84, 78, 100, 51, 70, 0, NA)
)
head(mathScore_test)
如果直接将断点设为实际范围而不加控制:
# 潜在的问题代码示例
mathScore_test$group_bad <- cut(
mathScore_test$math,
breaks = c(0, 60, 70, 80, 90, 100),
labels = c("不及格","及格","中","良","优"),
right = FALSE
)
mathScore_test
在上述 right=FALSE(左闭右开 [0, 60), [60, 70)... [90, 100))的情况下,分数为100的学生被划到了组外(显示为 NA),因为100不包含在最后一个区间内。同样,0分会进入不及格组,但如果区间设定有变也可能出现遗漏。
修复后的正确写法:
# 加上 include.lowest = TRUE 修正边界问题
mathScore_test$group_correct <- cut(
mathScore_test$math,
breaks = c(0, 60, 70, 80, 90, 100),
labels = c("不及格","及格","中","良","优"),
right = FALSE,
include.lowest = TRUE # 确保最大值等边界值能正确归入组别
)
mathScore_test
此时可以看到100分成功归类为“优”。
参数组合逻辑总结
| right 参数 | include.lowest 参数 | 效果备注 |
|---|---|---|
| FALSE | TRUE | 左闭右开,且强制包括最大值的右侧端点 |
| TRUE | TRUE | 左开右闭,且强制包括最小值的左侧端点 |
| TRUE | FALSE | 左开右闭,不包括两端极限值 |
| FALSE | FALSE | 左闭右开,不包括两端极限值 |
通常建议在R语言中设置 right=FALSE 且 include.lowest=TRUE,这样可以实现按“含下限不含上限”的逻辑分箱,同时保证数据的最大值不会被遗漏。
总结
以上是关于R语言中将连续数值变量分为不同类别的3种方法的详细内容,更多关于R语言变量分组切割的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













