在一组字符串

时间:2016-06-08 13:47:01

标签: r perl

我输入了一个基因列表,其中每个基因都有一个像> SomeText的标题。 对于每个基因,我想找到字符串GTG的频率。 (出现次数除以基因长度)。只有从1,4,7,10等位置(每个位置)开始,才能对字符串进行计数。

 >ENST00000619537.4 cds:known chromosome:GRCh38:21:6560714:6564489:1 gene:ENSG00000276076.4 gene_biotype:protein_coding transcript_biotype:protein_coding gene_symbol:CH507-152C13.3 description:alpha-crystallin A chain  [Source:RefSeq peptide;Acc:NP_001300979]
ATGGATGTGACCATCCAGCACCCCTGGTTCAAGCGCACCCTGGGGCCCTTCTACCCCAGC
CGGCTGTTCGACCAGTTTTTCGGCGAGGGCCTTTTTGAGTATGACCTGCTGCCCTTCCTG
TCGTCCACCATCAGCCCCTACTACCGCCAGTCCCTCTTCCGCACCGTGCTGGACTCCGGC
ATCTCTGAGGTTCGATCCGACCGGGACAAGTTCGTCATCTTCCTCGATGTGAAGCACTTC
TCCCCGGAGGACCTCACCGTGAAGGTGCAGGACGACTTTGTGGAGATCCACGGAAAGCAC
AACGAGCGCCAGGACGACCACGGCTACATTTCCCGTGAGTTCCACCGCCGCTACCGCCTG
CCGTCCAACGTGGACCAGTCGGCCCTCTCTTGCTCCCTGTCTGCCGATGGCATGCTGACC
TTCTGTGGCCCCAAGATCCAGACTGGCCTGGATGCCACCCACGCCGAGCGAGCCATCCCC
GTGTCGCGGGAGGAGAAGCCCACCTCGGCTCCCTCGTCCTAA
>ENST00000624019.3 cds:known chromosome:GRCh38:21:6561284:6563978:1 gene:ENSG00000276076.4 gene_biotype:protein_coding transcript_biotype:protein_coding gene_symbol:CH507-152C13.3 description:alpha-crystallin A chain  [Source:RefSeq peptide;Acc:NP_001300979]
ATGGACGCCCCCCCCCCCCACCCAACCACAGGCCTCCTCTCTGAGCCACGGGTTCGATCC
GACCGGGACAAGTTCGTCATCTTCCTCGATGTGAAGCACTTCTCCCCGGAGGACCTCACC
GTGAAGGTGCAGGACGACTTTGTGGAGATCCACGGAAAGCACAACGAGCGCCAGGACGAC
CACGGCTACATTTCCCGTGAGTTCCACCGCCGCTACCGCCTGCCGTCCAACGTGGACCAG
TCGGCCCTCTCTTGCTCCCTGTCTGCCGATGGCATGCTGACCTTCTGTGGCCCCAAGATC
CAGACTGGCCTGGATGCCACCCACGCCGAGCGAGCCATCCCCGTGTCGCGGGAGGAGAAG
CCCACCTCGGCTCCCTCGTCCTAA
>ENST00000624932.1 cds:known chromosome:GRCh38:21:6561954:6564203:1 gene:ENSG00000276076.4 gene_biotype:protein_coding transcript_biotype:protein_coding gene_symbol:CH507-152C13.3 description:alpha-crystallin A chain  [Source:RefSeq peptide;Acc:NP_001300979]
ATGCCTGTCTGTCCAGGAGACAGTCACAGGCCCCCGAAAGCTCTGCCCCACTTGGTGTGT
GGGAGAAGAGGCCGGCAGGTTCGATCCGACCGGGACAAGTTCGTCATCTTCCTCGATGTG
AAGCACTTCTCCCCGGAGGACCTCACCGTGAAGGTGCAGGACGACTTTGTGGAGATCCAC
GGAAAGCACAACGAGCGCCAGGACGACCACGGCTACATTTCCCGTGAGTTCCACCGCCGC
TACCGCCTGCCGTCCAACGTGGACCAGTCGGCCCTCTCTTGCTCCCTGTCTGCCGATGGC
ATGCTGACCTTCTGTGGCCCCAAGATCCAGACTGGCCTGGATGCCACCCACGCCGAGCGA
GCCATCCCCGTGTCGCGGGAGGAGAAGCCCACCTCGGCTCCCTCGTCCTAA

输出:

Gene   Frequency
Gene1: 3
Gene2 6.3
....

我觉得这样的事情,但我现在不知道如何定义职位要求:

freq <- sapply(gregexpr("GTG",x),function(x)if(x[[1]]!=-1) length(x) else 0)

5 个答案:

答案 0 :(得分:1)

以下是R中使用stringi的想法。

我们使用stri_locate_all_fixed()查找每个start出现的endGTG位置。然后我们创建一个列condition来测试start位置是否在1,4,7,10,13,16,19,22 ...中。

library(stringi)
library(dplyr)

data.frame(stri_locate_all_fixed(gene1, "GTG")) %>%
  mutate(condition = start %in% seq(1, nchar(gene), 3))

给出了:

#  start end condition
#1     4   6      TRUE

如果您想将其概括为基因列表,您可以这样做:

lst <- list(gene1, gene2, gene3)

res <- lapply(lst, function(x) { 
  data.frame(stri_locate_all_fixed(x, "GTG")) %>% 
    mutate(condition = start %in% seq(1, nchar(x), 3))
})

哪会给:

#[[1]]
#  start end condition
#1     4   6      TRUE
#
#[[2]]
#  start end condition
#1    NA  NA     FALSE
#
#[[3]]
#  start end condition
#1     3   5     FALSE
#2     9  11     FALSE
#3    21  23     FALSE
#4    70  72      TRUE
#5    75  77     FALSE

根据@ Sobrique的评论,如果除以长度表示出现的数量除以条件除以每个基因中的char总数,您可以这样做:

lapply(1:length(res), function(x) sum(res[[x]][["condition"]]) / nchar(lst[[x]]))

哪会给:

#[[1]]
#[1] 0.004830918
#
#[[2]]
#[1] 0
#
#[[3]]
#[1] 0.003021148

答案 1 :(得分:1)

这是一个Perl解决方案,可以按照您的要求进行操作

但我不明白你的示例输出是如何派生的:第一个和最后一个序列在你需要的位置只有一次出现1 / 207,第二个序列根本没有。{这意味着输出分别为0 / 741 / 3313。这些都不像你说的那样6.3use strict; use warnings 'all'; print "Gene Frequency\n"; my $name; local $/ = '>'; while ( <> ) { chomp; next unless /\S/; my ($name, $seq) = split /\n/, $_, 2; $seq =~ tr/A-Z//cd; my $n = 0; while ( $seq =~ /(?=GTG)/g ) { ++$n if $-[0] % 3 == 0; } printf "%-7s%.6f\n", $name, $n / length($seq); }

此程序需要输入文件的路径作为命令行上的参数

Gene   Frequency
Gene1  0.004831
Gene2  0.000000
Gene3  0.003021

输出

{{1}}

答案 2 :(得分:0)

嗯,你有一个R解决方案。我在perl中一起攻击了一些东西,因为你标记了它:

#!/usr/bin/env perl
use strict;
use warnings;

my $target = 'GTG'; 

local $/ = "\n>"; 
while ( <> ) {
    my ($gene) = m/(Gene\d+)/;  
    my @hits = grep { /^$target$/ } m/ ( [GTCA]{3} ) /xg;
    print "$gene: ".( scalar @hits), "\n";
}

虽然不会提供与输入相同的结果:

Gene1: 1
Gene2: 0
Gene3: 1

我正在将你的字符串分解为3个元素列表,并寻找特别匹配的字符串。 (而且我没有按长度划分,因为我不完全清楚这是字母中的实际字符串长度,还是其他一些指标)。

包括长度匹配 - 我们需要同时捕获名称和字符串:

#!/usr/bin/env perl
use strict;
use warnings;

local $/ = "\n>";
while (<>) {
   my ($gene, $gene_str) = m/(Gene\d+)\n([GTCA]+)/m;
   my @hits = grep { /^GTG$/ } $gene_str =~ m/ ( [GTCA]{3} ) /xg;   

   print "$gene: " .  @hits . "/". length ( $gene_str ), " = ", @hits / length($gene_str), "\n";

}

我们使用<>这是'魔术'文件句柄,并告诉perl从读取 STDIN或在命令行上指定的文件。很像sedgrep

输入您的信息:

Gene1: 1/207 = 0.00483091787439614
Gene2: 0/74 = 0
Gene3: 1/331 = 0.00302114803625378

答案 3 :(得分:0)

这是一种不使用模式匹配的替代解决方案。并不重要。

.validate()

输出:

use strict;
use warnings;

my $gene;
while ( my $line = <> ) {
    if ( $line =~ /^>(.+)/ ) {
        $gene = $1;
        next;
    }

    chomp $line;

    printf "%s: %s\n", 
        $gene, 
        ( grep { $_ eq 'GTG' } split /(...)/, $line ) / length $line;
}

它基本上类似于Sobrique的答案,但假设基因系列包含正确的字符。它将基因字符串拆分为三个字符的列表,并采用字面上Gene1: 0.00483091787439614 Gene2: 0 Gene3: 0.00302114803625378 的字符串。

分裂通过滥用GTG使用模式作为分隔符的事实来工作,并且如果使用捕获组,它也将捕获分隔符。这是一个例子。

split

空元素会被my @foo = split /(...)/, '1234567890'; p @foo; # from Data::Printer __END__ [ [0] "", [1] 123, [2] "", [3] 456, [4] "", [5] 789, [6] 0 ] 过滤掉。它可能不是最有效的方式,但它可以完成工作。

您可以通过调用grep来运行它。

答案 4 :(得分:0)

这是我根据您的要求创建的功能。我很确定有比这更好的替代方法,但这解决了这个问题。

require(stringi)

input_gene_list<- list(gene1= "GTGGGGGTTTGTGGGGGTG", gene2= "GTGGGGGTTTGTGGGGGTG", gene3= "GTGGGGGTTTGTGGGGGTG")

gene_counter<- function(gene){
      x<- gene
      y<- gsub(pattern = "GTG",replacement =  "GTG ", x = x, perl=TRUE)

      if(str_count(y,pattern = "GTG")) {

        gene_count<- unlist(gregexpr(pattern = " ", y))

          counter<- 0
          for(i in 1:length(gene_count)){
            if((gene_count[i] %% 3) == 1) counter=counter+1
          }
          return(counter/nchar(x))
        }
}


output_list<- lapply(input_gene_list, function(x) gene_counter(x))

result<- t(as.data.frame(output_list))
  

结果

           [,1]
gene1 0.1052632
gene2 0.1052632
gene3 0.1052632

也分享你对它的看法!谢谢!