如何通过考虑来自另一列的信息来计算列中值的平均值?

zar*_*ara 5 text-processing

文件1:

HOGBRM443983         -2522.00  19800826
HOGBRM445985         -2389.00  19801101
HOUSAM1891409        -1153.00  19811228
HOUSAM2004289        -650.00   19860101
HOUSAM2005991        -843.00   19860109
HOCANM388722         -1546.00  19860116
HOUSAM2007297        -1882.00  19860125
HOUSAM2007389        -1074.00  19860128
HOITAM801038516      -691.00   19860128
Run Code Online (Sandbox Code Playgroud)

第 2 列和第 3 列分别包含 column1 中每个 id 的值和生日信息(年、月、日)。我想检查每个出生年份存在多少个 id,以及不同年份 id 的平均值(来自第二列)是多少。例如,在 file1 中,1980、1981 和 1986 年分别有 2、1 和 6 个 ID,因此输出应为:

output:

1980 2 -2455.5
1981 1 -1153.00
1986 6 -114.33
Run Code Online (Sandbox Code Playgroud)

其中第一列显示出生年份,第二列显示每年的id数,第三列是不同年份的ids平均值。

考虑到真实数据确实很大,任何建议将不胜感激。

don*_*sti 7

gnu datamash

cut -c1-35 infile | datamash -W -g 3 count 3 mean 2
Run Code Online (Sandbox Code Playgroud)

请注意,您需要先处理您的数据(我使用cut它是您输入样本的明显选择,但任何工具都可以)以便从出生日期中删除月份和日期:

HOGBRM443983         -2522.00  1980
HOGBRM445985         -2389.00  1980
HOUSAM1891409        -1153.00  1981
HOUSAM2004289        -650.00   1986
......
Run Code Online (Sandbox Code Playgroud)

然后才通过管道将其传输到datamash.
这也假设第三列按年份排序(如果没有排序使用datamash -s -W -g ...


Wil*_*ard 5

awk 答案:

awk '{y=substr($3,1,4); c[y]++; s[y]+=$2} END {for (y in c) {print y, c[y], (s[y]/c[y])}}' file.txt
Run Code Online (Sandbox Code Playgroud)