在R中使用case_when与%in%实现多列分组的频率值重编码
问题原因
你遇到的报错是因为c(labrador, beagle, corgi)会把3列3行的所有值拼接成长度为9的向量,和数据集3行的长度不匹配,所以mutate无法生成新列。你需要的是逐行判断指定分组的列中是否存在符合规则的值,tidyverse里的if_any()函数刚好适配这个需求。
解决方案代码
library(tidyverse) data <- tibble::tribble( ~labrador, ~beagle, ~corgi, ~pigeon, ~sparrow, ~robin, "Weekly", "Rarely", "Never", "Rarely", "Never", "Rarely", "Never", "Never", "Monthly", "Never", "Never", "Never", "Rarely", "Never", "Never", "Weekly", "Never", "Daily" ) # 定义分组,后续新增分组只要修改这个列表即可,扩展性强 group_list <- list( dogs = c("labrador", "beagle", "corgi"), birds = c("pigeon", "sparrow", "robin") ) # 批量生成分组列 result <- data %>% mutate( # 遍历分组列表生成对应列 !!!map(group_list, function(cols) { case_when( if_any(all_of(cols), ~.x %in% c("Daily", "Weekly", "Monthly")) ~ "Regularly", if_any(all_of(cols), ~.x == "Rarely") ~ "Rarely", if_any(all_of(cols), ~.x == "Never") ~ "Never" ) }) ) print(result)
运行结果与预期完全一致
| labrador | beagle | corgi | pigeon | sparrow | robin | dogs | birds |
|---|---|---|---|---|---|---|---|
| Weekly | Rarely | Never | Rarely | Never | Rarely | Regularly | Rarely |
| Never | Never | Monthly | Never | Never | Never | Regularly | Never |
| Rarely | Never | Never | Weekly | Never | Daily | Rarely | Regularly |
扩展性说明
如果后续新增更多分类和列,只需要修改group_list列表即可,不需要重复写mutate逻辑:
- 新增狗的品种,只要在
dogs对应的向量里添加对应列名 - 新增其他动物分组,只要在
group_list里加对应分组名和包含的列名即可
内容的提问来源于stack exchange,提问作者Matthew Law
相关产品推荐
相关产品推荐

