假设我有一个像下面的
myseq
这样的序列。它是一个 DNA 序列,因此每组 3 个连续字母在随附的 myaa
序列中构成一个字母(氨基酸)。
我想创建一个
mydf
数据框,其中包含 myseq
中每组 3 个字母的开始和结束位置。在下面没有间隙的基本示例中,我可以使用 seq()
轻松完成此操作。
myseq <- "CTACGTAGCTAGCTGGGGTACCGTTATTCAGCTAGCATG"
myaa <- "XYZWWXZZVVYZX"
st_pos <- seq(1, nchar(myseq)+1-3, 3)
en_pos <- seq(1+3, nchar(myseq)+1, 3)
mydf <- data.frame(starts=st_pos, ends=en_pos, label=unlist(strsplit(myaa, "")))
这会产生这个数据框,这正是我想要的:
> mydf
starts ends label
1 1 4 X
2 4 7 Y
3 7 10 Z
4 10 13 W
5 13 16 W
6 16 19 X
7 19 22 Z
8 22 25 Z
9 25 28 V
10 28 31 V
11 31 34 Y
12 34 37 Z
13 37 40 X
但是,我在实际数据中遇到了一些示例,其中
myseq
包含间隙。在这些情况下,我不能依赖 seq()
,因为我需要考虑起始位置和结束位置的间隙。
我该怎么办?我向您展示了下面的 2 个案例,以及我预期的
mydf
数据框,我只是硬编码了开始和结束位置。
#case 1 - gaps breaking groups of 3 letters in half
myseq <- "CTACGTAGCTAGCTGGGGTACCGTT---ATTC--AGCTAGCATG"
st_pos <- c(1, 4, 7, 10, 13, 16, 19, 22, 25, 31, 36, 39, 42)
en_pos <- c(4, 7, 10, 13, 16, 19, 22, 25, 31, 36, 39, 42, 45)
mydf <- data.frame(starts=st_pos, ends=en_pos, label=unlist(strsplit(myaa, "")))
#case 2 - gaps in between groups of 3 letters, and at the beginning of groups of 3 letters
myseq <- "CTACGTAGCTAGCTGGGGTACCGT---TAT--TCAGCTAGCATG"
st_pos <- c(1, 4, 7, 10, 13, 16, 19, 22, 29, 32, 36, 39, 42)
en_pos <- c(4, 7, 10, 13, 16, 19, 22, 25, 32, 36, 39, 42, 45)
mydf <- data.frame(starts=st_pos, ends=en_pos, label=unlist(strsplit(myaa, "")))
在这些情况下我应该如何以简单的方式生成
st_pos
和 en_pos
向量?谢谢!
你可以试试
> myseq <- "CTACGTAGCTAGCTGGGGTACCGTT---ATTC--AGCTAGCATG"
> add <- cumsum(c(FALSE, diff(el(strsplit(myseq, '')) == '-')) > 0)
> t(t(matrixStats::colRanges(matrix(seq_len(nchar(myseq)) + add, 3))) + c(0, 1))
[,1] [,2]
[1,] 1 4
[2,] 4 7
[3,] 7 10
[4,] 10 13
[5,] 13 16
[6,] 16 19
[7,] 19 22
[8,] 22 25
[9,] 25 29
[10,] 29 32
[11,] 32 36
[12,] 36 39
[13,] 39 42
[14,] 42 45
[15,] 1 47
Warning message:
In matrix(seq_len(nchar(myseq)) + add, 3) :
data length [44] is not a sub-multiple or multiple of the number of rows [3]