创建类似awk直方图

时间:2018-04-09 16:55:56

标签: bash unix dataframe awk grouping

这是我的输入文件:

1.37987
1.21448
0.624999
1.28966
1.77084
1.088
1.41667

我想创建一个我选择的大小的bin来获得直方图输出,例如:类似于这样的0.1个箱子,从0开始:

0 0.1 0
...
0.5 0.6 0
0.6 0.7 1
...
1.0 1.1 1
1.1 1.2 0
1.2 1.3 2
1.3 1.4 1
...

我的文件对于R来说太大了,所以我正在寻找一个awk解决方案(也可以解决其他任何我能理解的问题,因为我还是Linux初学者)。

在这篇文章中已经回答了这个问题:awk histogram in buckets但解决方案对我不起作用。

3 个答案:

答案 0 :(得分:2)

如果不完全正确,这应该非常接近。至少将它视为一个起点并自己验证/计算出数学(特别是决定/验证哪个桶与0.2一样的精确边界匹配应该进入 - 0.1到0.2和/或0.2到0.3? ):

$ cat tst.awk
BEGIN { delta = (delta == "" ? 0.1 : delta) }
{
    bucketNr = int(($0+delta) / delta)
    cnt[bucketNr]++
    numBuckets = (numBuckets > bucketNr ? numBuckets : bucketNr)
}
END {
    for (bucketNr=1; bucketNr<=numBuckets; bucketNr++) {
        end = beg + delta
        printf "%0.1f %0.1f %d\n", beg, end, cnt[bucketNr]
        beg = end
    }
}

$ awk -f tst.awk file
0.0 0.1 0
0.1 0.2 0
0.2 0.3 0
0.3 0.4 0
0.4 0.5 0
0.5 0.6 0
0.6 0.7 1
0.7 0.8 0
0.8 0.9 0
0.9 1.0 0
1.0 1.1 1
1.1 1.2 0
1.2 1.3 2
1.3 1.4 1
1.4 1.5 1
1.5 1.6 0
1.6 1.7 0
1.7 1.8 1

请注意,您可以在命令行上指定存储桶增量大小,0.1只是默认值:

$ awk -v delta='0.3' -f tst.awk file
0.0 0.3 0
0.3 0.6 0
0.6 0.9 1
0.9 1.2 1
1.2 1.5 4
1.5 1.8 1

$ awk -v delta='0.5' -f tst.awk file
0.0 0.5 0
0.5 1.0 1
1.0 1.5 5
1.5 2.0 1

答案 1 :(得分:1)

这也是可能的:

awk -v size=0.1 
  '{ b=int($1/size); a[b]++; bmax=b>bmax?b:bmax; bmin=b<bmin?b:bmin }
   END { for(i=bmin;i<=bmax;++i) print i*size,(i+1)*size,a[i] }' <file>

它基本上与EdMorton的解决方案相同,但是从默认0的最小值开始打印存储桶。它基本上考虑了负数。

答案 2 :(得分:1)

这是我用Awk解决这个问题。

运行:#include <stdio.h> float max_of_two(float x, float y) { return (x > y) ? x : y; } float max_of_three(float m, float n, float p) { return max_of_two(max_of_two(m, n), p); } int main() { float m,n,p; scanf("%f%f%f", &m,&n,&p); printf("%f", max_of_three(m, n, p)); return 0; }

awk -f belowscript.awk inputfile

一些注意事项:

  • 我添加了对Ed Morton在命令行上提供bin大小的支持。
  • 它只打印包含某些内容的容器
  • 完全匹配进入哪个bin - 自然采用较小或较大的bin进行否定时需要进行调整以使其保持一致。
  • 0边界需要特殊的套管用于第一个负仓中的那些数字,因为没有这样的数字作为-0。 Awk的关联数组使用字符串作为键,因此&#34; -0&#34;是可能的,并且对于for循环使用@ind_num_asc排序顺序,似乎正确排序-0 - 尽管这可能不是可移植的。