短文列表,要选择至少2个字母不同的行

时间:2015-07-20 03:36:13

标签: r text awk grep

我有一个8个字母的DNA序列表,例如:

    GGAGACAA  
    GGATACAA 
    AATCAGTC 
    ACACCTGG 

我想选择位置的所有行,每行至少2个不同的行。理想情况下,我想保留3,4和1或2行(但不关心哪一行)。但至少,我想保留3和4.最重要的是,没有包含的线与任何其他保留线只有一个位置基差。

你会怎么做? R,grep / gawk是我常用的工具,但我无法弄清楚如何使用那些看似简单的任务。

ETA-第一和第二行只有一个字母彼此不同(G与第四位的T)。这就是为什么我不想保留它们的原因。有大约65,000个可能的8个碱基的组合,所以我的大多数(~4000行)列表应该满足这2个不同于所有其他行标准的字母。我很难弄清楚如何找到那些没有的人。

4 个答案:

答案 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

可能有一些方法可以使上述更有效,留作练习: - )。