我有一个名为 的文本文件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
!