免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 5476 | 回复: 18
打印 上一主题 下一主题

对多个文件求平均 [复制链接]

论坛徽章:
8
技术图书徽章
日期:2013-08-22 11:21:28未羊
日期:2015-01-19 22:22:25巳蛇
日期:2014-08-11 16:53:08子鼠
日期:2014-05-29 09:04:44摩羯座
日期:2014-04-11 14:15:07丑牛
日期:2014-01-24 12:41:28金牛座
日期:2013-11-21 17:38:28射手座
日期:2015-01-21 08:50:32
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-08-18 16:23 |只看该作者 |倒序浏览
30可用积分
本帖最后由 huang6894 于 2014-08-18 16:26 编辑

还有一个问题。。。。对于N个以下的文本,我需要对第2、4、7列相同的第5列求平均值并作分析,想问一下应该怎么优化我的代码~

这N个文件的顺序格式都是一样的,不过每个文件在100M左右,每个文件里面的每一行都是唯一的。第2、第4列是位置信息,第3列则是区域信息,第四列是该区域的每个点,区域文件存放在文件ref上,第7列是正负信息,第5列则是对应的质量值。
设定第6列是质控值,用200除以该值得到权重,求平均时需要把第五列先乘以该权重才是他的真实质量值,每个文件的权重是唯一的。
目的是计算每个位置在所有文本中的平均值,然后分析假如某文件某行的数值小于0.5倍平均值的话,输出该行。。。。
文本:

  1. ==> head -6 result_for_depth.13B0005773.1408345911.txt result_for_depth.13B0005805.1408342063.txt result_for_depth.13B0013031.1408342008.txt result_for_depth.13B0013194.1408342004.txt

  2. ==> result_for_depth.13B0005773.1408345911.txt <==
  3. 13B0005773      chr1    2336191-2337323 2336191 55      123     +
  4. 13B0005773      chr1    2336191-2337323 2336191 16      123     -
  5. 13B0005773      chr1    2336191-2337323 2336192 52      123     +
  6. 13B0005773      chr1    2336191-2337323 2336192 16      123     -
  7. 13B0005773      chr1    2336191-2337323 2336193 52      123     +
  8. 13B0005773      chr1    2336191-2337323 2336193 16      123     -

  9. ==> result_for_depth.13B0005805.1408342063.txt <==
  10. 13B0005805      chr1    2336191-2337323 2336191 54      119     +
  11. 13B0005805      chr1    2336191-2337323 2336191 11      119     -
  12. 13B0005805      chr1    2336191-2337323 2336192 50      119     +
  13. 13B0005805      chr1    2336191-2337323 2336192 11      119     -
  14. 13B0005805      chr1    2336191-2337323 2336193 50      119     +
  15. 13B0005805      chr1    2336191-2337323 2336193 11      119     -

  16. ==> result_for_depth.13B0013031.1408342008.txt <==
  17. 13B0013031      chr1    2336191-2337323 2336191 51      118     +
  18. 13B0013031      chr1    2336191-2337323 2336191 14      118     -
  19. 13B0013031      chr1    2336191-2337323 2336192 47      118     +
  20. 13B0013031      chr1    2336191-2337323 2336192 14      118     -
  21. 13B0013031      chr1    2336191-2337323 2336193 47      118     +
  22. 13B0013031      chr1    2336191-2337323 2336193 15      118     -

  23. ==> result_for_depth.13B0013194.1408342004.txt <==
  24. 13B0013194      chr1    2336191-2337323 2336191 49      117     +
  25. 13B0013194      chr1    2336191-2337323 2336191 13      117     -
  26. 13B0013194      chr1    2336191-2337323 2336192 43      117     +
  27. 13B0013194      chr1    2336191-2337323 2336192 13      117     -
  28. 13B0013194      chr1    2336191-2337323 2336193 43      117     +
  29. 13B0013194      chr1    2336191-2337323 2336193 13      117     -
复制代码
文件ref:

  1. chr1    2336191    2337323
复制代码
我的代码:

  1. die "-- must set depth_dir and ref_bed --\n" if (@ARGV < 2);
  2. my $dir = $ARGV[0];
  3. my $bed = $ARGV[1];
  4. my(%dep,%sam,%f,%p);
  5. my @allfile=glob "$ARGV[0]/result_for_depth.*.txt";
  6. foreach my $file(@allfile){
  7.         open FILE,$file;
  8.         while(<FILE>){
  9.                 chomp;
  10.                  my ($sample, $chr, $pos, $dep, $qc, $stand) = (split /\t/,$_)[0,1,3,4,5,6];
  11.                  my $depth = $dep * 200/$qc;
  12.                  my $yu = $pos.$stand;
  13.                  $dep{$chr}{$yu}+=$depth;
  14.                  $sam{$file}{$chr}{$yu}=$depth;
  15.                  $f{$file}{$chr}{$pos}="$sample\t$chr\t$pos";
  16.          }
  17.          close FILE;
  18. }

  19. foreach my $file(@allfile){
  20.         open OUT,"> $file.cnv.result" || die "$!";
  21.         open BED,"$bed" or die "$!";
  22.         while(<BED>){
  23.                 chomp;
  24.                 my ($chr, $pos1, $pos2) = (split /\t/,$_)[0,1,2];
  25.                 for my $pos ($pos1 .. $pos2){
  26.                         my $y = $pos."+";
  27.                         my $t = $pos."-";
  28.                         my $mean1 = int(($dep{$chr}{$y}/$#allfile)+1);
  29.                         my $mean2 = int(($dep{$chr}{$t}/$#allfile)+1);
  30.                         if(($sam{$file}{$chr}{$y}<=0.5*$mean1)&&($sam{$file}{$chr}{$t}<=0.5*$mean2)){               
  31.                                 print OUT "$f{$file}{$chr}{$pos}\n";
  32.                         }
  33.                   }
  34.             }
  35. }


复制代码

最佳答案

查看完整内容

全读入hash么....要省内存,sort然后while(){}就好。然后

论坛徽章:
1
程序设计版块每日发帖之星
日期:2015-10-07 06:20:00
2 [报告]
发表于 2014-08-18 16:23 |只看该作者
本帖最后由 chenhao392 于 2014-08-20 06:06 编辑

全读入hash么....要省内存,sort然后while(<>){}就好。
  1. cat result_for_depth*txt | sort -k2 -k4n -k7 >working_file.bed
复制代码
然后
  1. #!/usr/bin/perl

  2. use strict;
  3. use warnings;


  4. my $pattern='';
  5. my %hash;
  6. my @f_score;
  7. my @r_score;

  8. open FILE, "<$ARGV[0]" or die "$. $!\n";
  9. while(<FILE>){
  10.     chomp;
  11.     my ($sample, $chr, undef, $pos, $dep, $qc, $strand)=split(/\s+/,$_);
  12.     if($pattern ne "$chr$pos"){
  13.         $pattern = $chr.$pos;
  14.         if($. >1){
  15.             &flush();
  16.         }
  17.     }
  18.     else{
  19.     }

  20.     my $score=$dep*200/$qc;
  21.     if($strand eq '+'){
  22.         push @f_score,$score;
  23.         push @{$hash{'+'}},"$sample\t$chr\t$pos\t$score";
  24.     }
  25.     else{
  26.         push @r_score,$score;
  27.         push @{$hash{'-'}},"$sample\t$chr\t$pos\t$score";
  28.     }
  29. }
  30. close FILE;

  31. &flush();




  32. sub flush{
  33.     my $f_mean=mean(@f_score);
  34.     my $r_mean=mean(@r_score);
  35.     my %mem;
  36.     foreach my $slide(@{$hash{'+'}}){
  37.         my ($sample,$chr,$pos,$score)=split(/\t/,$slide);
  38.         if($score >= 0.5*$f_mean){
  39.             $mem{"$sample\t$chr\t$pos"}="";
  40.         }
  41.     }
  42.     foreach my $slide(@{$hash{'-'}}){
  43.         my ($sample,$chr,$pos,$score)=split(/\t/,$slide);
  44.         if($score >= 0.5*$r_mean && defined $mem{"$sample\t$chr\t$pos"}){
  45.             print "$sample\t$chr\t$pos\n";
  46.         }
  47.     }

  48.     %mem=();
  49.     @f_score=();
  50.     @r_score=();
  51.     %hash=();
  52. }

  53. sub mean{
  54.     my $sum;
  55.     foreach(@_){
  56.         $sum+=$_;
  57.     }
  58.     return $sum/($#_+1);
  59. }
复制代码
  1. perl tt.pl working_file.bed
  2. 13B0005805        chr1        2336191
  3. 13B0013194        chr1        2336191
  4. 13B0013031        chr1        2336191
  5. 13B0005773        chr1        2336191
  6. 13B0005805        chr1        2336192
  7. 13B0013194        chr1        2336192
  8. 13B0013031        chr1        2336192
  9. 13B0005773        chr1        2336192
  10. 13B0005805        chr1        2336193
  11. 13B0013194        chr1        2336193
  12. 13B0013031        chr1        2336193
  13. 13B0005773        chr1        2336193
复制代码

论坛徽章:
5
丑牛
日期:2014-01-21 08:26:26卯兔
日期:2014-03-11 06:37:43天秤座
日期:2014-03-25 08:52:52寅虎
日期:2014-04-19 11:39:48午马
日期:2014-08-06 03:56:58
3 [报告]
发表于 2014-08-18 18:32 |只看该作者
优化下 ~ {:2_172:}
            my $mean2 = int( ( $dep{$chr}{$t} / $#allfile ) + 1 );

$#allfile: index ==> count - 1
@allfile: count
  1. #!/usr/bin/perl

  2. die "-- must set depth_dir and ref_bed --\n" if ( @ARGV < 2 );
  3. my $dir = $ARGV[0];
  4. my $bed = $ARGV[1];
  5. my ( %dep, %sam, %f, %p );
  6. my @allfile = glob "$ARGV[0]/result_for_depth.*.txt";

  7. foreach my $file (@allfile) {
  8.     open FILE, $file;
  9.     while (<FILE>) {
  10.         my ( $sample, $chr, undef, $pos, $dep, $qc, $stand ) = split;
  11.         my $depth = $dep * 200 / $qc;
  12.         my $yu    = $pos . $stand;
  13.         $dep{$chr}{$yu} += $depth;
  14.         $sam{$file}{$chr}{$yu} = $depth;
  15.         $f{$file}{$chr}{$pos}  = "$sample\t$chr\t$pos";
  16.     }
  17.     close FILE;
  18. }

  19. open BED, "$bed" or die "$!";
  20. my @BED = map [split], <BED>;

  21. foreach my $file (@allfile) {
  22.     open OUT, "> $file.cnv.result" || die "$!";
  23.     for (@BED) {
  24.         my ( $chr, $pos1, $pos2 ) = @$_;
  25.         for my $pos ( $pos1 .. $pos2 ) {
  26.             my $y     = $pos . "+";
  27.             my $t     = $pos . "-";
  28.             
  29.             # $#allfile: index, @allfile: count
  30.             my $mean1 = int( ( $dep{$chr}{$y} / $#allfile ) + 1 );
  31.             my $mean2 = int( ( $dep{$chr}{$t} / $#allfile ) + 1 );
  32.             if (   ( $sam{$file}{$chr}{$y} <= 0.5 * $mean1 )
  33.                 && ( $sam{$file}{$chr}{$t} <= 0.5 * $mean2 ) )
  34.             {
  35.                 print OUT "$f{$file}{$chr}{$pos}\n";
  36.             }
  37.         }
  38.     }
  39. }

复制代码

论坛徽章:
8
技术图书徽章
日期:2013-08-22 11:21:28未羊
日期:2015-01-19 22:22:25巳蛇
日期:2014-08-11 16:53:08子鼠
日期:2014-05-29 09:04:44摩羯座
日期:2014-04-11 14:15:07丑牛
日期:2014-01-24 12:41:28金牛座
日期:2013-11-21 17:38:28射手座
日期:2015-01-21 08:50:32
4 [报告]
发表于 2014-08-18 19:54 |只看该作者
回复 2# pitonas


    嗯嗯,谢谢pitonas大大,我研究一下

论坛徽章:
8
技术图书徽章
日期:2013-08-22 11:21:28未羊
日期:2015-01-19 22:22:25巳蛇
日期:2014-08-11 16:53:08子鼠
日期:2014-05-29 09:04:44摩羯座
日期:2014-04-11 14:15:07丑牛
日期:2014-01-24 12:41:28金牛座
日期:2013-11-21 17:38:28射手座
日期:2015-01-21 08:50:32
5 [报告]
发表于 2014-08-19 10:02 |只看该作者
回复 2# pitonas


    大神。。。程序死掉了,6G内存跑不了。。。。

论坛徽章:
5
丑牛
日期:2014-01-21 08:26:26卯兔
日期:2014-03-11 06:37:43天秤座
日期:2014-03-25 08:52:52寅虎
日期:2014-04-19 11:39:48午马
日期:2014-08-06 03:56:58
6 [报告]
发表于 2014-08-19 14:59 |只看该作者
我不知道它是否可以改写?
我是文盲, 看不懂问题. 我做不到了....


非常抱歉 ~ {:2_168:}

回复 4# huang6894


   

论坛徽章:
8
技术图书徽章
日期:2013-08-22 11:21:28未羊
日期:2015-01-19 22:22:25巳蛇
日期:2014-08-11 16:53:08子鼠
日期:2014-05-29 09:04:44摩羯座
日期:2014-04-11 14:15:07丑牛
日期:2014-01-24 12:41:28金牛座
日期:2013-11-21 17:38:28射手座
日期:2015-01-21 08:50:32
7 [报告]
发表于 2014-08-19 15:33 |只看该作者
本帖最后由 huang6894 于 2014-08-19 15:34 编辑

回复 5# pitonas


    好吧,我又错了。。。。。

我修改了一下:
不过还在测试。。。希望有好运气吧。。。
  1. die "-- must set depth_dir and ref_bed --\n" unless (-d $ARGV[0] );
  2. my $dir = $ARGV[0];
  3. my %dep;
  4. my @allfile = glob "$dir/result_for_depth.*.txt";

  5. foreach my $file (@allfile) {
  6.         my $line;
  7.         open FILE, $file;
  8.         while (<FILE>) {
  9.                 chomp;
  10.                 my ( $sample, $chr, undef, $pos, $depth, $stand ) = split;#输入文件修改了,在原有的基础上做了权重校正,这里去掉了$qc
  11.                 push @{$dep{$line}{R}},[$sample,$depth];#因为所有文件的每一行的key都是一样的
  12.                 $dep{$line}{$sample}=[ $sample, $chr, $pos, $depth, $stand ];
  13.                 $line ++;
  14.                }
  15.                close FILE;
  16. }

  17. open OUT,"> $dir/all_cnv_result";
  18. while ( my ( $k, $v ) = each %dep ) {
  19.         my @tmp = @{ $v->{R} };
  20.         my ($a,@R);
  21.         for my $t (@tmp) {
  22.                  $a += $t->[1];
  23.                  push @R,$t->[0];
  24.         }
  25.         my $mean = $a/($#allfile+1);
  26.         for my $R (@R) {
  27.                 my ( $A, $B, $C, $D, $E ) = @{ $v->{ $R } };
  28.                 if($D <= 0.45*$mean){
  29.                         print OUT "$A\t$B\t$C\t$D\t$E\t$mean\tdel\n";
  30.                 }
  31.         }
  32. }
  33. close OUT;
复制代码

论坛徽章:
5
丑牛
日期:2014-01-21 08:26:26卯兔
日期:2014-03-11 06:37:43天秤座
日期:2014-03-25 08:52:52寅虎
日期:2014-04-19 11:39:48午马
日期:2014-08-06 03:56:58
8 [报告]
发表于 2014-08-19 15:41 |只看该作者
  1.                 # chomp; # don't do this !! it's stupid!!
  2.                 my ( $sample, $chr, undef, $pos, $depth, $stand ) = split;
复制代码
回复 6# huang6894


   

论坛徽章:
8
技术图书徽章
日期:2013-08-22 11:21:28未羊
日期:2015-01-19 22:22:25巳蛇
日期:2014-08-11 16:53:08子鼠
日期:2014-05-29 09:04:44摩羯座
日期:2014-04-11 14:15:07丑牛
日期:2014-01-24 12:41:28金牛座
日期:2013-11-21 17:38:28射手座
日期:2015-01-21 08:50:32
9 [报告]
发表于 2014-08-19 15:42 |只看该作者
回复 7# pitonas


    哦。。。好的

论坛徽章:
32
处女座
日期:2013-11-20 23:41:20双子座
日期:2014-06-11 17:20:43戌狗
日期:2014-06-16 11:05:00处女座
日期:2014-07-22 17:30:47狮子座
日期:2014-07-28 15:38:17金牛座
日期:2014-08-05 16:34:01亥猪
日期:2014-08-18 13:34:25白羊座
日期:2014-09-02 15:03:55金牛座
日期:2014-11-10 10:23:58处女座
日期:2014-12-02 09:17:52程序设计版块每日发帖之星
日期:2015-06-16 22:20:002015亚冠之塔什干火车头
日期:2015-06-20 23:28:22
10 [报告]
发表于 2014-08-19 17:43 |只看该作者
回复 7# pitonas

why stupid?
   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP