用于复杂变量拆分问题的 r 正则表达式

r regex for complex variable splitting problem

我有一个 data.table 代表抗菌药物耐药性基因变体的变量,这些变体对于每种药物都串联在一起 class。

我需要为每个基因变体生成一个单独的二进制列,如果给定药物的基因变体 class 存在,则标记为 TRUE,否则标记为 FALSE

新变量的名称应采用drugclass_genevariantname格式,其中drugclass继承自原始变量名称,genevariantname是从[拆分操作中提取的值] =16=].

基因变体由分号分隔 ; 所以这是我在下面的函数中用来拆分的字符,它将 return data.table 与添加到末尾的新二进制列:

getamr <- function(dt, amrcol, splitchar) {

    columnvector = dt[[amrcol]]

    if (all(is.na(columnvector))) {return(dt)}

    y = unique(unlist(strsplit(x = columnvector, split = splitchar)))

    y = sort(y)

    for (i in 1:length(y)) {

      dt[, noquote(paste0(amrcol, "_", y[i])) :=
           ifelse(grepl(y[i], columnvector, fixed = TRUE), TRUE, FALSE)]
    }

    return(dt)

  }

此函数适用于创建新列和识别每个基因变异是否存在。但是,由于格式复杂,基因变体的名称没有正确分配给新变量,类似于:

gene1[position1:oldAA-newAA;position2:oldAA-newAA];gene2[position1:oldAA-newAA];gene3[v];gene4;gene5

在此示例中,我希望创建以下新变量:

我遇到的困难是在上面要点中的第一种和第二种情况下,在原始字符串中,拆分字符位于方括号内。这导致:

...在第二种情况下不再有意义,变异位置和变异变化已从它们发生的基因名称中孤立出来。

我应该如何修改上面的函数来更正新的列名,以便:

  1. 像第一种情况这样的例子中方括号是闭合的
  2. 变异位置和变化总是以基因名称开头

下面是一些示例数据,说明了这个问题的复杂性:

# Load data.table:
library(data.table)

# Create example data:
mydt <- data.table(id = c(1,2,3,4,5), 
                 amr_drug1 = c("erm(B)[v];mdf(A)*;mph-(A)*;strA;sat2A", "mdf(A)*;strA;sat2A", "-", "erm(B)[v];mdf(A)*;mph-(A)*;strA;sat2A", "-"), 
                 amr_drug2 = c("-", "aph(6)-Id,strB[v]", "aph(6)-Id,strB[v]", "aph(6)-Id,strB[v]", "-"), 
                 amr_drug3 = c("gyrA_EC2[83:S-L]", "gyrA_EC2[83:S-L;87:D-N];parC_EC2[80:S-I]", "gyrA_EC2[83:S-L;87:D-N];parC_EC2[80:S-I]", "gyrA_EC2[83:S-L]", "-"), 
                 amr_drug4 = c("OXA-1", "OXA-1", "OXA-1", "OXA-1", "OXA-1"),
                 amr_drug5 = c("-", "-", "-", "-", "-"))


# Identify AMR columns:
amrcols <- grep("^amr", names(mydt), value = TRUE)

# Replace '-' with NA:
mydt[, c(amrcols) := lapply(.SD, function(x) ifelse(x == "-", NA_character_, x)), .SDcols = amrcols]

# Apply function across all AMR columns:
for (i in 1:length(amrcols)) { getamr(mydt, amrcols[i], ";") } 

第三个 amr 列 (gyrA_EC2) 中的一个基因有两个变体括在方括号中 - 在拆分操作后,第二个变体从基因名称中分离出来 - 见下文:

> mydt
   id                             amr_drug1         amr_drug2                                amr_drug3 amr_drug4 amr_drug5
1:  1 erm(B)[v];mdf(A)*;mph-(A)*;strA;sat2A              <NA>                         gyrA_EC2[83:S-L]     OXA-1      <NA>
2:  2                    mdf(A)*;strA;sat2A aph(6)-Id,strB[v] gyrA_EC2[83:S-L;87:D-N];parC_EC2[80:S-I]     OXA-1      <NA>
3:  3                                  <NA> aph(6)-Id,strB[v] gyrA_EC2[83:S-L;87:D-N];parC_EC2[80:S-I]     OXA-1      <NA>
4:  4 erm(B)[v];mdf(A)*;mph-(A)*;strA;sat2A aph(6)-Id,strB[v]                         gyrA_EC2[83:S-L]     OXA-1      <NA>
5:  5                                  <NA>              <NA>                                     <NA>     OXA-1      <NA>
   amr_drug1_erm(B)[v] amr_drug1_mdf(A)* amr_drug1_mph-(A)* amr_drug1_sat2A amr_drug1_strA amr_drug2_aph(6)-Id,strB[v]
1:                TRUE              TRUE               TRUE            TRUE           TRUE                       FALSE
2:               FALSE              TRUE              FALSE            TRUE           TRUE                        TRUE
3:               FALSE             FALSE              FALSE           FALSE          FALSE                        TRUE
4:                TRUE              TRUE               TRUE            TRUE           TRUE                        TRUE
5:               FALSE             FALSE              FALSE           FALSE          FALSE                       FALSE
   amr_drug3_87:D-N] amr_drug3_gyrA_EC2[83:S-L amr_drug3_gyrA_EC2[83:S-L] amr_drug3_parC_EC2[80:S-I] amr_drug4_OXA-1
1:             FALSE                      TRUE                       TRUE                      FALSE            TRUE
2:              TRUE                      TRUE                      FALSE                       TRUE            TRUE
3:              TRUE                      TRUE                      FALSE                       TRUE            TRUE
4:             FALSE                      TRUE                       TRUE                      FALSE            TRUE
5:             FALSE                     FALSE                      FALSE                      FALSE            TRUE

任何防止方括号内的第二个(或后续)变体与其基因名称分开的解决方案将不胜感激。

关于拆分功能,您可以首先使用如下模式仅在方括号外的分号处拆分:

;(?=(?:[^\[\]]*\[[^\[\]]*\])*[^\[\]]*$)

然后,在额外的步骤中拆分内部有分号的字符串,例如使用 ;|\[|\] 作为拆分模式。保留第一个结果以分解并重建嵌套值或类似值。

Regex demonstration