R 索引字符串,字符块表示核苷酸变体

R indexing string with character blocks denoting nucleotide variants

我的问题是我需要在字符串中找到一个位置,其中我有字符块,实际上应该只是一个字符位置。我正在处理核苷酸序列,我需要跟踪序列中的位置,但我有一些位置存在变体,这些变体被表示为 [A/T],其中可能存在 A 或 T,具体取决于我关心哪个序列(这是两个相似的 DNA 序列,在整个序列中有几个位置不同)。因此,对于这些变异位点中的每一个,序列的长度都多了四 characters/positions。

我知道我可以通过编写新代码来解决这个问题,其中 [A/T] 可以转换为 X,而 [T/A] 由 Y 表示,但这会让人感到困惑因为已经有一个标准的简并代码,但它不会跟踪哪个核苷酸来自哪个品系(对我来说,/ 之前的那个来自品系 A,/ 之后的那个来自品系 B)。我想以某种方式索引这个 DNA 序列字符串,我在下面这样想:

如果我有这样的字符串:

dna <- "ATC[A/T]G[G/C]ATTACAATCG"

我想要一个 table/data.frame:

pos nuc
1   A
2   T
3   C
4   [A/T]
5   G
6   [G/C]
... and so on

如果我更了解正则表达式,我觉得我可以以某种方式使用 strplit。我可以在每个字符处插入条件以拆分,除非被方括号约束,方括号应作为一个块保留吗?

这是一个简单的方法来获取括号中字符以外的所有内容:

strsplit(dna, '\[[A-Z]/[A-Z]\]')

[[1]]
[1] "ATC"        "G"          "ATTACAATCG"

也许否定会给你括号内的任何东西,或者在我列出的参数中使用正则表达式。

编辑: 这是可以让您了解括号之间内容的代码:

lbracket <- as.numeric(unlist(gregexpr('\[', dna)))
rbracket <- as.numeric(unlist(gregexpr('\]', dna)))
mapply(function(x, y) substr(dna, start=x, stop=y), lbracket, rbracket)

[1] "[A/T]" "[G/C]"

应该可以。

library('stringr')
df <- as.data.frame(strsplit(gsub("\[./.\]", '_', dna), ''), stringsAsFactors=F)
df[,1][df[,1] == '_'] <- str_extract_all(dna, "\[./.\]")[[1]];names(df) <- 'nuc'
df
#      nuc
# 1      A
# 2      T
# 3      C
# 4  [A/T]
# 5      G
# 6  [G/C]
# 7      A
# 8      T
# 9      T
# 10     A
# 11     C
# 12     A
# 13     A
# 14     T
# 15     C
# 16     G

这是另一个

dna <- "ATC[A/T]G[G/C]ATTACAATCG"

(tmp <- gsub('(\w)(\w)','~\1~\2~', dna))
# [1] "~A~T~C[A/T]G[G/C]~A~T~~T~A~~C~A~~A~T~~C~G~"

(nuc <- Filter(nzchar, strsplit(gsub("(\[.+?\])","~\1~", tmp), '~')[[1]]))
# [1] "A"     "T"     "C"     "[A/T]" "G"     "[G/C]" "A"     "T"     "T"    
# [10] "A"     "C"     "A"     "A"     "T"     "C"     "G"

data.frame(nuc)
#      nuc
# 1      A
# 2      T
# 3      C
# 4  [A/T]
# 5      G
# 6  [G/C]
# 7      A
# 8      T
# 9      T
# 10     A
# 11     C
# 12     A
# 13     A
# 14     T
# 15     C
# 16     G

我是那种喜欢简单的人,这里有一个小技巧...

x <- 'ATC[A/T]G[G/C]ATTACAATCG'
data.frame(nuc = regmatches(x, gregexpr('\[[^]]*]|.', x))[[1]])

#      nuc
# 1      A
# 2      T
# 3      C
# 4  [A/T]
# 5      G
# 6  [G/C]
# 7      A
# 8      T
# 9      T
# 10     A
# 11     C
# 12     A
# 13     A
# 14     T
# 15     C
# 16     G

上面的正则表达式使用交替,在左边我们匹配方括号内的子字符串,在右边我们使用.匹配任何单个字符。