通过合并多个文件来创建表

时间:2016-10-10 01:00:32

标签: perl file merge

这看起来很简单,但令我难以置信。

我有文字文件,每种文件以一种组织命名(例如cortex.txtheart.txt

每个文件包含两列,列标题为gene_nameexpression_value

每个文件包含大约30K到40K行

我需要将文件合并到一个包含29列的文件中,标题为

genename, tissue1, tissue2, tissue3, etc. to tissue28

这样每行包含一个基因及其在28个组织中的表达值

以下代码创建一个数组,其中包含每个文件中每个基因名称的列表:

my @list_of_genes;

foreach my $input_file ( @input_files ) {

    print $input_file, "\n";

    open ( IN, "outfiles/$input_file");

    while ( <IN> ) {

        if ( $_ =~ m/^(\w+\|ENSMUSG\w+)\t/) {

            # check if the gene is already in the gene list
            my $count = grep { $_ eq $1 } @list_of_genes;

            # if not in list, add to the list
            if ( $count == 0 ) {
                push (@list_of_genes, $1);
            }
        }
    }

    close IN;
}

我希望下一段代码可以使用,但正则表达式只识别第一个基因名称。

注意:我只在一个名为&#34; tissue1.txt&#34;的测试文件上进行测试。

想法是创建一个包含所有文件名的数组,然后依次获取每个基因名称并搜索每个文件以提取每个值,并按行顺序将其写入outfile。

foreach my $gene (@list_of_genes) {

    # print the gene name in the first column
    print OUT $gene, "\t";

    # use the gene name to search the first element of the @input_file array and dprint to the second column
    open (IN, "outfiles/tissue1.txt");

       while ( <IN> ) { 

        if ($_ =~ m/^$gene\t(.+)\n/i ) {
            print OUT $1;
        }

    }

    print OUT "\n";
}

编辑1: 谢谢鲍罗丁。您的代码输出确实是每个基因名称的列表,每个组织中都包含所有表达值。

e.g。 Bcl20 | ENSMUSG00000000317,0.815796340254127,0.815796340245643

这比我管理的好多了谢谢你。还需要做两件事。

1)如果在.txt文件中找不到基因名称,则应记录值0

e.g。 Ht4 | ENSMUSG00000000031,4.75878049632381,0

2)我需要一个逗号分隔的标题行,以便每个值来自的组织仍然与值相关联(基本上是一个表) - 组织是文本文件的名称

e.g。从2个文件heart.txt和liver.txt开始,第一行应该是:

genename | ID,心脏,肝脏

其中genename | id始终是第一个标题

1 个答案:

答案 0 :(得分:1)

这是一个很多代码,用于实现使用哈希来强制唯一性的简单习惯用法!

您希望ENSMUSG目录中所有*.txt个文件中的每个不同outfiles字符串都需要一组表达式值

如果您需要的文件是outfles目录中唯一的文件,则解决方案如下所示。我已使用autodie检查所有Perl IO操作的返回状态(chdiropenprint等),并仅检查{{1} } value包含$gene。如果输入数据表现良好,您甚至可能不需要检查。

如果有错误,请原谅我,因为我目前无法访问Perl编译器。我已经通过视线检查了它看起来很好。

|ENSMUSG