CROSSTABS: Drop buggy ASE for asymmetric lambda; fix T for symmetric lambda.
[pspp] / src / language / stats / crosstabs.q
index 5095b7471551bd57fad15da0db9eb16ff6a8e182..21947ee45785426476716947b4581cc65ec3fac6 100644 (file)
@@ -16,9 +16,8 @@
 
 /* FIXME:
 
-   - T values for Spearman's R and Pearson's R are wrong.
    - How to calculate significance of symmetric and directional measures?
-   - Asymmetric ASEs and T values for lambda are wrong.
+   - How to calculate ASE for asymmetric lambda?
    - ASE of Goodman and Kruskal's tau is not calculated.
    - ASE of symmetric somers' d is wrong.
    - Approx. T of uncertainty coefficient is wrong.
@@ -2265,12 +2264,12 @@ calc_chisq (struct pivot_table *pt,
     }
 }
 
-/* Calculate the value of Pearson's r.  r is stored into R, ase_1 into
-   ASE_1, and ase_0 into ASE_0.  The row and column values must be
+/* Calculate the value of Pearson's r.  r is stored into R, its T value into
+   T, and standard error into ERROR.  The row and column values must be
    passed in PT and Y. */
 static void
 calc_r (struct pivot_table *pt,
-        double *PT, double *Y, double *r, double *ase_0, double *ase_1)
+        double *PT, double *Y, double *r, double *t, double *error)
 {
   double SX, SY, S, T;
   double Xbar, Ybar;
@@ -2308,7 +2307,7 @@ calc_r (struct pivot_table *pt,
   SY = sum_Y2c - pow2 (sum_Yc) / pt->total;
   T = sqrt (SX * SY);
   *r = S / T;
-  *ase_0 = sqrt ((sum_X2Y2f - pow2 (sum_XYf) / pt->total) / (sum_X2r * sum_Y2c));
+  *t = *r / sqrt (1 - pow2 (*r)) * sqrt (pt->total - 2);
 
   {
     double s, c, y, t;
@@ -2329,7 +2328,7 @@ calc_r (struct pivot_table *pt,
          c = (t - s) - y;
          s = t;
        }
-    *ase_1 = sqrt (s) / (T * T);
+    *error = sqrt (s) / (T * T);
   }
 }
 
@@ -2596,13 +2595,11 @@ calc_symmetric (struct crosstabs_proc *proc, struct pivot_table *pt,
       }
 
       calc_r (pt, R, C, &v[6], &t[6], &ase[6]);
-      t[6] = v[6] / t[6];
 
       free (R);
       free (C);
 
       calc_r (pt, (double *) pt->rows, (double *) pt->cols, &v[7], &t[7], &ase[7]);
-      t[7] = v[7] / t[7];
     }
 
   /* Cohen's kappa. */
@@ -2803,22 +2800,8 @@ calc_directional (struct crosstabs_proc *proc, struct pivot_table *pt,
       v[1] = (sum_fmj - rm) / (pt->total - rm);
       v[2] = (sum_fim - cm) / (pt->total - cm);
 
-      /* ASE1 for Y given PT. */
-      {
-       double accum;
-
-       for (accum = 0., i = 0; i < pt->n_rows; i++)
-         for (j = 0; j < pt->n_cols; j++)
-           {
-             const int deltaj = j == cm_index;
-             accum += (pt->mat[j + i * pt->n_cols]
-                       * pow2 ((j == fim_index[i])
-                              - deltaj
-                              + v[0] * deltaj));
-           }
-
-       ase[2] = sqrt (accum - pt->total * v[0]) / (pt->total - cm);
-      }
+      /* XXX We don't have a working formula for ASE1. */
+      ase[2] = SYSMIS;
 
       /* ASE0 for Y given PT. */
       {
@@ -2831,22 +2814,8 @@ calc_directional (struct crosstabs_proc *proc, struct pivot_table *pt,
        t[2] = v[2] / (sqrt (accum - pow2 (sum_fim - cm) / pt->total) / (pt->total - cm));
       }
 
-      /* ASE1 for PT given Y. */
-      {
-       double accum;
-
-       for (accum = 0., i = 0; i < pt->n_rows; i++)
-         for (j = 0; j < pt->n_cols; j++)
-           {
-             const int deltaj = i == rm_index;
-             accum += (pt->mat[j + i * pt->n_cols]
-                       * pow2 ((i == fmj_index[j])
-                              - deltaj
-                              + v[0] * deltaj));
-           }
-
-       ase[1] = sqrt (accum - pt->total * v[0]) / (pt->total - rm);
-      }
+      /* XXX We don't have a working formula for ASE1. */
+      ase[1] = SYSMIS;
 
       /* ASE0 for PT given Y. */
       {
@@ -2874,7 +2843,7 @@ calc_directional (struct crosstabs_proc *proc, struct pivot_table *pt,
                         * pow2 (temp0 + (v[0] - 1.) * temp1));
            }
        ase[0] = sqrt (accum1 - 4. * pt->total * v[0] * v[0]) / (2. * pt->total - rm - cm);
-       t[0] = v[0] / (sqrt (accum0 - pow2 ((sum_fim + sum_fmj - cm - rm) / pt->total))
+       t[0] = v[0] / (sqrt (accum0 - pow2 (sum_fim + sum_fmj - cm - rm) / pt->total)
                       / (2. * pt->total - rm - cm));
       }