如何基于字符串模式拼接数据框同一列内的关联字符串?
解决方案:批量拼接样本名称与对应编号
Tidyverse 实现(推荐)
利用dplyr的分组填充和字符串处理功能,完美匹配你的需求:
library(tidyverse) # 原始数据 df <- data.frame(sample_name = c("Sample01", "g01", "g02", "g03", "Sample02", "g01", "g02", "Sample03", "g03", "g04", "g07")) # 核心处理逻辑 result_df <- df %>% # 标记样本名称行,非样本行设为NA mutate(group = if_else(str_detect(sample_name, "^[A-Z][a-z]+\\d{2}$"), sample_name, NA_character_)) %>% # 向下填充分组,让每个g编号对应最近的样本名称 fill(group, .direction = "down") %>% # 仅保留g开头的编号行 filter(str_detect(sample_name, "^g")) %>% # 拼接样本名称与编号 mutate(sample_name = str_c(group, sample_name, sep = "_")) %>% # 清理冗余列 select(-group) # 输出结果 print(result_df)
步骤说明:
- 识别样本行:用正则表达式
^[A-Z][a-z]+\\d{2}$匹配SampleXX格式的行,生成分组标识。 - 填充分组:通过
fill将每个g编号行关联到上方最近的样本名称,自动处理不同样本对应的行数差异。 - 拼接字符串:过滤掉原始样本行后,用
str_c完成下划线拼接,得到目标格式。
Base R 实现
如果不依赖Tidyverse,可通过基础函数完成:
# 原始数据 df <- data.frame(sample_name = c("Sample01", "g01", "g02", "g03", "Sample02", "g01", "g02", "Sample03", "g03", "g04", "g07")) # 1. 定位样本名称行 sample_pos <- which(grepl("^[A-Z][a-z]+\\d{2}$", df$sample_name)) sample_names <- df$sample_name[sample_pos] # 2. 确定每个样本对应的g编号行范围 g_ranges <- mapply( function(start, end) (start + 1):(end - 1), start = sample_pos, end = c(sample_pos[-1], nrow(df) + 1) ) # 3. 批量拼接字符串 combined_names <- unlist(mapply( function(sample, rows) paste0(sample, "_", df$sample_name[rows]), sample = sample_names, rows = g_ranges )) # 转为目标数据框 result_df_base <- data.frame(sample_name = combined_names) # 输出结果 print(result_df_base)
步骤说明:
- 定位样本行:用
grepl和which找到所有样本名称的位置。 - 划分g行范围:通过
mapply计算每个样本对应的g编号行区间,自动适配不同样本的行数。 - 拼接生成结果:再次用
mapply批量拼接样本名称与对应编号,最终转为数据框。
内容的提问来源于stack exchange,提问作者Spencer
相关产品推荐
相关产品推荐

