home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1993 #3 / NN_1993_3.iso / spool / alt / lang / awk / 29 < prev    next >
Encoding:
Internet Message Format  |  1993-01-28  |  3.9 KB

  1. Path: sparky!uunet!hela.iti.org!usc!usc!not-for-mail
  2. From: ajayshah@almaak.usc.edu (Ajay Shah)
  3. Newsgroups: alt.lang.awk
  4. Subject: Re: Histogrammer? (with some src)
  5. Date: 28 Jan 1993 16:48:41 -0800
  6. Organization: University of Southern California, Los Angeles, CA
  7. Lines: 157
  8. Message-ID: <1k9ut9INNg0k@almaak.usc.edu>
  9. References: <dfrankow.728249852@myria> <1993Jan28.221236.28016@csc.ti.com>
  10. NNTP-Posting-Host: almaak.usc.edu
  11.  
  12. I also wrote a histogrammer in awk and found it was too slow.
  13. I then rewrote it in C.
  14. If there is interest I'll post it.
  15.  
  16. BTW there are two variants:
  17.  
  18. a) "One-way and two-way frequency tables"
  19.  
  20. This works with discrete data.  It reduces data into a table like:
  21.  
  22. 1                        2        40%        40%
  23. 2                        2        40%        80%
  24. 7                        1        20%       100%
  25.  
  26. Totally                  5
  27.  
  28. or
  29.  
  30.            | f2
  31.         f1 |        1         2 |     Total
  32. -----------+--------------------+----------
  33.          1 |        1         2 |         3
  34.          2 |        0         1 |         1
  35. -----------+--------------------+----------
  36.      Total |        1         3 |         4
  37.  
  38.  
  39. b) "Histogram".  This deals with real-valued data and comes 
  40.    up with things like:
  41.  
  42.                0.0                                                       0.778
  43.               +--------------------------------------------------------------- 
  44.   0.00-3.00   |**********************************************
  45.   3.00-6.00   |******************
  46.   6.00-9.00   |******************
  47.  
  48.  
  49.  
  50. I have a program named `crosstab' which produces the first
  51. kind of tables and a program named `binning' which does the second.
  52.  
  53.         -ans.
  54.  
  55.  
  56. Here is a awk one-way frequency table:
  57.  
  58.  
  59. {
  60.         count[$3]++;
  61. }
  62.  
  63. END {
  64.         for (x in count) {
  65.                 ++i; y[i] = x;
  66.         }
  67.         N = i;
  68.         # Now y is a array containing element values.
  69.         do {
  70.                 interchanged = 0;
  71.                 for (i=1; i<N; i++)
  72.                         if (y[i] > y[i+1]) {
  73.                                 tmp = y[i]; y[i] = y[i+1]; y[i+1] = tmp;
  74.                                 interchanged = 1;
  75.                         }
  76.         } while (interchanged);
  77.  
  78.         for (i=1; i<=N; i++)
  79.                 printf("%f  %d\n", y[i], count[y[i]]);
  80. }
  81.  
  82.  
  83. Here is it in perl:
  84.  
  85. #!/usr/rand/bin/perl
  86.  
  87. #From sondeen@ISI.EDU Thu Mar 19 10:44:10 1992
  88. #Here is a perl program to do what you request (I did it for practice :-)
  89.  
  90. #To run it, you must have the program "perl" in your search path (hint:
  91. #do "which perl").  Save the following in a file called ctab and then
  92. #run "perl ctab your_field_numbers your_data_file(s)" eg:
  93.  
  94. #perl ctab 2 1 ctabs.dat ctabs.dat    <== for two copies :-)
  95. # From: ajayshah@alhena.usc.edu (Ajay Shah)
  96. # Newsgroups: alt.sources.wanted
  97. # Subject: Has someone written a Unix tool for [cross-]tabulation?
  98. # I'm looking for a Unix utility which does tabulations and cross
  99. # tabulations.
  100. # E.g. given a dataset
  101. # 1 7 9
  102. # 1 6 19
  103. # 2 7 4
  104. # 2 6 3
  105. # 3 7 2
  106. #         ...
  107.  
  108. $usage = "ctab field [field+] file+";
  109.  
  110. @indices = ();
  111.  
  112. while (($parm = shift) =~ /^\d+/) {
  113.     push(@indices, $parm - 1);    # reduce index by 1
  114. }
  115.  
  116. if ($#indices < 0 || $parm eq '') {
  117.     print "$usage\n";
  118.     exit 1;
  119. }
  120.  
  121. unshift(@ARGV,$parm);
  122.  
  123. %counts = ();
  124. %firsts = ();
  125. %seconds = ();
  126.  
  127. while (<>) {
  128.     chop;
  129.     split;
  130.     shift if ($_[0] eq '');    # skip leading nothing
  131.     @_ = @_[@indices];
  132.     if ($#_ == $#indices) {
  133.         $firsts{@_[0]}++;
  134.         $seconds{@_[1]}++ if ($#indices > 0);
  135.         $index = join('|',@_);
  136.         $counts{$index}++;
  137.     } else {
  138.         #skip bad line?
  139.     }
  140. }
  141.  
  142. @firsts = sort keys %firsts;
  143. @seconds = sort keys %seconds;
  144.  
  145. if ($#seconds >= 0) {
  146.     print "    ";
  147.     foreach $second (@seconds) {
  148.         print "$second    ";
  149.     }
  150.     print "\n";
  151. }
  152.  
  153. foreach $first (@firsts) {
  154.     print "$first    ";
  155.     foreach $second (@seconds) {
  156.         printf "%d    ",$counts{$first . '|' . $second};
  157.         # printf to make '' show up as 0
  158.     }
  159.     print "$counts{$first}    " if ($#seconds < 0);
  160.     print "\n";
  161. }
  162.  
  163. exit 0;
  164. -- 
  165. Ajay Shah, (213)749-8133, ajayshah@rcf.usc.edu
  166.