确定列表中的平均值、stdev、stderror 和值计数

确定列表中的平均值、stdev、stderror 和值计数

我有一个名为 的文本文件data.txt,包含 2 列和 80,667 行。前 20 行是,代表所有行:

  Column A     Column B

ACKR1/CCRL2     12.66
ACKR1/CMKLR1    10.41
ACKR1/CXCR4     13.01
ACKR1/FZD5      10.72
ACKR1/GPR107    10.22
ACKR1/GPR137    10.73
ACKR1/GPR146    11.93
ACKR1/TAPT1     11.24
ACKR1/TPRA1     11.81
ACKR1/XPR1      10.01
ACKR2/ACKR3     9.36
ACKR2/ACKR3     10.48
ACKR2/ACKR3     11.08
ACKR2/ACKR3     11.11
ACKR2/ACKR3     11.38
ACKR2/ACKR3     11.73
ACKR2/ACKR3     12.97
ACKR2/ADGRA2    8.68
ACKR2/ADGRA2    9.03
ACKR2/ADGRA2    9.34

正如您所看到的,A 列中有一些重复的值(例如 ACKR2/ACKR3、ACKR2/ADGRA2)。我想要做的是创建另一个文件,results.txt其中包含唯一值的平均值、标准偏差和标准误差,以及它们在data.txt.例如:

   Value         Avg    Stdev    StdErr    Count

ACKR1/CCRL2     12.66    -         -         1
ACKR1/CMKLR1    10.41    -         -         1
ACKR1/CXCR4     13.01    -         -         1
ACKR1/FZD5      10.72    -         -         1
ACKR1/GPR107    10.22    -         -         1
ACKR1/GPR137    10.73    -         -         1
ACKR1/GPR146    11.93    -         -         1
ACKR1/TAPT1     11.24    -         -         1 
ACKR1/TPRA1     11.81    -         -         1
ACKR1/XPR1      10.01    -         -         1
ACKR2/ACKR3     11.46   0.84      0.35       7
ACKR2/ADGRA2    8.69    0.33      0.19       3

我不太分阶段地获得标准差和标准误差,但至少获得一个就很好了。

我是一名生物学家,所以我不太擅长编写 UNIX 脚本。我真的不知道从哪里开始,任何帮助将不胜感激。抱歉,如果以前已经回答过类似的问题,我搜索过但找不到任何内容。

非常感谢!

答案1

不确定 Stdev 和 Sterr 的计算。但使用这个方法,你可以很容易地计算出来

$ awk '{A[$1]++;B[$1]+=$2}END{print "Value\t\tAvg\tCount";for (i in A){print i"\t"B[i]/A[i]"\t"A[i]}}' input.txt
Value           Avg     Count
ACKR2/ADGRA2    9.01667 3
ACKR1/GPR107    10.22   1
ACKR1/XPR1      10.01   1
ACKR1/CMKLR1    10.41   1
ACKR1/CCRL2     12.66   1
ACKR1/GPR146    11.93   1
ACKR1/GPR137    10.73   1
ACKR1/CXCR4     13.01   1
ACKR2/ACKR3     11.1586 7
ACKR1/TPRA1     11.81   1
ACKR1/FZD5      10.72   1
ACKR1/TAPT1     11.24   1

awk '{
A[$1]++;B[$1]+=$2
}
END
{
print "Value\t\tAvg\tCount";
for (i in A)
{
print i"\t"B[i]/A[i]"\t"A[i]
}
}'  input.txt

答案2

因为我没有空闲的时间,而且我(显然)永远不会抽出时间来awk正确学习,所以我只是一起写这篇文章,看看我是否能够用 Python 解决它。

没有从@Kamaraj 那里拿走任何东西awk(我投了赞成票)。

#!/usr/bin/env python3

colDict = {}  

with open ("cols") as infile: # Open the file
    for line in infile: # Read line by line
        splitLine = line.split() # Split line into list
        if splitLine[0] not in colDict: # Is value _not_ already in dict?
            value = splitLine[0] # Create new value
            colDict[value] = {} # Create nested dict
            colDict[value]["Avg"] = float(splitLine[1]) # Insert 'avg' 
            colDict[value]["Count"] = 1 # Insert count
        else: # Value _is_ in dict
            colDict[value]["Avg"] += float(splitLine[1]) # Add 'avg' float value
            colDict[value]["Count"] += 1 # Increment counter

print("Value\t\tAvg\tCount")
for value in sorted(colDict):
    print("{0}\t{1:.2f}\t{2}".format(value, 
                              colDict[value]["Avg"]/colDict[value]["Count"],
                              colDict[value]["Count"]))

执行后:

./parseCols.py
Value           Avg     Count
ACKR1/CCRL2     12.66   1   
ACKR1/CMKLR1    10.41   1   
ACKR1/CXCR4     13.01   1   
ACKR1/FZD5      10.72   1   
ACKR1/GPR107    10.22   1   
ACKR1/GPR137    10.73   1   
ACKR1/GPR146    11.93   1   
ACKR1/TAPT1     11.24   1   
ACKR1/TPRA1     11.81   1   
ACKR1/XPR1      10.01   1   
ACKR2/ACKR3     11.16   7   
ACKR2/ADGRA2    9.02    3  

输出的唯一区别是我的输出已排序(在Value)并且我将其四舍五入Avg为两位小数。

再次;感谢@Kamaraj 在 中编写了如此紧凑的解决方案awk

相关内容