1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 2011 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 #include <gsl/gsl_cdf.h>
22 #include <gsl/gsl_randist.h>
24 #include "data/casereader.h"
25 #include "data/dataset.h"
26 #include "data/dictionary.h"
27 #include "data/format.h"
28 #include "data/missing-values.h"
29 #include "data/variable.h"
30 #include "language/stats/npar.h"
31 #include "libpspp/str.h"
32 #include "output/tab.h"
33 #include "libpspp/message.h"
35 #include "gl/minmax.h"
36 #include "gl/xalloc.h"
38 #include "data/value.h"
41 #define _(msgid) gettext (msgid)
56 output_freq_table (variable_pair *vp,
57 const struct mcnemar *param,
58 const struct dictionary *dict);
62 output_statistics_table (const struct two_sample_test *t2s,
63 const struct mcnemar *param,
64 const struct dictionary *dict);
68 mcnemar_execute (const struct dataset *ds,
69 struct casereader *input,
70 enum mv_class exclude,
71 const struct npar_test *test,
78 const struct dictionary *dict = dataset_dict (ds);
80 const struct two_sample_test *t2s = UP_CAST (test, const struct two_sample_test, parent);
83 struct casereader *r = input;
85 struct mcnemar *mc = xcalloc (t2s->n_pairs, sizeof *mc);
87 for (i = 0 ; i < t2s->n_pairs; ++i )
89 mc[i].val0.f = mc[i].val1.f = SYSMIS;
92 for (; (c = casereader_read (r)) != NULL; case_unref (c))
94 const double weight = dict_get_case_weight (dict, c, &warn);
96 for (i = 0 ; i < t2s->n_pairs; ++i )
98 variable_pair *vp = &t2s->pairs[i];
99 const union value *value0 = case_data (c, (*vp)[0]);
100 const union value *value1 = case_data (c, (*vp)[1]);
102 if (var_is_value_missing ((*vp)[0], value0, exclude))
105 if (var_is_value_missing ((*vp)[1], value1, exclude))
109 if ( mc[i].val0.f == SYSMIS)
111 if (mc[i].val1.f != value0->f)
112 mc[i].val0.f = value0->f;
113 else if (mc[i].val1.f != value1->f)
114 mc[i].val0.f = value1->f;
117 if ( mc[i].val1.f == SYSMIS)
119 if (mc[i].val0.f != value1->f)
120 mc[i].val1.f = value1->f;
121 else if (mc[i].val0.f != value0->f)
122 mc[i].val1.f = value0->f;
125 if (mc[i].val0.f == value0->f && mc[i].val0.f == value1->f)
129 else if ( mc[i].val0.f == value0->f && mc[i].val1.f == value1->f)
133 else if ( mc[i].val1.f == value0->f && mc[i].val0.f == value1->f)
137 else if ( mc[i].val1.f == value0->f && mc[i].val1.f == value1->f)
143 msg (ME, _("The McNemar test is appropriate only for dichotomous variables"));
148 casereader_destroy (r);
150 for (i = 0 ; i < t2s->n_pairs ; ++i)
151 output_freq_table (&t2s->pairs[i], mc + i, dict);
153 output_statistics_table (t2s, mc, dict);
160 output_freq_table (variable_pair *vp,
161 const struct mcnemar *param,
162 const struct dictionary *dict)
164 const int header_rows = 2;
165 const int header_cols = 1;
167 struct tab_table *table = tab_create (header_cols + 2, header_rows + 2);
169 const struct variable *wv = dict_get_weight (dict);
170 const struct fmt_spec *wfmt = wv ? var_get_print_format (wv) : & F_8_0;
173 struct string pair_name;
174 struct string val1str ;
175 struct string val0str ;
177 tab_set_format (table, RC_WEIGHT, wfmt);
179 ds_init_empty (&val0str);
180 ds_init_empty (&val1str);
182 var_append_value_name ((*vp)[0], ¶m->val0, &val0str);
183 var_append_value_name ((*vp)[1], ¶m->val1, &val1str);
185 ds_init_cstr (&pair_name, var_to_string ((*vp)[0]));
186 ds_put_cstr (&pair_name, " & ");
187 ds_put_cstr (&pair_name, var_to_string ((*vp)[1]));
189 tab_title (table, "%s", ds_cstr (&pair_name));
191 ds_destroy (&pair_name);
193 tab_headers (table, header_cols, 0, header_rows, 0);
195 /* Vertical lines inside the box */
196 tab_box (table, 0, 0, -1, TAL_1,
197 1, 0, tab_nc (table) - 1, tab_nr (table) - 1 );
199 /* Box around entire table */
200 tab_box (table, TAL_2, TAL_2, -1, -1,
201 0, 0, tab_nc (table) - 1, tab_nr (table) - 1 );
203 tab_vline (table, TAL_2, header_cols, 0, tab_nr (table) - 1);
204 tab_hline (table, TAL_2, 0, tab_nc (table) - 1, header_rows);
206 tab_text (table, 0, 0, TAB_CENTER, var_to_string ((*vp)[0]));
208 tab_joint_text (table, 1, 0, 2, 0, TAB_CENTER, var_to_string ((*vp)[1]));
209 tab_hline (table, TAL_1, 1, tab_nc (table) - 1, 1);
212 tab_text (table, 0, header_rows + 0, TAB_LEFT, ds_cstr (&val0str));
213 tab_text (table, 0, header_rows + 1, TAB_LEFT, ds_cstr (&val1str));
215 tab_text (table, header_cols + 0, 1, TAB_LEFT, ds_cstr (&val0str));
216 tab_text (table, header_cols + 1, 1, TAB_LEFT, ds_cstr (&val1str));
218 tab_double (table, header_cols + 0, header_rows + 0, TAB_RIGHT, param->n00, NULL, RC_WEIGHT);
219 tab_double (table, header_cols + 0, header_rows + 1, TAB_RIGHT, param->n01, NULL, RC_WEIGHT);
220 tab_double (table, header_cols + 1, header_rows + 0, TAB_RIGHT, param->n10, NULL, RC_WEIGHT);
221 tab_double (table, header_cols + 1, header_rows + 1, TAB_RIGHT, param->n11, NULL, RC_WEIGHT);
225 ds_destroy (&val0str);
226 ds_destroy (&val1str);
231 output_statistics_table (const struct two_sample_test *t2s,
232 const struct mcnemar *mc,
233 const struct dictionary *dict)
237 struct tab_table *table = tab_create (5, t2s->n_pairs + 1);
239 const struct variable *wv = dict_get_weight (dict);
240 const struct fmt_spec *wfmt = wv ? var_get_print_format (wv) : & F_8_0;
242 tab_title (table, _("Test Statistics"));
243 tab_set_format (table, RC_WEIGHT, wfmt);
245 tab_headers (table, 0, 1, 0, 1);
247 tab_hline (table, TAL_2, 0, tab_nc (table) - 1, 1);
248 tab_vline (table, TAL_2, 1, 0, tab_nr (table) - 1);
251 /* Vertical lines inside the box */
252 tab_box (table, -1, -1, -1, TAL_1,
254 tab_nc (table) - 1, tab_nr (table) - 1);
256 /* Box around entire table */
257 tab_box (table, TAL_2, TAL_2, -1, -1,
258 0, 0, tab_nc (table) - 1,
261 tab_text (table, 1, 0, TAT_TITLE | TAB_CENTER,
264 tab_text (table, 2, 0, TAT_TITLE | TAB_CENTER,
265 _("Exact Sig. (2-tailed)"));
267 tab_text (table, 3, 0, TAT_TITLE | TAB_CENTER,
268 _("Exact Sig. (1-tailed)"));
270 tab_text (table, 4, 0, TAT_TITLE | TAB_CENTER,
271 _("Point Probability"));
273 for (i = 0 ; i < t2s->n_pairs; ++i)
276 variable_pair *vp = &t2s->pairs[i];
278 struct string pair_name;
279 ds_init_cstr (&pair_name, var_to_string ((*vp)[0]));
280 ds_put_cstr (&pair_name, " & ");
281 ds_put_cstr (&pair_name, var_to_string ((*vp)[1]));
283 tab_text (table, 0, 1 + i, TAB_LEFT, ds_cstr (&pair_name));
284 ds_destroy (&pair_name);
286 tab_double (table, 1, 1 + i, TAB_RIGHT, mc[i].n00 + mc[i].n01 + mc[i].n10 + mc[i].n11, NULL, RC_WEIGHT);
288 sig = gsl_cdf_binomial_P (mc[i].n01, 0.5, mc[i].n01 + mc[i].n10);
290 tab_double (table, 2, 1 + i, TAB_RIGHT, 2 * sig, NULL, RC_PVALUE);
291 tab_double (table, 3, 1 + i, TAB_RIGHT, sig, NULL, RC_PVALUE);
293 tab_double (table, 4, 1 + i, TAB_RIGHT, gsl_ran_binomial_pdf (mc[i].n01, 0.5, mc[i].n01 + mc[i].n10),