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

R语言统计分号分隔多值列内指定字符串的出现次数

问题根因

原代码使用Refer == id做整值精确匹配,仅能识别Refer单元格内容和目标ID完全相等的行,无法识别分号分隔的多值单元格中包含的目标ID,因此会漏统计符合要求的行。

方案1:最小改动原有循环代码

仅需替换匹配逻辑即可,不需要重构原有代码结构。为了避免ID存在子串包含关系时出现误匹配(比如ID为A1时误匹配A11这类值),使用带边界的正则规则做匹配:

library(dplyr)
df0 <- data.frame (ID  = c("A1", "A2", "A3", "A4", "B1", "C1", "D1"),
                  Refer = c(" ", " ", "A1", "A1;A2", "A3;A1", "A2","A2;C1")
)

n1 <- nrow(df0)
df1 = data.frame(matrix(
  vector(), 0, 2, dimnames=list(c(), c("ID","Count"))),
  stringsAsFactors=F)

for (i in 1:n1){
  id <- df0$ID[i]
  # 构造正则匹配规则:id前后只能是字符串开头/结尾,或者分号分隔符
  match_rule <- paste0("(^|;)", id, "($|;)")
  df2 <- filter(df0, grepl(match_rule, Refer))
  n2 <- nrow(df2) 
  df1[i,1] <- id
  df1[i,2] <- n2
}

运行后A1的计数为3,和预期结果一致。

方案2:无循环的简洁向量化实现

如果数据量较大,循环效率偏低,可以直接拆分多值单元格后计数,代码更简洁、运行速度更快:

library(dplyr)
library(tidyr)

df1 <- df0 %>%
  # 按分号拆分Refer列的多值,拆分为独立行
  separate_rows(Refer, sep = ";") %>%
  # 过滤掉空格、空值
  filter(trimws(Refer) != "") %>%
  # 统计每个ID的出现次数
  count(Refer, name = "Count") %>%
  # 和原始ID列表做连接,未出现的ID计数补0
  right_join(df0 %>% distinct(ID), by = c("Refer" = "ID")) %>%
  mutate(Count = tidyr::replace_na(Count, 0)) %>%
  select(ID = Refer, Count)
关键注意点
  • 不要直接用简单的无边界字符串包含逻辑(比如裸写grepl(id, Refer))做匹配,否则当ID存在命名包含关系时(比如同时存在A1和A11两个ID),会出现误计数,必须加分隔符/首尾边界限制。
  • separate_rows是tidyr包中专门处理分隔符多值单元格的函数,不需要手写字符串拆分、遍历的逻辑,适配绝大多数多值列统计场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 08:03:28