免费注册 查看新帖 |

Chinaunix

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

多行时两两之间的皮尔森相关系数 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-05-09 10:21 |只看该作者 |倒序浏览
下面是皮尔森相关系数的计算代码,是我copy的。它只是求两行的系数值的,但是我想求n行两两之间的相关系数。不知道怎么办了。
  1. #!/usr/local/bin/perl -w
  2. @x=(110.869429,224.432417,135.254959,314.799695,59.180641,160.191048,52.39372,283.666241,186.943458,170.444396,156.968469,424.092255,108.10017,51.204317,156.07176075,114.350089,66.6382395,154.04725,109.046664,228.484335
  3. );
  4. @y=(17.327247,17.404148,18.458939,17.559107,16.760933,15.49883,16.692633,17.327166,18.539049,19.794257,16.585954,15.774536,18.639974,16.643166,17.98409575,15.085853,18.899189,15.530345,16.620445,14.616374
  5. );
  6. if($#x==$#y){
  7. $N = $#x;
  8. print "N = $N\n";
  9. $sum_sq_x = 0;
  10. $sum_sq_y = 0;
  11. $sum_coproduct = 0;
  12. $mean_x = $x[1];
  13. $mean_y = $y[1];
  14. for($i=2;$i<=$N;$i++){
  15.      $sweep = ($i - 1.0) / $i;
  16.      $delta_x = $x[$i] - $mean_x;
  17.      $delta_y = $y[$i] - $mean_y;
  18.      $sum_sq_x += $delta_x * $delta_x * $sweep;
  19.      $sum_sq_y += $delta_y * $delta_y * $sweep;
  20.      $sum_coproduct += $delta_x * $delta_y * $sweep;
  21.      $mean_x += $delta_x / $i;
  22.      $mean_y += $delta_y / $i;
  23. }
  24. $pop_sd_x = sqrt( $sum_sq_x );
  25. $pop_sd_y = sqrt( $sum_sq_y );
  26. $cov_x_y = $sum_coproduct;
  27. $correlation = $cov_x_y / ($pop_sd_x * $pop_sd_y);
  28. print "Calculate Pearson correlation euqals:\t$correlation\n";
  29. exit(0);
  30. }
  31. print "PASS!\n";
  32. exit(1);
复制代码

论坛徽章:
0
2 [报告]
发表于 2011-05-09 12:05 |只看该作者
n行兩兩之間的係數值 和 兩行之間的係數值有什麽關係

论坛徽章:
0
3 [报告]
发表于 2011-05-09 18:00 |只看该作者
回复 2# wind_ch


    我不知道呢。
我只想求n行中,所有每两行之间的系数值。
要是有10行,那么我就要求45个系数值。

论坛徽章:
0
4 [报告]
发表于 2011-05-09 20:26 |只看该作者
和你程序里面一样, n行的话把每行保存成一个数组, 这是一个组合的问题吧.

论坛徽章:
0
5 [报告]
发表于 2011-05-10 13:31 |只看该作者
回复 4# wind_ch


可是,这个对我来说还是很难。
我卡在这儿了。
我就是得到两两之间的系数值,并输出
a   b   0.5
a   c    -0.3
b    d    0.8

论坛徽章:
0
6 [报告]
发表于 2011-05-10 14:52 |只看该作者
本帖最后由 wind_ch 于 2011-05-11 09:29 编辑

假設你有10行數據, 每行保存進一個數組裏面, @arr1, @arr2 ... @arr10;
你可以每得到一個數組就把引用push到@data中去
把你處理兩行的程序寫成函數pearson

  1. use strict;

  2. sub pearson($){
  3.     my ($ref_a, $ref_b) = @_;
  4.     my @x = @{$ref_a};
  5.     my @y = @{$ref_b};

  6.     ...
  7. }

  8. my @data = (\@arr1, \@arr2, ... , \@arr10);
  9. for(my $i = 0;  $i < $#data; $i++){
  10.     for(my $j = $i + 1; $j <= $#data; $j++){
  11.         pearson($data[$i], $data[$j]);
  12.     }
  13. }   
复制代码

论坛徽章:
0
7 [报告]
发表于 2011-05-11 09:16 |只看该作者
回复 6# wind_ch
  1. #!/usr/local/bin/perl -w

  2. sub pearson($){
  3.         my ($ref_a,$ref_b) = @_;
  4.         my @x = @{$ref_a};
  5.         my @y = @{$ref_b};
  6.         my $N;
  7. if($#x==$#y){
  8. $N = $#x;
  9. print "N = $N\n";
  10. my $sum_sq_x = 0;
  11. my $sum_sq_y = 0;
  12. my $sum_coproduct = 0;
  13. my $mean_x = $x[1];
  14. my $mean_y = $y[1];
  15. for($i=2;$i<=$N;$i++){
  16.      $sweep = ($i - 1.0) / $i;
  17.      $delta_x = $x[$i] - $mean_x;
  18.      $delta_y = $y[$i] - $mean_y;
  19.      $sum_sq_x += $delta_x * $delta_x * $sweep;
  20.      $sum_sq_y += $delta_y * $delta_y * $sweep;
  21.      $sum_coproduct += $delta_x * $delta_y * $sweep;
  22.      $mean_x += $delta_x / $i;
  23.      $mean_y += $delta_y / $i;
  24. }
  25. $pop_sd_x = sqrt( $sum_sq_x );
  26. $pop_sd_y = sqrt( $sum_sq_y );
  27. $cov_x_y = $sum_coproduct;
  28. $correlation = $cov_x_y / ($pop_sd_x * $pop_sd_y);
  29. print "Calculate Pearson correlation euqals:\t$correlation\n";
  30. exit(0);
  31. }
  32. print "PASS!\n";
  33. exit(1);
  34. }

  35. open my $fh,"<","rece_test05.txt" or die "Error.\n";
  36. my $out_file = $file . ".out";
  37. open WFH,">",$out_file or die "Cannot open $out_file : $!\n";


  38. my @data = (\@arr1, \@arr2, ... , \@arr500);
  39. for(my $i = 0;  $i < $#data; $i++){
  40.     for(my $j = $i + 1; $j <= $#data; $j++){
  41.         pearson($data[$i], $data[$j]);
  42.     }
  43. }   
复制代码
我的文件是这样的,并且有500行,太多了。
  1. LOC_Os04g46810.1         7.725284         7.728594         8.770031         9.910465         8.743908        10.332676
  2. LOC_Os12g38010.1         50.067357        17.339407        23.806961        18.379239        22.397611        18.687081
  3. LOC_Os10g31680.1         15.484767        14.557025        24.277390        22.325550        14.808402        21.870804
  4. LOC_Os12g38310.1         5.636056         4.594795          5.666566         5.314397          5.830249        6.089081       
  5. LOC_Os01g24560.1         7.853027         6.814309        11.343256         7.927583         9.649349        8.403233       
  6. LOC_Os11g24140.1         11.791185        16.645000        16.399312        17.516789        29.046365        24.098895
  7. LOC_Os10g31640.1         7.241884         6.794815         7.552480         8.329901         7.704593         11.929825
  8. LOC_Os07g01410.1         20.902209        20.462937        26.375332        19.077440        23.761116        24.877955
  9. LOC_Os10g18820.1          6.598861         8.858383         6.343684         7.583544         6.956356        8.908550       
  10. LOC_Os01g24550.1         17.682395        18.022256        23.544243        18.772425        15.611792        20.254603
复制代码
我不知道,怎么把每一行引入数组@arr1,@arr2,,,而且,还得$name1 = pop(@arr1),$name2 = pop (arr2),得到每一行的 名称。
我想输出的文件格式是
LOC_Os12g38010.1    LOC_Os04g46810.1  0.356489
既 $name1 $name2 $correlation
关键是有太多行

论坛徽章:
0
8 [报告]
发表于 2011-05-11 09:32 |只看该作者
這個你稍微看下書就能解決的

论坛徽章:
0
9 [报告]
发表于 2011-05-11 10:08 |只看该作者
回复 8# wind_ch


    这个也太难了吧,子程序的输出部分我不会,文件的读入我也不会,卡在这好难受啊

论坛徽章:
0
10 [报告]
发表于 2011-05-11 10:23 |只看该作者
本帖最后由 iamlimeng 于 2011-05-11 11:32 编辑
  1. #!/usr/bin/perl

  2. use strict;
  3. use warnings;
  4. my $file = "rece_test05";

  5. open (IN,"<$file.txt") or die "Error.\n";
  6. my @data = <IN>;
  7. close IN;
  8. chomp @data;
  9. my $out_file = $file . ".out";
  10. open (OUT,">$out_file.txt") or die "Cannot open $out_file : $!\n";
  11. my ($name1,$name2);
  12. foreach my $i (0..$#data-1){
  13.         foreach my $j($i+1..$#data) {
  14.                  my @line1 = split(/\s+/,$data[$i]);
  15.                  my @line2 = split(/\s+/,$data[$j]);
  16.                  $name1 = shift @line1;
  17.                  $name2 = shift @line2;
  18.                  pearson(\@line1,\@line2);
  19.          }
  20. }
  21. close OUT;

  22. sub pearson {
  23.     my ($ref_a, $ref_b) = @_;
  24.     my @x = @{$ref_a};
  25.     my @y = @{$ref_b};
  26.         if($#x==$#y){
  27.                  my $N = $#x;
  28.                  my $sum_sq_x = 0;
  29.                  my $sum_sq_y = 0;
  30.                  my $sum_coproduct = 0;
  31.                  my $mean_x = $x[1];
  32.                  my $mean_y = $y[1];
  33.                  for(my $i=2;$i<=$N;$i++){
  34.                           my $sweep = ($i - 1.0) / $i;
  35.                           my $delta_x = $x[$i] - $mean_x;
  36.                           my $delta_y = $y[$i] - $mean_y;
  37.                           $sum_sq_x += $delta_x * $delta_x * $sweep;
  38.                           $sum_sq_y += $delta_y * $delta_y * $sweep;
  39.                           $sum_coproduct += $delta_x * $delta_y * $sweep;
  40.                           $mean_x += $delta_x / $i;
  41.                           $mean_y += $delta_y / $i;
  42.                  }
  43.                  my $pop_sd_x = sqrt( $sum_sq_x );
  44.                  my $pop_sd_y = sqrt( $sum_sq_y );
  45.                  my $cov_x_y = $sum_coproduct;
  46.                  my $correlation = $cov_x_y / ($pop_sd_x * $pop_sd_y);
  47.                  print OUT "$name1 $name2: $correlation\n";
  48.         }
  49. }
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP