zoukankan      html  css  js  c++  java
  • 【Perl示例】整合多个文件

    这个需求是在生信分析中几乎天天用到,各种语言都能实现,也都各有特点。这次以perl为例。

    已知

    文件CT-VS-CON.All.xls为全部蛋白表达矩阵及其差异分析结果。
    image.png

    文件Homo_sapiens.ko为蛋白KEGG注释结果。
    image.png

    文件Homo_sapiens.fa为蛋白鉴定数据库(有的序列以多行展示)。
    image.png

    需求

    将以上三表整合为一个表,输出需要的信息。
    image.png

    实现

    #! /usr/bin/perl -w
    use strict;
    
    =pod
        Description: combine table
        Author: 
        Created: 
        Version: 
    =cut
    
    use Getopt::Long;
    #use Bio::SeqIO;
    
    my ($exp,$ko,$fa,$help,$outdir);
    GetOptions(
            "exp:s" => $exp,
            "ko:s" => $ko,
            "fa:s" => $fa,
            "outdir:s" => $outdir,
            "help|?" => $help
    );
    $outdir ||= ".";
    
    if (!defined $exp || !defined $ko || !defined $fa || defined $help){
        die << "USAGE";
    description: combine table
    usage: perl $0 [options]
    options:
        -exp <file> *   all proteins expression matrix
        -ko <file> *    all proteins ko annotation table (protein=>ko)
        -fa <file>     all proteins sequence
        -outdir <path>     output directory, default is current directory "."
        -help|?     help information
    eg:
        perl $0 -exp a-VS-b.All.xls -ko All.ko -fa All.fa -outdir .
    USAGE
    }
    
    my %ko;
    open KO, "<$ko" or die $!;
    while(<KO>){
        chomp;
        if($_ =~ /^#/){next;}
        my @K=split/	/;
        if(defined $K[1]){
            $ko{$K[0]}=$K[1];
        }else{
            $ko{$K[0]}="-";
        }
    }
    close KO;
    
    my %hash;
    my $keys;
    open DB, "< $fa" or die $!;
    while(<DB>){
        chomp;
        if($_ =~ /^>(.*?)s/){  #非贪婪匹配
            $keys = $1;
        }else{
            $hash{$keys} .= $_;
        }
    }
    close DB;
    #foreach my $id(keys %hash){
    #    print "$id
    $hash{$id}
    ";
    #}
    
    my %exp;
    my ($ratio,$class,$des,$pvalue);
    open OUT, ">out.txt" or die $!;
    open EXP, "< $exp" or die $!;
    while(<EXP>){
        chomp;
        my @tmp=split/	/,$_;
        if($.==1){
            for(my $i=0;$i<=$#tmp;$i++){
                if($tmp[$i] =~ /ratio/i){$ratio=$i;}
                if($tmp[$i] =~ /pvalue/i){$pvalue=$i;}
                if($tmp[$i] =~ /class/i){$class=$i;}
                if($tmp[$i] =~ /Description/i){$des=$i;}
            }
        print OUT "Protein	ratio	pvalue	Class	Description	log2FC	KEGG	Sequence
    ";
        next;
        }
        $tmp[$class] =~ s/Non/None/;
        $exp{$tmp[0]}="$tmp[0]	$tmp[$ratio]	$tmp[$pvalue]	$tmp[$class]	$tmp[$des]	";
        $exp{$tmp[0]} .= log2($tmp[$ratio]);
    }
    close EXP;
    
    my ($kegg,$seq);
    foreach my $id (keys %exp){
        if(exists $ko{$id}){
            $kegg=$ko{$id};
        }else{
            $kegg="-";
        }
        if(exists $hash{$id}){
            $seq=$hash{$id};
        }else{$seq="-";}
        print OUT "$exp{$id}	$kegg	$seq
    ";
    }
    close OUT;
    ############################
    # subroutine
    ############################
    sub log2 {
        my $n = shift;
        return log($n)/log(2);
    }
    

    Perl编写的特点是only write,条条大道通罗马,高手也许几行就能解决,我这里写得有点冗余,但有些是不能省的,目的是为了更规范化,便于维护和他人阅读。

  • 相关阅读:
    D365FO Debug找不到w3cp进程
    D365FO 10.0PU32 开发环境 Data Management导出失败
    一张图看懂项目管理
    用户体验为什么重要?如何提升产品的用户体验?(写给产品小白)
    敏捷考证?你应该知道的敏捷体系认证(最全名单)
    漫画:禅道程序员的一天
    敏捷开发管理--任务分解经验之谈
    漫画:优秀程序员的必备特质有哪些?
    漫画:女生/男生告白攻略
    漫画:程序员脱单秘籍
  • 原文地址:https://www.cnblogs.com/jessepeng/p/12198853.html
Copyright © 2011-2022 走看看