用于复杂变量拆分问题的 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
在此示例中,我希望创建以下新变量:
drug1_gene1[position1:oldAA-newAA]
drug1_gene1[position2:oldAA-newAA]
drug1_gene2[position1:oldAA-newAA]
drug1_gene3[v]
drug1_gene4
drug1_gene5
我遇到的困难是在上面要点中的第一种和第二种情况下,在原始字符串中,拆分字符位于方括号内。这导致:
drug1_gene1[position1:oldAA-newAA
drug1_position2:oldAA-newAA]
...在第二种情况下不再有意义,变异位置和变异变化已从它们发生的基因名称中孤立出来。
我应该如何修改上面的函数来更正新的列名,以便:
- 像第一种情况这样的例子中方括号是闭合的
- 变异位置和变化总是以基因名称开头
下面是一些示例数据,说明了这个问题的复杂性:
# 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
任何防止方括号内的第二个(或后续)变体与其基因名称分开的解决方案将不胜感激。
关于拆分功能,您可以首先使用如下模式仅在方括号外的分号处拆分:
;(?=(?:[^\[\]]*\[[^\[\]]*\])*[^\[\]]*$)
然后,在额外的步骤中拆分内部有分号的字符串,例如使用 ;|\[|\]
作为拆分模式。保留第一个结果以分解并重建嵌套值或类似值。
我有一个 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
在此示例中,我希望创建以下新变量:
drug1_gene1[position1:oldAA-newAA]
drug1_gene1[position2:oldAA-newAA]
drug1_gene2[position1:oldAA-newAA]
drug1_gene3[v]
drug1_gene4
drug1_gene5
我遇到的困难是在上面要点中的第一种和第二种情况下,在原始字符串中,拆分字符位于方括号内。这导致:
drug1_gene1[position1:oldAA-newAA
drug1_position2:oldAA-newAA]
...在第二种情况下不再有意义,变异位置和变异变化已从它们发生的基因名称中孤立出来。
我应该如何修改上面的函数来更正新的列名,以便:
- 像第一种情况这样的例子中方括号是闭合的
- 变异位置和变化总是以基因名称开头
下面是一些示例数据,说明了这个问题的复杂性:
# 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
任何防止方括号内的第二个(或后续)变体与其基因名称分开的解决方案将不胜感激。
关于拆分功能,您可以首先使用如下模式仅在方括号外的分号处拆分:
;(?=(?:[^\[\]]*\[[^\[\]]*\])*[^\[\]]*$)
然后,在额外的步骤中拆分内部有分号的字符串,例如使用 ;|\[|\]
作为拆分模式。保留第一个结果以分解并重建嵌套值或类似值。