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

如何按F/P/C标签拆分数据集列,多匹配时生成其余列重复的多行?

R实现:拆分多标签字符串列并生成多行数据

问题描述

我有一个数据集,其中某一列的值为字符串,格式为:F: 任意内容; F: 任意内容; P: 任意内容; P: 任意内容; C:任意内容; C: 任意内容;。需要将该列拆分为F、P、C三列,当存在多个F(或P、C)时,需为每个匹配项生成一行,其余列保持不变。

示例输入

Name Value GOs
Ab1 1000 "F: f1; F: f2; P: p1"
Bb1 2000 "P: p1; F: f1"
Cb1 3000 "C: c1; F: f1"

期望输出

Name Value F P C
Ab1 1000 f1 p1 -
Ab1 1000 f2 p1 -
Bb1 2000 f1 p1 -
Cb1 3000 f1 - c1

尝试使用str_match(a, "F:\\s*(.*?)\\s*;")仅能匹配第一个结果,需要获取所有匹配项。测试数据集代码:

df <- data.frame(Name = c("A","B","C"),Value = c(10,20,30),GOs= c("F: f1; F: f2; P: p1","P: p1; F: f1","C: c1; F: f1"))

解决方案

使用stringr包的str_extract_all获取所有匹配项,结合dplyr的行处理与展开功能实现需求,完整代码如下:

library(dplyr)
library(stringr)

# 加载测试数据
df <- data.frame(Name = c("A","B","C"),Value = c(10,20,30),GOs= c("F: f1; F: f2; P: p1","P: p1; F: f1","C: c1; F: f1"))

# 处理流程
result <- df %>%
  # 提取所有F、P、C对应的内容,生成列表列
  mutate(
    F = str_extract_all(GOs, "(?<=F:\\s).*?(?=\\s*;|$)"),
    P = str_extract_all(GOs, "(?<=P:\\s).*?(?=\\s*;|$)"),
    C = str_extract_all(GOs, "(?<=C:\\s).*?(?=\\s*;|$)")
  ) %>%
  # 按行处理,统一各列表列的长度
  rowwise() %>%
  mutate(
    max_len = max(length(F), length(P), length(C)),
    # 空列表替换为"-",短列表填充至最长长度
    F = if (length(F) == 0) rep("-", max_len) else rep(F, length.out = max_len),
    P = if (length(P) == 0) rep("-", max_len) else rep(P, length.out = max_len),
    C = if (length(C) == 0) rep("-", max_len) else rep(C, length.out = max_len)
  ) %>%
  ungroup() %>%
  # 将列表列展开为多行
  unnest(c(F, P, C)) %>%
  # 移除临时列和原GOs列
  select(-GOs, -max_len)

# 输出结果
print(result)

关键说明

  • str_extract_all:通过正则表达式的正向零宽断言,精准捕获每个标签后的内容,一次性获取所有匹配项,解决了str_match仅匹配第一个结果的问题。
  • 行内统一长度:按行计算当前行F/P/C列表的最大长度,将短列表重复填充到相同长度,确保展开时每行的标签值一一对应。
  • unnest:将列表列拆分为多行,每个标签匹配项单独占一行,同时保留原数据的其他列内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 19:28:15