使平均行具有相同的模式

使平均行具有相同的模式

我有一个巨大的表(10 列和 6000 行),只有当它们在第 3 列 (ko) 中具有相同的模式时,我才必须对所有行求平均值。我的表包含数字和字符串。

这是一个例子:

pvalue  padj    ko  pathway
17,14   0,01    ko00620 Pyruvatemetabolism
15,76   0,01    ko00620 Pyruvatemetabolism
13,22   0,00    ko00620 Pyruvatemetabolism
12,40   0,00    ko00051 Fructoseandmannosemetabolism
12,03   0,01    ko00051 Fructoseandmannosemetabolism

我想获得这样的东西

pvalue  padj    ko  pathway
15,38   0,01    ko00620 Pyruvatemetabolism
12,22   0,00    ko00051 Fructoseandmannosemetabolism

答案1

可能不是您正在寻找的答案,但不管怎样,这很有趣:

#!/usr/bin/env perl

use strict;
use warnings;

use DBI;

my $dbh = DBI->connect(
    'dbi:CSV:',
    undef, undef, {
        f_ext           => '.csv/r',
        csv_sep_char    => "\t",
        csv_quote_char  => undef,
        csv_escape_char => undef,
    }
);

my $sth = $dbh->prepare(
    'SELECT AVG(pvalue), AVG(padj), ko, pathway
    FROM data GROUP BY ko, pathway'
);
$sth->execute();

while ( my $row = $sth->fetchrow_arrayref ) {
    printf "%.2f\t%.2f\t%s\t%s\n", @$row;
}

$dbh->disconnect;

上面假设您的数据位于名为 的制表符分隔的 CSV 文件中data.csv

答案2

也许 GNUdatamash适合你:

$ datamash -H -g3,4 mean 1 mean 2 < file
GroupBy(ko) GroupBy(pathway)    mean(pvalue)    mean(padj)
ko00620 Pyruvatemetabolism  15,373333333333 0,0066666666666667
ko00051 Fructoseandmannosemetabolism    12,215  0,005

答案3

用 awk

awk '
    NR == 1 {print;next} 
    {
        n[$3]++
        val[$3] += $1
        adj[$3] += $2
        path[$3] = $4
    } 
    END {
        for (ko in n) 
            printf "%.2f %.2f %s %s\n", val[ko]/n[ko], adj[ko]/n[ko], ko, path[ko]
    }
' file | column -t

相关内容