如何将80个水平的因子变量合并为8个水平(R语言)
多分类因子变量合并解决方案
嘿,刚好能帮你搞定这个把80个水平合并成8类的问题!之前用ifelse+grepl做二分类确实好用,但多分类的话,用dplyr里的case_when会更清晰、更易维护——它能按顺序定义多个匹配规则,完美适配你的8类需求。
核心思路
- 先列出
Weapon.Description的所有水平,明确每类要包含的关键词 - 用
case_when按优先级顺序设置匹配规则(注意:先匹配更具体的类别,避免被宽泛的规则覆盖) - 最后用
TRUE ~ "兜底类别"确保所有水平都能被分类
具体代码示例
我结合你提到的"AIR PISTOL/REVOLVER/RIFLE/BB GU..."这类水平,给你写一个可直接调整的模板:
# 先加载需要的包(如果没装的话先运行 install.packages(c("dplyr", "stringr"))) library(dplyr) library(stringr) # 先查看所有80个水平,方便你梳理分类规则 levels(crime_3yr$Weapon.Description) # 开始合并分类,你可以根据自己的8类需求修改每个规则的关键词和类别名 crime_3yr$Weapon.Category <- case_when( # 第1类:气动/BB枪类(匹配你提到的AIR/BB开头的水平) str_detect(crime_3yr$Weapon.Description, "AIR|BB|PELLET") ~ "Air/Pellet Weapons", # 第2类:各类枪械(手枪、步枪等) str_detect(crime_3yr$Weapon.Description, "GUN|PISTOL|RIFLE|REVOLVER|HANDGUN") ~ "Firearms", # 第3类:锋利近战武器(斧头、刀具等) str_detect(crime_3yr$Weapon.Description, "AXE|KNIFE|BLADE|SWORD") ~ "Sharp Melee", # 第4类:钝器(棍棒、锤子等) str_detect(crime_3yr$Weapon.Description, "BAT|CLUB|HAMMER|STICK") ~ "Blunt Melee", # 第5类:爆炸物 str_detect(crime_3yr$Weapon.Description, "BOMB|EXPLOSIVE|GRENADE") ~ "Explosives", # 第6类:非致命约束器械(电击器、辣椒水等) str_detect(crime_3yr$Weapon.Description, "TASER|PEPPER|STUN") ~ "Non-Lethal Restraints", # 第7类:特殊武器(车辆、纵火工具等) str_detect(crime_3yr$Weapon.Description, "VEHICLE|FIRE|ARSON") ~ "Special Weapons", # 第8类:兜底,所有未匹配的归为其他 TRUE ~ "Other/Unknown" ) # 检查分类结果,看看每个类别的数量 table(crime_3yr$Weapon.Category)
关键注意事项
- 优先级顺序:比如"AIR PISTOL"同时包含"AIR"和"PISTOL",所以必须把气动类的规则放在枪械类前面,否则会被错误归为Firearms
- 灵活调整关键词:你可以根据自己的8类划分标准,修改每个
str_detect里的匹配关键词,比如如果某类需要包含"BRASS KNUCKLES",就加在对应规则的pattern里 - 不用tidyverse的替代方案:如果不想加载dplyr,也可以用嵌套
ifelse,但可读性会差很多,示例如下:
crime_3yr$Weapon.Category <- ifelse(str_detect(crime_3yr$Weapon.Description, "AIR|BB|PELLET"), "Air/Pellet Weapons", ifelse(str_detect(crime_3yr$Weapon.Description, "GUN|PISTOL|RIFLE"), "Firearms", ifelse(str_detect(crime_3yr$Weapon.Description, "AXE|KNIFE"), "Sharp Melee", # 继续添加剩余5类的ifelse规则 "Other/Unknown")))
内容的提问来源于stack exchange,提问作者Prashanth Cp
相关产品推荐
相关产品推荐

