【问题标题】:Counting occurrences of a word in a file, counting the number of occurrences of any repeated word. Perl计算文件中某个单词的出现次数,计算任何重复单词的出现次数。 Perl
【发布时间】:2023-04-04 02:38:01
【问题描述】:

我使用正则表达式逐行读取文件,然后将其拆分为如下标量变量,正则表达式可以正常工作。

while (<GTFFILE>) {

        if ($_ =~ /(^\d)\s+\w+\s+(\w+)\s+(\d+)\s+(\d+)\s+\.\s+\W\s+\.\s+(\w+\_\w+\s+\"\w+\"\;)/){

    my $gene = $1;
    my $type = $2;
    my $start = $3;
    my $end = $4;
    my $geneId = $5;

尝试从从正则表达式中获取的值生成散列。

    $featurestart{$start} = $start;
    $featureend{$end} = $end;   

我需要使用从正则表达式生成的哈希来查找外显子的长度。这是每行完成的,但我收到错误:Missing $ on loop variable。有什么想法吗?

            for each ($_) { 
            $exonlength = ($featureend{$_} - $featurestart{$_});
            printf ("Exon lengths: = %1.1f\n", $exonlength);
            }

在这里我一无所知,我想找到$geneId中每个单词的出现次数。我将如何匹配未知单词,并计算每个未知单词的不同出现次数?我猜测某种函数可以聚集在一起,也许在散列/数组中将一个单词的重复放在一起,然后以某种方式计算每个簇?

                    $geneCount{$geneId} = $type; 
                foreach $geneId { 

                }
        }   
    }
}

GTF 文件的每一行是: 1 个未知外显子 3204563 3207049。 - 。基因ID“Xkr4”;基因名称“Xkr4”; p_id "P15240"; transcript_id "NM_001011874.1"; tss_id "TSS13146"; 这就是正则表达式正在阅读的内容。外显子因行而异,可以是外显子,也可以是 cds 等,每行只有一个或另一个,因此计算外显子一词的出现次数,计算文件中外显子的数量。 “外显子”后面用空格隔开的两个数字是坐标,外显子长度是通过从第一个数字中减去第二个数字来计算的。用';'分隔的短语被分组为geneId。对于这些,我想计算整个文件中这部分的出现次数,类似于外显子,这会发生变化,但是不知道字符串可能是什么,所以想法是找出这个变量中有多少不同的字符串出现。

【问题讨论】:

    标签: regex perl count hashmap tr


    【解决方案1】:

    好的,有几个问题。首先请允许我将必填链接放到https://metacpan.org/pod/Bio::Perl,当有人提到基因和解析文件时,我总是很想这样做。

    当你到达​​p>

    if ($_ =~ /exon/)
    

    $_ 仍然是整行。因此,您检查当前行中是否包含字符串“exon”。所以我假设您想计算该字符串的出现次数?可悲的是tr/// 不会为你这样做。相反,它将用自己替换每个“e”、“x”、“o”或“n”,并计算发生的频率。所以你计算字符,而不是“外显子”这个词。如果你坚持用这种笨拙的方式计算 s/exon/exon/g 而不是 tr/// 东西应该可以工作。

    编辑: 好的,抱歉,我不得不中断写作。

    对于您的错误:您要循环什么?如果你的意思是

    foreach ($_) {
    

    那么这没有多大意义,因为$_ 只是一个元素。外显子的长度是多少?我根本不知道外显子是什么。 但我假设您打算以其他方式填充您的哈希值。实际上,它们与值具有相同的键,因此首先将它们放在首位并没有多大意义。

    如果您在计数后需要任何帮助,您当然必须提供更多信息,您的输入是什么样的以及您正在尝试做什么。

    edit 2 问题被编辑后:

    好的,如果这是您想要做的,您可以执行以下操作:

    my $numberOfExon = 0;   # We will increase this whenever we meet an exon.
    my @exonLength;         # This array will store all the exon lengths          
    my %geneCount;          # This hash will store the counts per geneId
    
    while (<GTFFILE>) {
    
        if ($_ =~ /(^\d)\s+\w+\s+(\w+)\s+(\d+)\s+(\d+)\s+\.\s+\W\s+\.\s+(\w+\_\w+\s+\"\w+\"\;)/){
    
            my $gene = $1;
            my $type = $2;
            my $start = $3;
            my $end = $4;
            my $geneId = $5;
    
            if ($_ =~ /exon/){
    
                $numberOfExon++;              # just count the lines that have exon in them
                my $length = $end - $start;   # just calculate the length
    
                push @exonLength, $length;    # Do with the length whatever you want
    
                $geneCount{$geneId}++;        # Increase the number of times this Id was seen
                                              # If this was the first time, a new field is created
            }
        }
    }
    
    print "Number of Exon: $numberOfExon \n";
    print "Count of Ids:\n";
    use Data::Dumper;
    print Dumper(\%geneCount);
    

    这仅计算外显子的 Id,而不是其他任何东西的 Id。如果你想要其他的,只需将geneCount{geneId}++放在第一个}(if外显子部分)之后。

    【讨论】:

    • 感谢您的回复,我已经编辑了我的问题,以便您更清楚。现在应该显示输入文件的样子。你觉得数组比散列更有用吗?
    • @CG3 更新了答案
    • 再次感谢,您能告诉我如何打印外显子的数量和不同基因的数量吗?我已经尝试过您的解决方案,但它仍在打印大量数字,而不是每个数字的单个计数值。
    • ID 计数:$VAR1 = {};抱歉,我按回车太快了,我的意思是说这是为geneId 计数打印的内容?
    • 抱歉,我意识到我只是把 print 语句放在了错误的位置,但现在它只打印出其中一个实例:Ids 计数:$VAR1 = { '"Xkr4";' => 1 }; ?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-24
    • 2012-08-09
    相关资源
    最近更新 更多