Changed the definition of factors to be self referential.
[pspp-builds.git] / src / oneway.q
index 185a96303ab3f98c0973d188a95444d09e28f00c..ff6b79b66e9d322eac109ce062ac5806cf8bfef5 100644 (file)
@@ -84,21 +84,24 @@ static int ostensible_number_of_groups=-1;
 static is_missing_func value_is_missing;
 
 
-static void calculate(const struct casefile *cf, void *_mode);
+static void run_oneway(const struct casefile *cf, void *_mode);
 
 
 /* Routines to show the output tables */
 static void show_anova_table(void);
 static void show_descriptives(void);
 static void show_homogeneity(void);
-static void show_contrast_coeffs(void);
-static void show_contrast_tests(void);
 
+static void show_contrast_coeffs(short *);
+static void show_contrast_tests(short *);
 
-enum stat_table_t {STAT_DESC, STAT_HOMO};
+
+enum stat_table_t {STAT_DESC = 1, STAT_HOMO = 2};
 
 static enum stat_table_t stat_tables ;
 
+void output_oneway(void);
+
 
 int
 cmd_oneway(void)
@@ -133,7 +136,21 @@ cmd_oneway(void)
        }
     }
 
-  multipass_procedure_with_splits (calculate, &cmd);
+  multipass_procedure_with_splits (run_oneway, &cmd);
+
+
+  return CMD_SUCCESS;
+}
+
+
+void
+output_oneway(void)
+{
+
+  int i;
+  short *bad_contrast ; 
+
+  bad_contrast = xmalloc ( sizeof (short) * cmd.sbc_contrast );
 
   /* Check the sanity of the given contrast values */
   for (i = 0 ; i < cmd.sbc_contrast ; ++i ) 
@@ -141,12 +158,14 @@ cmd_oneway(void)
       int j;
       double sum = 0;
 
+      bad_contrast[i] = 0;
       if ( subc_list_double_count(&cmd.dl_contrast[i]) != 
           ostensible_number_of_groups )
        {
-         msg(SE
+         msg(SW
              _("Number of contrast coefficients must equal the number of groups"));
-         return CMD_FAILURE;
+         bad_contrast[i] = 1;
+         continue;
        }
 
       for (j=0; j < ostensible_number_of_groups ; ++j )
@@ -164,13 +183,15 @@ cmd_oneway(void)
 
   show_anova_table();
      
-  if (cmd.sbc_contrast)
+  if (cmd.sbc_contrast )
     {
-      show_contrast_coeffs();
-      show_contrast_tests();
+      show_contrast_coeffs(bad_contrast);
+      show_contrast_tests(bad_contrast);
     }
 
 
+  free(bad_contrast);
+
   /* Clean up */
   for (i = 0 ; i < n_vars ; ++i ) 
     {
@@ -181,13 +202,11 @@ cmd_oneway(void)
 
   hsh_destroy(global_group_hash);
 
-  return CMD_SUCCESS;
 }
 
 
 
 
-
 /* Parser for the variables sub command */
 static int
 oneway_custom_variables(struct cmd_oneway *cmd UNUSED)
@@ -561,7 +580,7 @@ show_homogeneity(void)
 
 /* Show the contrast coefficients table */
 static void 
-show_contrast_coeffs(void)
+show_contrast_coeffs(short *bad_contrast)
 {
   char *s;
   int n_cols = 2 + ostensible_number_of_groups;
@@ -621,6 +640,7 @@ show_contrast_coeffs(void)
       int i;
       char *lab;
 
+
       lab = val_labs_find(indep_var->val_labs,*group_value);
   
       if ( lab ) 
@@ -632,10 +652,15 @@ show_contrast_coeffs(void)
 
       for (i = 0 ; i < cmd.sbc_contrast ; ++i ) 
        {
+
          tab_text(t, 1, i + 2, TAB_CENTER | TAT_PRINTF, "%d", i + 1);
-         tab_text(t, count + 2, i + 2, TAB_RIGHT | TAT_PRINTF, "%g", 
-                  subc_list_double_at(&cmd.dl_contrast[i],count)
-                  );
+
+         if ( bad_contrast[i] ) 
+           tab_text(t, count + 2, i + 2, TAB_RIGHT, "?" );
+         else
+           tab_text(t, count + 2, i + 2, TAB_RIGHT | TAT_PRINTF, "%g", 
+                    subc_list_double_at(&cmd.dl_contrast[i],count)
+                    );
        }
          
       count++ ; 
@@ -648,7 +673,7 @@ show_contrast_coeffs(void)
 
 /* Show the results of the contrast tests */
 static void 
-show_contrast_tests(void)
+show_contrast_tests(short *bad_contrast)
 {
   int v;
   int n_cols = 8;
@@ -746,6 +771,10 @@ show_contrast_tests(void)
          tab_text (t,  2, (v * lines_per_variable) + i + 1 + cmd.sbc_contrast,
                    TAB_CENTER | TAT_TITLE | TAT_PRINTF, "%d",i+1);
 
+
+         if ( bad_contrast[i]) 
+           continue;
+
          /* FIXME: Potential danger here.
             We're ASSUMING THE array is in the order corresponding to the 
             hash order. */
@@ -769,17 +798,15 @@ show_contrast_tests(void)
            }
          sec_vneq = sqrt(sec_vneq);
 
-
          df_numerator = pow2(df_numerator);
-         
 
          tab_float (t,  3, (v * lines_per_variable) + i + 1, 
                     TAB_RIGHT, contrast_value, 8,2);
 
-         tab_float (t,  3, (v * lines_per_variable) + i + 1 + cmd.sbc_contrast,
+         tab_float (t,  3, (v * lines_per_variable) + i + 1 + 
+                    cmd.sbc_contrast,
                     TAB_RIGHT, contrast_value, 8,2);
 
-
          std_error_contrast = sqrt(vars[v]->p.grp_data.mse * coef_msq);
 
          /* Std. Error */
@@ -891,7 +918,7 @@ precalc ( struct cmd_oneway *cmd UNUSED )
 
 
 static void 
-calculate(const struct casefile *cf, void *cmd_)
+run_oneway(const struct casefile *cf, void *cmd_)
 {
   struct casereader *r;
   struct ccase c;
@@ -903,12 +930,8 @@ calculate(const struct casefile *cf, void *cmd_)
                                 (hsh_hash_func *) hash_value,
                                 0,
                                 (void *) indep_var->width );
-
-
-
   precalc(cmd);
 
-
   for(r = casefile_get_reader (cf);
       casereader_read (r, &c) ;
       case_destroy (&c)) 
@@ -919,10 +942,30 @@ calculate(const struct casefile *cf, void *cmd_)
        dict_get_case_weight(default_dict,&c,&bad_weight_warn);
       
       const union value *indep_val = case_data (&c, indep_var->fv);
+
+      /* Deal with missing values */
+      if ( value_is_missing(indep_val,indep_var) )
+          continue;
+
+      /* Skip the entire case if /MISSING=LISTWISE is set */
+      if ( cmd->miss == ONEWAY_LISTWISE ) 
+       {
+         for(i = 0; i < n_vars ; ++i) 
+           {
+             const struct variable *v = vars[i];
+             const union value *val = case_data (&c, v->fv);
+
+             if (value_is_missing(val,v) )
+                 break;
+           }
+         if ( i != n_vars ) 
+             continue;
+
+       }
+      
          
       hsh_insert ( global_group_hash, (void *) indep_val );
 
-
       for ( i = 0 ; i < n_vars ; ++i ) 
        {
          const struct variable *v = vars[i];
@@ -986,10 +1029,16 @@ calculate(const struct casefile *cf, void *cmd_)
 
   
   if ( stat_tables & STAT_HOMO ) 
-    levene(cf, indep_var, n_vars, vars, LEV_LISTWISE, value_is_missing);
+    levene(cf, indep_var, n_vars, vars, 
+          (cmd->miss == ONEWAY_LISTWISE) ? LEV_LISTWISE : LEV_ANALYSIS ,
+          value_is_missing);
 
   ostensible_number_of_groups = hsh_count (global_group_hash);
 
+
+  output_oneway();
+
+
 }
 
 
@@ -1037,8 +1086,5 @@ postcalc (  struct cmd_oneway *cmd UNUSED )
 
       totals->se_mean = totals->std_dev / sqrt(totals->n);
        
-
-
-      
     }
 }