如何按特定条件提取字符串,并用dplyr实现数据集字符串替换与分组
Hey Chloe, let's break down your two questions step by step using dplyr and stringr (a package that pairs perfectly with dplyr for string manipulation):
1. 按特定条件提取字符串
假设你的数据集有一列类似offense_type,包含值如NARC-SELL、NARC-POSSES、FRAUD(甚至带毒品种类的变体,比如NARC-SELL-HEROIN),我们可以用正则表达式精准提取需要的部分:
提取主类别(如NARC、FRAUD)
如果你想把每个记录归类到顶级类别:
# 先加载必要的包 library(dplyr) library(stringr) # 提取开头的大写字母前缀(NARC/FRAUD) df <- df %>% mutate(offense_category = str_extract(offense_type, "^[A-Z]+"))
^[A-Z]+是正则表达式,匹配字符串开头的所有大写字母,刚好能提取出NARC或FRAUD这类主类别。
提取具体行为(如SELL、POSSES)
如果需要提取-后面的行为类型(忽略毒品种类):
df <- df %>% mutate(offense_action = str_extract(offense_type, "(?<=-)[A-Z]+"))
(?<=-)是正向预查,意思是“匹配紧跟在-后面的内容”,[A-Z]+则提取后续的大写字母,这样就能得到SELL或POSSES,自动跳过后面的毒品种类后缀。
2. 按不同条件替换字符串并分组
你提到要区分NARC-SELL和NARC-POSSES但忽略毒品种类,同时保留FRAUD的独立性,之后用dplyr分组统计。这里分两步:先清洗字符串,再分组。
第一步:按条件替换/清洗字符串
我们可以用case_when(适合多条件分支)或者str_replace(适合正则批量替换)来统一格式:
方法1:用case_when明确分支
df <- df %>% mutate(cleaned_offense = case_when( # 匹配所有包含NARC-SELL的记录,统一替换为NARC-SELL str_detect(offense_type, "NARC-SELL") ~ "NARC-SELL", # 匹配所有包含NARC-POSSES的记录,统一替换为NARC-POSSES str_detect(offense_type, "NARC-POSSES") ~ "NARC-POSSES", # 所有FRAUD相关记录统一为FRAUD str_detect(offense_type, "FRAUD") ~ "FRAUD", # 其他类型保持原样(可选) TRUE ~ offense_type ))
方法2:用str_replace批量替换更简洁
如果你的offense_type格式都是类别-行为-毒品种类,可以用正则一次性去掉毒品种类后缀:
df <- df %>% mutate(cleaned_offense = str_replace(offense_type, "(NARC-(SELL|POSSES))-.+", "\\1"))
这个正则的意思是:匹配NARC-SELL或NARC-POSSES后面的所有内容,然后替换成前面捕获的分组\\1(也就是保留NARC-SELL/NARC-POSSES),自动忽略后面的毒品种类。
第二步:用dplyr分组统计
清洗完字符串后,就可以按处理后的cleaned_offense分组,做你需要的统计(比如计数、平均值等):
# 分组并计算每个类别的记录数和平均刑期(假设你有sentence_length列) offense_summary <- df %>% group_by(cleaned_offense) %>% summarise( total_cases = n(), average_sentence = mean(sentence_length, na.rm = TRUE) )
内容的提问来源于stack exchange,提问作者Chloe

