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

如何用R拆分数据框中+分隔内容并生成对应多行记录

解决方案

这里提供两种实现方式,分别基于tidyverse工具包和Base R,都能满足需求:

方法一:使用tidyverse工具包

tidyverse的函数组合可以更简洁地实现数据处理逻辑:

library(tidyverse)

# 原数据框
df <- data.frame(Gene= c("A", "B", "C","D","E","F"),
                 G1=c("GH13_22+CBM4",  "GH109+PL7+GH9","GT57", "AA3","",""),
                 G2=c("GH13_22","","GT57+GH15","AA3", "GT41","PL+PL2"),
                 G3=c("GH13", "GH1O9","", "CBM34+GH13+CBM48", "GT41","GH16+CBM4+CBM54+CBM32"))

# 处理逻辑
df2 <- df %>%
  group_by(Gene) %>%
  mutate(
    # 拆分各列的"+"分隔内容,空字符串转为空列表
    G1_list = str_split(G1, "\\+") %>% map(~ if(.x == "") character(0) else .x),
    G2_list = str_split(G2, "\\+") %>% map(~ if(.x == "") character(0) else .x),
    G3_list = str_split(G3, "\\+") %>% map(~ if(.x == "") character(0) else .x),
    # 计算当前Gene组需要扩展的最大行数
    max_rows = max(lengths(G1_list), lengths(G2_list), lengths(G3_list))
  ) %>%
  # 按最大行数扩展每组的行数
  uncount(max_rows) %>%
  # 生成行索引,用于提取对应位置的元素
  mutate(row_idx = row_number()) %>%
  # 提取元素,超出拆分长度的位置填空字符串
  mutate(
    G1 = map2_chr(G1_list, row_idx, ~ if(.y <= length(.x)) .x[.y] else ""),
    G2 = map2_chr(G2_list, row_idx, ~ if(.y <= length(.x)) .x[.y] else ""),
    G3 = map2_chr(G3_list, row_idx, ~ if(.y <= length(.x)) .x[.y] else "")
  ) %>%
  # 移除辅助列
  select(-G1_list, -G2_list, -G3_list, -max_rows, -row_idx) %>%
  ungroup()

# 查看结果
print(df2)

方法二:使用Base R

如果不想加载第三方包,Base R的循环处理也能实现需求:

# 原数据框(设置stringsAsFactors=FALSE确保字符类型)
df <- data.frame(Gene= c("A", "B", "C","D","E","F"),
                 G1=c("GH13_22+CBM4",  "GH109+PL7+GH9","GT57", "AA3","",""),
                 G2=c("GH13_22","","GT57+GH15","AA3", "GT41","PL+PL2"),
                 G3=c("GH13", "GH1O9","", "CBM34+GH13+CBM48", "GT41","GH16+CBM4+CBM54+CBM32"),
                 stringsAsFactors = FALSE)

result_list <- list()

# 循环处理每个Gene
for(g in unique(df$Gene)){
  sub_df <- df[df$Gene == g, ]
  # 拆分各列内容,空字符串转为空向量
  g1_split <- if(sub_df$G1 == "") character(0) else strsplit(sub_df$G1, "\\+")[[1]]
  g2_split <- if(sub_df$G2 == "") character(0) else strsplit(sub_df$G2, "\\+")[[1]]
  g3_split <- if(sub_df$G3 == "") character(0) else strsplit(sub_df$G3, "\\+")[[1]]
  
  # 计算当前Gene需要的最大行数
  max_len <- max(length(g1_split), length(g2_split), length(g3_split))
  
  # 扩展各列,不足的位置填空字符串
  g1_expand <- c(g1_split, rep("", max_len - length(g1_split)))
  g2_expand <- c(g2_split, rep("", max_len - length(g2_split)))
  g3_expand <- c(g3_split, rep("", max_len - length(g3_split)))
  
  # 生成当前Gene的结果子框
  sub_result <- data.frame(Gene = rep(g, max_len),
                           G1 = g1_expand,
                           G2 = g2_expand,
                           G3 = g3_expand,
                           stringsAsFactors = FALSE)
  result_list[[g]] <- sub_result
}

# 合并所有子数据框并重置行名
df2 <- do.call(rbind, result_list)
rownames(df2) <- NULL

# 查看结果
print(df2)

两种方法最终生成的df2都与你给出的期望输出完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 11:05:17