You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在R中用str_detect按相似字符串分组并生成组ID

基于字符串特征生成组编号的解决方案

原始数据

library(tidyverse)

dt <- tibble(Poison = c('Arsenic', 'Arsenic in Wine', 'Cyanide', 'Cyanide and Sugar'),
             Result = c('Death', 'Death With Class', 'Death', 'Death'))

需求说明

需要新增Group列,将包含Arsenic的条目归为组1,包含Cyanide的条目归为组2,而非按Poison字段的完整字符串独立分组。

错误的尝试及结果

直接按Poison分组会将每个不同字符串视为独立组,导致所有Group值均为1:

dt <- dt %>%
  group_by(Poison) %>%
  mutate(Group = n())

结果:

# A tibble: 4 × 3
# Groups:   Poison [4]
  Poison            Result           Group
  <chr>             <chr>            <int>
1 Arsenic           Death                1
2 Arsenic in Wine   Death With Class     1
3 Cyanide           Death                1
4 Cyanide and Sugar Death                1

可行解决方案

方法1:字符串检测+条件判断

通过str_detect检测关键词,结合case_when指定组号:

dt <- dt %>%
  mutate(Group = case_when(
    str_detect(Poison, "Arsenic") ~ 1,
    str_detect(Poison, "Cyanide") ~ 2,
    TRUE ~ 0 # 可选:为未匹配的条目设置默认组号
  ))

输出结果:

# A tibble: 4 × 3
  Poison            Result           Group
  <chr>             <chr>            <dbl>
1 Arsenic           Death                1
2 Arsenic in Wine   Death With Class     1
3 Cyanide           Death                2
4 Cyanide and Sugar Death                2

方法2:提取核心关键词转组号

提取字符串中的核心关键词,将其转为因子后生成整数组号,适合关键词较多的场景:

dt <- dt %>%
  mutate(
    # 提取开头的核心关键词
    core_keyword = str_extract(Poison, "^Arsenic|^Cyanide"),
    # 按指定顺序将关键词转为组号
    Group = as.integer(factor(core_keyword, levels = c("Arsenic", "Cyanide")))
  ) %>%
  select(-core_keyword) # 可选:删除中间辅助列

方法3:分组后自动生成组号

基于提取的关键词分组,用cur_group_id()自动分配组编号:

dt <- dt %>%
  group_by(core_keyword = str_extract(Poison, "^Arsenic|^Cyanide")) %>%
  mutate(Group = cur_group_id()) %>%
  ungroup() %>%
  select(-core_keyword)

若需指定组号顺序,可将core_keyword转为带指定levels的因子后再分组。


内容的提问来源于stack exchange,提问作者ksinva

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 13:25:28