如何在R语言的case_when()中嵌套for循环实现分箱编号?
问题
我通过ggplot_build()获取了数据框df的直方图分箱的xmin和xmax,对应的分箱数据框名为his_bin。现在想给df新增bin_number列标记分箱编号,尝试用case_when()但不知道怎么嵌套for循环实现,我的代码示例如下:
df <- df %>% mutate(bin_number = case_when( df$column_a > his_bin$xmin[i] & df$column_a < his_bin$xmax[i] ~ i ) )
解决方案
case_when()本身不支持直接嵌套for循环,它是基于向量化逻辑做条件判断的,循环写法不符合其语法。推荐两种更高效的实现方式:
方法1:用purrr遍历匹配分箱
借助purrr::map_int()遍历column_a的每个值,找到对应的分箱编号:
library(dplyr) library(purrr) df <- df %>% mutate(bin_number = map_int(column_a, ~{ # 找到当前值所属的分箱索引 match_idx <- which(.x >= his_bin$xmin & .x <= his_bin$xmax) # 处理无匹配的情况(返回NA) if (length(match_idx) == 0) NA_integer_ else match_idx }))
说明:
- 调整判断条件为
>=和<=,避免值刚好等于xmin或xmax时无匹配 - 如果你的分箱是左开右闭/其他规则,对应修改比较符号即可
方法2:用cut()快速生成分箱编号
利用cut()函数直接基于his_bin的分箱边界生成编号,效率更高:
library(dplyr) df <- df %>% mutate(bin_number = cut(column_a, breaks = c(min(his_bin$xmin), his_bin$xmax), labels = FALSE, include.lowest = TRUE))
说明:
breaks参数传入分箱的左边界最小值和所有右边界,确保覆盖所有分箱范围labels = FALSE直接返回分箱的整数编号,无需额外转换include.lowest = TRUE保证最左侧分箱包含最小的xmin值
注意事项
- 确保
his_bin中的分箱是连续且无重叠的,否则会出现一个值匹配多个分箱或无匹配的异常情况 - 如果有值落在所有分箱之外,两种方法都会返回
NA,可根据需求用replace_na()设置默认值(比如0)
内容的提问来源于stack exchange,提问作者pinawa
相关产品推荐
相关产品推荐

