我有一个8个字母的DNA序列表,例如:
GGAGACAA
GGATACAA
AATCAGTC
ACACCTGG
我想选择位置的所有行,每行至少2个不同的行。理想情况下,我想保留3,4和1或2行(但不关心哪一行)。但至少,我想保留3和4.最重要的是,没有包含的线与任何其他保留线只有一个位置基差。
你会怎么做? R,grep / gawk是我常用的工具,但我无法弄清楚如何使用那些看似简单的任务。
ETA-第一和第二行只有一个字母彼此不同(G与第四位的T)。这就是为什么我不想保留它们的原因。有大约65,000个可能的8个碱基的组合,所以我的大多数(~4000行)列表应该满足这2个不同于所有其他行标准的字母。我很难弄清楚如何找到那些没有的人。
答案 0 :(得分:6)
stringdist包具有函数stringdistmatrix和许多不同的距离度量。
> library(stringdist)
> stringdistmatrix(x, x)
[,1] [,2] [,3] [,4]
[1,] 0 1 7 7
[2,] 1 0 6 7
[3,] 7 6 0 5
[4,] 7 7 5 0
现在由你决定你的意思" 2个不同的字母"!
答案 1 :(得分:3)
使用adist
:
txt <- c("GGAGACAA", "GGATACAA", "AATCAGTC", "ACACCTGG")
d <- adist(txt)
diag(d) <- Inf
cuts <- col(d)[lower.tri(d)][d[lower.tri(d)] <= 2]
#[1] 1 # will be removed:
txt[-cuts]
#[1] "GGATACAA" "AATCAGTC" "ACACCTGG"
答案 2 :(得分:2)
复制数据
txt <- c("GGAGACAA", "GGATACAA", "AATCAGTC", "ACACCTGG")
比较所有序列
# split into letters
txtw <- sapply(txt, strsplit, "")
# find differences
txtc <- lapply(txtw, function(x) sapply(txtw, function(y) sum(x!=y)))
输出是同一地方与其他字母序列相比有多少字母的列表
> txtc
$GGAGACAA
GGAGACAA GGATACAA AATCAGTC ACACCTGG
0 1 7 7
$GGATACAA
GGAGACAA GGATACAA AATCAGTC ACACCTGG
1 0 7 7
$AATCAGTC
GGAGACAA GGATACAA AATCAGTC ACACCTGG
7 7 0 6
$ACACCTGG
GGAGACAA GGATACAA AATCAGTC ACACCTGG
7 7 6 0
如果您的比较是针对&#34; GGAGACAA&#34;,则2符合您的标准
> txtc[["GGAGACAA"]] > 1
GGAGACAA GGATACAA AATCAGTC ACACCTGG
FALSE FALSE TRUE TRUE
但如果你的参考是例如&#34; AATCAGTC&#34;,所有(除#34; AATCAGTC&#34;本身)符合您的标准
> txtc[["AATCAGTC"]] > 1
GGAGACAA GGATACAA AATCAGTC ACACCTGG
TRUE TRUE FALSE TRUE
所以我想你需要决定哪一个是参考。如果你总结一下与其他数据的区别,我想对于另一个数据集,你可能会发现一些与其他数据不同的东西(即显示为下面的3),但你的样本显示所有这些数据集至少有2个其他字符串至少有2个字母不同。
> sapply(txtc, function(x) sum(x>1))
GGAGACAA GGATACAA AATCAGTC ACACCTGG
2 2 3 3
编辑:按照上述方法,识别与其他所有内容至少在2个空格中不同的序列,只需找到最后一行非零输出的序列。但是,给定的样本数据似乎没有满足该标准的任何内容,因此我将使用下面的不同数据集重新运行:
txt <- c("GGAGACAA", "GGATACAA", "GGACACAA", "AGATACAA")
txtw <- sapply(txt, strsplit, "")
txtc <- lapply(txtw, function(x) sapply(txtw, function(y) sum(x!=y)))
# counting the number of different sequence against all sequences
matches <- sapply(txtc, function(x) sum(x>1))
# find those which has at least 1 other different sequence
different <- matches[matches>0]
在上面的示例中,&#34; GGATACAA&#34;只有一个字符与其他一个字符不同,所以我希望输出排除它,
> different
GGAGACAA GGACACAA AGATACAA
1 1 2
情况就是这样。上面的数字是至少有2个字母差异的序列数。 &#34; GGAGACAA&#34;和&#34; GGACACAA&#34;只有1个字母彼此不同,但保留,因为它们有1个符合该标准的其他序列,即&#34; AGATACAA&#34;。 &#34; AGATACAA&#34;有2个其他序列符合标准。
答案 3 :(得分:1)
$ cat tst.awk
{ a[NR] = $0 }
END {
lgth = length(a[1])
for (i=1;i<=NR;i++) {
maxSame = 0
for (j=1;j<=NR;j++) {
if (i != j) {
numSame = 0
for (k=1;k<=lgth;k++) {
if ( substr(a[i],k,1) == substr(a[j],k,1) ) {
numSame++
}
}
maxSame = (numSame > maxSame ? numSame : maxSame)
}
}
if ( maxSame < (lgth-2) ) {
print a[i]
}
}
}
$ awk -f tst.awk file
AATCAGTC
ACACCTGG
可能有一些方法可以使上述更有效,留作练习: - )。