R语言如何逐行基于其他列值为cut函数设置分箱断点
问题说明
给定如下参数与测试数据集:
Bins=10 df=data.frame(Min=c(0,10,20,30), Max=c(5,16,26,38),val=c(3,11,21,31))
需求为新增一列存储val列的分箱结果:逐行以该行Min、Max作为区间端点,将区间等分为10个等宽分箱,判定该行val值所属的分箱区间。
初始尝试代码如下,运行无法得到预期结果:
df$bin=cut(df$val, breaks = seq(from = df$Min, to =df$Max,length.out =Bins) ,include.lowest =TRUE)
原代码存在两个核心问题:
seq()传入向量作为from/to参数时,不会逐行生成独立的断点序列,只会生成不符合逐行分箱要求的全局断点,无法满足每行单独定义分箱区间的需求- n个等宽分箱需要n+1个断点,原代码设置
length.out = Bins,实际只能生成9个分箱,和要求的10个分箱数量不符
实现方案
基础R实现
通过apply()逐行遍历数据,每行单独生成分箱断点、判定所属分箱即可:
df$bin <- apply(df, 1, function(row) { breaks <- seq(row[["Min"]], row[["Max"]], length.out = Bins + 1) cut(row[["val"]], breaks = breaks, include.lowest = TRUE) })
Tidyverse实现
如果习惯使用dplyr语法,通过rowwise()标记按行执行运算,也可实现相同效果:
library(dplyr) df <- df %>% rowwise() %>% mutate(bin = cut(val, breaks = seq(Min, Max, length.out = Bins + 1), include.lowest = TRUE)) %>% ungroup()
以上代码运行后得到的分箱结果完全匹配逐行等宽分箱的要求,例如第一行区间[0,5]单箱宽度为0.5,val=3会落在(2.5,3]区间,和计算逻辑一致。
内容的提问来源于stack exchange,提问作者Camilo
相关产品推荐
相关产品推荐

