R语言处理CIGAR字符串:统计I前排除紧邻数字的数值总和
CIGAR字符串数字统计解决方案
原有代码问题分析
你现有方案的核心错误在于正则规则的逻辑缺陷:\d+(?!I)仅匹配后方不紧跟I的数字,既没有限制匹配范围为第一个I之前的内容,也没有排除紧邻I的数字段,还会纳入I之后的所有数字,因此出现计算错误。
基础需求实现(仅统计第一个I前符合要求的数字和)
实现思路
- 先截断字符串,仅保留第一个
I之前的内容 - 剔除该部分末尾紧邻
I的数字段 - 提取剩余所有数字求和即可
代码实现
library(tidyverse) sum_prior_first_I <- function(cigar_str) { # 移除第一个I及之后的所有内容 before_first_I <- str_remove(cigar_str, "I.*$") # 若I在字符串开头,直接返回0 if (str_detect(before_first_I, "^\\d+$")) { return(0) } # 移除紧邻I的最后一段数字 before_last_num <- str_remove(before_first_I, "\\d+$") # 提取所有数字求和 sum(as.numeric(str_extract_all(before_last_num, "\\d+")[[1]]), na.rm = TRUE) } # 测试基础示例 df <- data.frame(String = c("220M1I","10I200M","5M2D1I20M","22M5D2M3I5M")) df <- df %>% rowwise() %>% mutate(Sum_prior = sum_prior_first_I(String))
输出结果
# A tibble: 4 × 2 # Rowwise: String Sum_prior <chr> <dbl> 1 220M1I 220 2 10I200M 0 3 5M2D1I20M 7 4 22M5D2M3I5M 29
完全符合预期输出。
进阶需求实现(多I场景分Output_1/Output_2统计)
实现思路
利用CIGAR字符串固定为数字+操作符交替的结构,直接拆分所有单元后按位置计算:
- 将字符串拆分为
数字+操作符的独立单元 - 提取每个单元的数值与操作符,定位所有
I的位置 - Output_1取第一个
I之前所有单元的数值和 - Output_2取第二个
I之前所有单元的数值和(自动包含前一个I对应的数字)
代码实现
calc_I_multi <- function(cigar_str) { # 拆分所有CIGAR单元 units <- str_extract_all(cigar_str, "\\d+[A-Z]")[[1]] # 拆分数值与操作符 nums <- as.numeric(str_remove(units, "[A-Z]")) ops <- str_extract(units, "[A-Z]") # 定位所有I的位置 I_pos <- which(ops == "I") Output_1 <- ifelse(length(I_pos) >= 1, sum(nums[1:(I_pos[1]-1)]), 0) Output_2 <- ifelse(length(I_pos) >= 2, sum(nums[1:(I_pos[2]-1)]), NA_real_) return(tibble(Output_1, Output_2)) } # 测试进阶示例 df2 <- data.frame(String = c("5M10I200M20I","100M2D3I105M1I10M")) df2 <- df2 %>% rowwise() %>% mutate(calc_I_multi(String))
输出结果
# A tibble: 2 × 3 # Rowwise: String Output_1 Output_2 <chr> <dbl> <dbl> 1 5M10I200M20I 5 215 2 100M2D3I105M1I10M 102 210
完全符合预期输出。
内容的提问来源于stack exchange,提问作者JREN_OP
相关产品推荐
相关产品推荐

