FREQUENCIES: Choose number of bins for histogram based on valid cases.
[pspp] / src / language / stats / frequencies.q
index e52aaf0f9ae3f50d7b40880050e18b6d06170c34..523345be51e3a6955c3c13e9c3424314145f2bb9 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2007, 2009 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2007, 2009, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -601,7 +601,7 @@ postcalc (const struct dataset *ds)
 
 
 
-      if ( chart == GFT_HIST && var_is_numeric (v) )
+      if ( chart == GFT_HIST && var_is_numeric (v) && ft->n_valid > 0)
        {
          double d[frq_n_stats];
          struct histogram *hist ;
@@ -1170,6 +1170,8 @@ calc_stats (const struct variable *v, double d[frq_n_stats])
 
   /* Calculate percentiles. */
 
+  assert (ft->n_valid > 0);
+
   for (i = 0; i < n_percentiles; i++)
     {
       percentiles[i].flag = 0;
@@ -1372,7 +1374,7 @@ freq_tab_to_hist (const struct freq_tab *ft, const struct variable *var)
   double x_max = -DBL_MAX;
 
   struct histogram *hist;
-  const double bins = 11;
+  int bins;
 
   struct hsh_iterator hi;
   struct hsh_table *fh = ft->data;
@@ -1388,6 +1390,11 @@ freq_tab_to_hist (const struct freq_tab *ft, const struct variable *var)
       if ( frq->value.f > x_max ) x_max = frq->value.f ;
     }
 
+  /* Sturges' formula. */
+  bins = ceil (log (ft->valid_cases) / log (2) + 1);
+  if (bins < 5)
+    bins = 5;
+
   hist = histogram_create (bins, x_min, x_max);
 
   for( i = 0 ; i < ft->n_valid ; ++i )