【问题标题】:How can I get the average and standard deviations grouped by key?如何获得按键分组的平均值和标准差?
【发布时间】:2010-11-27 15:09:15
【问题描述】:

我需要找到这种格式的大量数据的平均值和标准差。我尝试使用 Excel,但似乎没有一种简单的方法来转置列。我在 Excel 中缺少什么还是应该只使用 Perl?

输入文件格式为:

0 123

0 234

0 456

1 657

1234

1 543

希望结果按第一列中的值对平均值和标准差进行分组:

0 AvgOfAllZeros StdDevOfALlZeros

1 AvgOfAllOnes StdDevOfAllOnes

【问题讨论】:

  • Excel 有 TRANSPOSE 作为一个函数,可以将水平数组转换为垂直数组,反之亦然,或者您的意思是不是转置?
  • 如果只是加载查看数据透视表并选择 avg 或其他而不是表中的 sum

标签: perl excel statistics


【解决方案1】:

这在 R 中很容易做到。如果您的数据在一个名为 foo 的文件中,那么这段代码就可以解决问题:

> data <- read.table("foo")
> cbind(avg=with(data, tapply(V2, V1, mean)),
+       stddev=with(data, tapply(V2, V1, sd)))
  avg   stddev
0 271 169.5553
1 478 218.8630

【讨论】:

    【解决方案2】:

    裂纹的指关节

    使用Statistics::Descriptive CPAN 模块,您可以通过以下方式获得它:

    use strict;
    use warnings;
    use Statistics::Descriptive;
    
    my ($file) = @ARGV;
    
    my @zeroes;
    my @ones;
    
    # Reading it in
    open my $fh, '<', $file or die "unable to open '$file', $!";
    
    while (my $line = <$fh>)
    {
       chomp $line;
       my ($value, $number) = split("\s+", $line);
       if ($value)
       {
          push @ones, $number;
       }
       else
       {
          push @zeroes, $number;
       }
    }
    close $fh or warn "Can't close fh! $!";
    
    # Stat processing
    $stat_zeroes   = Statistics::Descriptive::Full->new();
    $stat_ones     = Statistics::Descriptive::Full->new();
    
    $stat_zeroes->add_data(@zeroes);
    $stat_ones->add_data(@ones);
    
    print "0: ", $stat_zeroes->mean(), " ", $stat_zeroes->standard_deviation(), "\n",
          "1: ", $stat_ones->mean(), " ", $stat_zeroes->standard_deviation(), "\n";
    

    【讨论】:

      【解决方案3】:

      如果您在 Excel 中手动执行此操作,您可以复制数据,然后使用“选择性粘贴”菜单选项将其粘贴。那里有一个转置复选框。

      如果您更频繁地这样做,这里有一个 Perl 脚本。内存复杂度与输出大小成线性关系,因此在只有两行的情况下保持不变:

      #!/usr/bin/perl
      
      while (<>) {
          my ($x, $y) = split;
          $sum{$x} += $y;
          $count{$x}++;
          $sumSq{$x} += $y * $y;
      }
      
      for $i (sort keys %sum) {
          $stdev = sqrt(($sumSq{$i} - $sum{$i} * $sum{$i} / $count{$i}) / ($count{$i} - 1));
          print $i, " ", $sum{$i}/$count{$i}, " ", $stdev, "\n";
      }
      

      【讨论】:

        【解决方案4】:

        可以使用Excel。有一个 AVERAGEIF 函数,但与 STDEV 没有相似之处,因此需要另一种两步法。

        可以通过在右侧添加带有公式的两列来“转置”数据。假设您的数据在 A 列和 B 列中,C 列中的公式将是;

        =IF(A2=0,B2,"")
        

        在 D 列中会是;

        =IF(A2=1,B2,"")
        

        然后新列可以在底部添加公式

        平均

        =AVERAGE(C2:C7)
        

        对于标准开发

        =STDEV(C2:C7)
        

        【讨论】:

          【解决方案5】:

          您是否尝试过使用 Excel 的 AVERAGEIF 函数?

          【讨论】:

            【解决方案6】:

            如果您处理大量数据,那么您应该考虑PDL... Perl 数据语言。

            请参阅this 相关的 SO 答案。

            【讨论】:

              【解决方案7】:

              我会使用 SUMIF 和 COUNTIF 公式。您必须添加一两列额外的列来获得平方偏差,以便计算出标准偏差。一个例子是这样的

              用B10中的公式 =SUMIF($A$2:$A$7,"="&A10,$B$2:$B$7)/COUNTIF($A$2:$A$7,"="&A10) 在 B11 =SQRT(SUMIF($A$2:$A$7,"="&A10,$D$2:$D$7)/COUNTIF($A$2:$A$7,"="&A10))

              【讨论】:

                猜你喜欢
                • 2016-03-11
                • 2020-12-26
                • 2013-05-22
                • 2020-06-24
                • 1970-01-01
                • 1970-01-01
                • 2014-03-21
                • 1970-01-01
                相关资源
                最近更新 更多