计算允许不匹配的唯一句子的数量

时间:2018-07-28 08:01:22

标签: python awk

我有一个包含2亿个句子的文本文件。我想计算文件中特定类型句子的出现次数,并允许两个字符不匹配(这可能是重复字符的插入,或者两个字符的丢失)。字符始终为A,G,C或T。不匹配的字符的位置可以是随机的。我提供了一个小样本来说明我的解释:

我有以下句子:

GTCGAGGTTCTCATCGCCTGGCCGCGCGTGTCTAGATCGGAAGAGCTCGT
GTTTAGGTTCTCATCGCCTGGCCGCGCGTGTCTAGATCGGAAGAGCTCGT
GTCGAGGTTCTCATCGCCTGGCCGCGCGTGTCTAGATCGGAAGAGCTAAT
TAACGTTCAGTTACGGCGTTGAGGTTTTACCTAAGATCGGAAGAGCTCGT
TCCGTAGCGCTCTGCTTCCAGTCGTGGCGGGGAGATCGGAAGAGCTCGTA
TACAAGACTTCATGAATAACGTGACTACGGAGATCGGAAGAGCTCGTATG
TAATGCCACTCCTCTCCCGACTGTTAACACTACTGGTTATATTGACCATG
CGACCTGGGTCAGCTCTGGAGTTTCGTTGAGTTAGATCGGAAGAGCTCGT
ATTTTGATAGTTTGACGGTTAATGCTGGTAATGGTGGTTTTCTTCATTGC
ACCCATGCCTACAGTATTGTTATCGGTAGCAAGCACATCACCTTGAATGC
GCAAGTTGCCATACAAAACAGGGTCGCCAGCAATATCGGTATAAGTCAAA
GAGTTCTAGTGTACGAGAGAGAGACGACGATGGAGATCGGAAGCGCTCTT
TGTTACTACAGGCATAATACGTGTTCCCGGATGAAGATCGGAAGAGCTCG
GACGACCAAAATTAGGGTCAACGCTACCTGTAGGAAGTGTCCGCATAAAG

例如,如果这是我正在看的第一句话

 GTCGAGGTTCTCATCGCCTGGCCGCGCGTGTCTAGATCGGAAGAGCTCGT

然后是文件中的第二句话

 GT**TT**AGGTTCTCATCGCCTGGCCGCGCGTGTCTAGATCGGAAGAGCTCGT

与第一句话相似,因为只有两个字符不同。

然后在文件中的第三句话

GTCGAGGTTCTCATCGCCTGGCCGCGCGTGTCTAGATCGGAAGAGCT**AA**T

在这里,最后两个字符被修改,但其他所有内容都与第一句话相似。

因此,未更改的句子可以是任何内容,然后将其余句子与两个不匹配的句子进行比较,然后计数。区别可能是重复字符,缺少字符或新字符。并且,最后,当您读取文件时,输出将是特定句子出现3次,允许不匹配。

GTCGAGGTTCTCATCGCCTGGCCGCGCGTGTCTAGATCGGAAGAGCTCGT 3 times

有没有办法可以使用awk?我尝试过:

cat myfile.fq | 
awk '((NR-2)%4==0){character=$1;total++;count[character]++}END{for(character 
   in count){if(!max||count[character]>max) 
    {max=count[character];maxcharacter=character};if(count[character]==1){unique++}};print  total,unique}'

埃德·莫顿(Ed Morton)的编辑-通过C美化工具(https://codebeautify.org/c-formatter-beautifier)运行上述awk脚本以使其可读:

((NR - 2) % 4 == 0) {
  character = $1;
  total++;
  count[character]++
}
END {
  for (character in count) {
    if (!max || count[character] > max) {
      max = count[character];
      maxcharacter = character
    };
    if (count[character] == 1) {
      unique++
    }
  };
  print total, unique
}

2 个答案:

答案 0 :(得分:1)

您的要求尚不清楚,但这是我认为您可能要尝试做的事情的起点:

$ cat tst.awk
BEGIN {
    tgtStr  = "APPLEISHEALTHY"
    tgtLgth = length(tgtStr)
}
{
    curStr  = $0
    curLgth = length(curStr)

    isMatch = 0

    if ( curStr == tgtStr ) {
        # curStr is tgtStr
        # "APPLEISHEALTHY" vs "APPLEISHEALTHY"
        isMatch = 1
    }
    else if ( curLgth == (tgtLgth-2) ) {
        # curStr may be tgtStr minus 2 chars, e.g.
        # "APPLEISHEALTHY" vs "APPLEISHEALT"
        isMatch = 1
        maxLgth = tgtLgth
        curPos = tgtPos = 0
        for (pos=1; pos<=maxLgth; pos++) {
            curChar = substr(curStr,++curPos,1)
            tgtChar = substr(tgtStr,++tgtPos,1)
            if (curChar != tgtChar) {
                if (curPos == tgtPos) {
                    # first char mismatch but curStr is 2 chars shorter
                    # than tgtStr so thats expected so advance tgtPos
                    # 1 char and back up curPos 1 char and continue.
                    curPos--
                    tgtPos++
                }
                else {
                    # still mismatching after first 2-char skip so fail
                    isMatch = 0
                }
            }
        }
    }
    else if ( curLgth == tgtLgth ) {
        # curStr may be tgtStr minus 2 chars plus 2 other chars, e.g.
        # "APPLEISHEALTHY" vs "APPLEISHEALTXX"
    }
    else if ( curLgth == (tgtLgth+2) ) {
        # curStr may be tgtStr plus 2 chars, e.g.
        # "APPLEISHEALTHY" vs "APPLEISHEALTHYXX"
    }

    print curStr, (isMatch ? "is" : "is not"), "a match for", tgtStr
}

例如:

$ cat file
APPLEISHEALTHY
APPLEISALTHY
APPLEISXLTHY

$ awk -f tst.awk file
APPLEISHEALTHY is a match for APPLEISHEALTHY
APPLEISALTHY is a match for APPLEISHEALTHY
APPLEISXLTHY is not a match for APPLEISHEALTHY

您必须仔细考虑以上逻辑,看看是否正确,并为其余2种情况编写逻辑,但希望这可以向您展示如何解决该问题。

答案 1 :(得分:0)

您似乎拥有的是测序仪的“下一代短读”
就像我喜欢用awk破坏生物信息学问题来获取乐趣和获利一样。 使用indel(插入/删除)可以牢固地使用正确的工具来完成工作,如果您想让每个人都尝试并真正再现结果,那么通常使用local alignment的工具ncbi blast
(除非这是家庭作业)

如果要在这个空间中工作,则应该采取任何方式安装blast并弄清楚参数以实现目标。