COUNT: Correct treatment of missing values.
authorBen Pfaff <blp@cs.stanford.edu>
Sun, 15 Feb 2015 22:52:11 +0000 (14:52 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Sun, 15 Feb 2015 22:52:11 +0000 (14:52 -0800)
COUNT didn't properly handle user-missing values or the MISSING
keyword.  This corrects the problem.

Thanks to ftr <news.ftr@free.fr> for reporting this bug.
Bug #44157.

NEWS
src/language/xforms/count.c
tests/language/xforms/count.at

diff --git a/NEWS b/NEWS
index 05810946a3fe1044523393a9ec9d0f85f09329d4..c1746d6bc89c429588f118c0fec77ab68a5e6040 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,5 @@
 PSPP NEWS -- history of user-visible changes.
-Copyright (C) 1996-2000, 2008-2014 Free Software Foundation, Inc.
+Copyright (C) 1996-2000, 2008-2015 Free Software Foundation, Inc.
 See the end for copying conditions.
 
 Please send PSPP bug reports to bug-gnu-pspp@gnu.org.
@@ -43,6 +43,9 @@ Changes from 0.8.3 to 0.8.4:
    - Planned comparisons in ONEWAY ANOVA now correctly handle negative
      T-values.
 
+   - The COUNT command now correctly treats missing values as
+     documented.
+
    - Conformance fixes to Open Document output format.
 
 Changes from 0.8.2 to 0.8.3:
index c42bdc34cf01bedba7d5aa86756cdefca797ee4b..bf3c9e9ac5ad87cc39f1452998357e1a8b0988e2 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2009, 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2009, 2010, 2011, 2015 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
@@ -209,7 +209,7 @@ parse_numeric_criteria (struct lexer *lexer, struct pool *pool, struct criteria
       if (lex_match_id (lexer, "SYSMIS"))
         crit->count_system_missing = true;
       else if (lex_match_id (lexer, "MISSING"))
-       crit->count_user_missing = true;
+       crit->count_system_missing = crit->count_user_missing = true;
       else if (parse_num_range (lexer, &low, &high, NULL))
         {
           struct num_value *cur;
@@ -290,25 +290,25 @@ count_numeric (struct criteria *crit, const struct ccase *c)
   for (i = 0; i < crit->var_cnt; i++)
     {
       double x = case_num (c, crit->vars[i]);
-      if (var_is_num_missing (crit->vars[i], x, MV_ANY))
-        {
-          if (x == SYSMIS
-              ? crit->count_system_missing
-              : crit->count_user_missing)
+      struct num_value *v;
+
+      for (v = crit->values.num; v < crit->values.num + crit->value_cnt;
+           v++)
+        if (v->type == CNT_SINGLE ? x == v->a : x >= v->a && x <= v->b)
+          {
             counter++;
-        }
-      else
+            break;
+          }
+
+      if (var_is_num_missing (crit->vars[i], x, MV_ANY)
+          && (x == SYSMIS
+              ? crit->count_system_missing
+              : crit->count_user_missing))
         {
-          struct num_value *v;
-
-          for (v = crit->values.num; v < crit->values.num + crit->value_cnt;
-               v++)
-            if (v->type == CNT_SINGLE ? x == v->a : x >= v->a && x <= v->b)
-              {
-                counter++;
-                break;
-              }
+          counter++;
+          continue;
         }
+
     }
 
   return counter;
index 2187d9788d2bd4e519dbc2a7ca75e486b84b254f..eacf505d6b3d9de067eea52076b5ba3593d9dac9 100644 (file)
@@ -2,16 +2,22 @@ AT_BANNER([COUNT])
 
 AT_SETUP([COUNT -- numeric data])
 AT_DATA([count.sps], [dnl
-DATA LIST LIST /x * y *.
+DATA LIST LIST /x y.
 BEGIN DATA.
 1 2
 2 3
 4 5
 2 2
 5 6
+7 2
+. 2
 END DATA.
 
-COUNT c=x y (2).
+MISSING VALUES x(7)/y(3).
+
+COUNT c=x y (2)/d=x y(7)/e=x y(missing)/f=x y(sysmis).
+
+FORMATS ALL(F1).
 
 LIST.
 ])
@@ -22,12 +28,14 @@ x,F8.0
 y,F8.0
 
 Table: Data List
-x,y,c
-1.00,2.00,1.00
-2.00,3.00,1.00
-4.00,5.00,.00
-2.00,2.00,2.00
-5.00,6.00,.00
+x,y,c,d,e,f
+1,2,1,0,0,0
+2,3,1,0,1,0
+4,5,0,0,0,0
+2,2,2,0,0,0
+5,6,0,0,0,0
+7,2,1,1,1,0
+.,2,1,0,1,1
 ])
 AT_CLEANUP