每行获取平均值

5
我有一个按此格式组织的大型数据集。
HF TLLL A T 0.999 NA 0.666 NA 0.566 NA NA 0.87
HF TLLM A T 0.500 0.500 0.666 0.566 NA NA 0.87

我想计算每行从第5列到行末的平均值,并忽略字符串NA。然后将平均值附加到每行的末尾。
输出如下:
HF TLLL A T 0.999 NA 0.666 NA 0.566 NA NA 0.87 0.775
HF TLLM A T 0.500 0.500 0.666 0.566 NA NA 0.87 0.620

我一直像这样计算总和,但是无法想出如何跟踪被求和的整数数量,以便计算平均值。

awk '{x=0;for(i=5;i<=NF;i++)x=x+$i;print $0, x}'

我假设你所说的“平均数”是指“算术平均数”。 “NA”是否算作零数据点,还是完全忽略? 这将影响每行数据点的数量,从而影响计算出的平均值。 - Digital Trauma
是的,我指的是算术平均数。NA应该被完全忽略。 - user1308144
我想知道为什么你在这个问题上被踩了。你提供了样例输入、期望输出、映射解释以及一种尝试解决问题的方案。就我而言,这是一个非常完美的问题! - Ed Morton
有人对这篇文章进行了负面评价。知道原因会更好。这篇文章写得很好,包括输入数据、期望输出和尝试解决问题。所以我点了赞。编辑:@EdMorton 你比我快几秒钟 :) - Jotne
@Jotne 的点赞好主意,我现在也已经这样做了。 - Ed Morton
同意。这是一个好问题,我也点赞了。(尽管根据我的评论需要稍作澄清)。我没有投反对票。 - Digital Trauma
3个回答

5
$ cat file
HF TLLL A T 0.999 NA 0.666 NA 0.566 NA NA 0.87
HF TLLM A T 0.500 0.500 0.666 0.566 NA NA 0.87
HF TLLM A T NA NA NA NA NA NA NA

$ awk '{sum=cnt=0; for (i=5;i<=NF;i++) if ($i != "NA") { sum+=$i; cnt++ } print $0, (cnt ? sum/cnt : "NA") }' file
HF TLLL A T 0.999 NA 0.666 NA 0.566 NA NA 0.87 0.77525
HF TLLM A T 0.500 0.500 0.666 0.566 NA NA 0.87 0.6204
HF TLLM A T NA NA NA NA NA NA NA NA

三元表达式避免了在输入行3上发生除以零错误的问题,因为每个数据字段都是“NA”。

1
在“0/0”检查中加上+1。当我写下s=n=0时,我想到了这一点,但在printf时忘记了... - Kent

1
kent$  awk '{s=n=0;for(i=5;i<=NF;i++)if($i!="NA"){s+=$i*1;n++}printf "%s %.3f\n",$0,s/n}' file
HF TLLL A T 0.999 NA 0.666 NA 0.566 NA NA 0.87 0.775
HF TLLM A T 0.500 0.500 0.666 0.566 NA NA 0.87 0.620

1
使用 awk,您可以这样做:
awk '{for (i=5;i<=NF;i++) {if ($i!="NA") t++;a+=$i}print $0,a/t;a=t=0}' file
HF TLLL A T 0.999 NA 0.666 NA 0.566 NA NA 0.87 0.77525
HF TLLM A T 0.500 0.500 0.666 0.566 NA NA 0.87 0.6204

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接