我有一个data.table
变量,它们代表抗菌药物耐药性基因变异,对于每种药物类别,它们都被串联在一起。
我需要为每个基因变体分别生成一个二进制列,如果存在给定药物类别的基因变体,则标记为TRUE
,否则为FALSE
。
新变量的名称应采用drugclass_genevariantname格式,其中drugclass是从原始变量的名称继承的,genevariantname是从使用strsplit
的拆分操作中提取的值。
基因变体之间用分号;
隔开,这是我在以下函数中用来分割的字符,它将返回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
任何能防止方括号内的第二个(或后续)变体与基因名称分离的解决方案,都将受到赞赏。
答案 0 :(得分:1)
关于分割功能,您可以首先仅使用方括号在方括号之外的分号处使用以下模式进行分割:
;(?=(?:[^\[\]]*\[[^\[\]]*\])*[^\[\]]*$)
然后,在附加步骤中拆分内部具有分号的字符串,例如使用;|\[|\]
作为拆分模式。保留第一结果以分解并重建嵌套值或类似值。