AWK:用重复条目替换不同的值(平均值)

时间:2016-05-11 17:45:30

标签: bash awk replace average

我有许多数据文件,其中每列代表一个唯一的样本,每行对应一个基因名称。以下是我的一个较小文件的示例:

MAPK3 9.49707613464767 9.34083460789419 9.12918870414545 
TIE1 5.12900020712651 5.15008091018047 5.15008091018047 
CYP2C19 3.80757247946463 3.80757247946463 3.87721584865861 
CXCR5 6.40745840005515 6.40745840005515 6.40745840005515 
CXCR5 6.04763929379884 6.13038198258514 6.13038198258514 
DUSP1 12.0320377077951 12.7960658385305 12.625340661444 
MMP10 4.1933379022831 4.1933379022831 4.1933379022831 
RXRG 4.33755505408386 4.32903686336417 4.32903686336417 
RXRG 6.91141485189572 6.96893082690402 6.96893082690402

请注意,在第一列中,基因名称CXCR5RXRG已被复制,但每个条目的值都不同。我需要的输出文件如下所示:

MAPK3 9.49707613464767 9.34083460789419 9.12918870414545 
TIE1 5.12900020712651 5.15008091018047 5.15008091018047 
CYP2C19 3.80757247946463 3.80757247946463 3.87721584865861 
CXCR5 6.22754884693 6.2689201913201 6.2689201913201
DUSP1 12.0320377077951 12.7960658385305 12.625340661444 
MMP10 4.1933379022831 4.1933379022831 4.1933379022831 
RXRG 5.6244849529898 5.6489838451341 5.6489838451341

将重复基因的值平均并替换每个样本的原始条目。此外,我想保持独特的基因名称和价值不变。需要明确的是,对于第1列中的每个重复基因名称,我不希望整行的平均值,而是每列的平均值。 我试图利用这里描述的聪明的awk单行,calculate and print the average value of strings in a columnAverage from different columns in shell script。但是我无法概括命令来解释我的文件,这些文件可能有多达100个样本/列。他们不必要地混淆了我独特的基因名称。

我的新手级编码技能将是我的死!有什么建议吗?

由于

3 个答案:

答案 0 :(得分:1)

Twilio.Device.setup(token, { debug: true }); // enable debug logging 救援!使用decorate / sort / undecorate模式来保持行的顺序相同。

awk

指定可以使用格式修饰符切换到$ awk '{f2[$1]+=$2; f3[$1]+=$3; f4[$1]+=$4; c[$1]++; r[$1]=NR} END{for(k in c) print r[k] "\t" k, f2[k]/c[k], f3[k]/c[k], f4[k]/c[k]}' file | sort -n | cut -f2 MAPK3 9.49708 9.34083 9.12919 TIE1 5.129 5.15008 5.15008 CYP2C19 3.80757 3.80757 3.87722 CXCR5 6.22755 6.26892 6.26892 DUSP1 12.032 12.7961 12.6253 MMP10 4.19334 4.19334 4.19334 RXRG 5.62448 5.64898 5.64898 的小数点数。

答案 1 :(得分:1)

我对awk很新,但这可能就行了(似乎对我有用)

#!/bin/awk -f

{
    for(i = 2; i <= 4; ++i)
        id[$1][i] = (id[$1][i] * num[$1] + $i) / (num[$1] + 1);
    ++num[$1]
}

END {
    for(key in num)
        printf "%s %.15g %.15g %.15g \n", key, id[key][2], id[key][3], id[key][4]
}

<强>输出:

$ cat test.txt|test.awk 
MMP10 4.1933379022831 4.1933379022831 4.1933379022831 
DUSP1 12.0320377077951 12.7960658385305 12.625340661444 
CYP2C19 3.80757247946463 3.80757247946463 3.87721584865861 
TIE1 5.12900020712651 5.15008091018047 5.15008091018047 
CXCR5 6.22754884692699 6.26892019132015 6.26892019132015 
RXRG 5.62448495298979 5.6489838451341 5.6489838451341 
MAPK3 9.49707613464767 9.34083460789419 9.12918870414545 

它使关联数组键入第一列名称并保持运行平均值。

答案 2 :(得分:1)

$ cat tst.awk
NR == 1 { CONVFMT="%."length($2)-index($2,".")"f" }
$1 != key { prt() }
{
    key=$1
    for (i=2 ; i<=NF ; i++) {
        sum[i] += $i
    }
    cnt++
}
END { prt() }

function prt() {
    if (key != "") {
        printf "%s", key
        for (i=2; i<=NF; i++) {
            printf "%s%s", OFS, sum[i] / cnt
        }
        print ""
    }
    delete sum
    cnt = 0
}

$ awk -f tst.awk file
MAPK3 9.49707613464767 9.34083460789419 9.12918870414545
TIE1 5.12900020712651 5.15008091018047 5.15008091018047
CYP2C19 3.80757247946463 3.80757247946463 3.87721584865861
CXCR5 6.22754884692699 6.26892019132015 6.26892019132015
DUSP1 12.03203770779510 12.79606583853050 12.62534066144400
MMP10 4.19333790228310 4.19333790228310 4.19333790228310
RXRG 5.62448495298979 5.64898384513410 5.64898384513410