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 (sizeof *mc, t2s->n_pairs);
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 ds_init_empty (&val0str);
178 ds_init_empty (&val1str);
180 var_append_value_name ((*vp)[0], ¶m->val0, &val0str);
181 var_append_value_name ((*vp)[1], ¶m->val1, &val1str);
183 ds_init_cstr (&pair_name, var_to_string ((*vp)[0]));
184 ds_put_cstr (&pair_name, " & ");
185 ds_put_cstr (&pair_name, var_to_string ((*vp)[1]));
187 tab_title (table, ds_cstr (&pair_name));
189 ds_destroy (&pair_name);
191 tab_headers (table, header_cols, 0, header_rows, 0);
193 /* Vertical lines inside the box */
194 tab_box (table, 0, 0, -1, TAL_1,
195 1, 0, tab_nc (table) - 1, tab_nr (table) - 1 );
197 /* Box around entire table */
198 tab_box (table, TAL_2, TAL_2, -1, -1,
199 0, 0, tab_nc (table) - 1, tab_nr (table) - 1 );
201 tab_vline (table, TAL_2, header_cols, 0, tab_nr (table) - 1);
202 tab_hline (table, TAL_2, 0, tab_nc (table) - 1, header_rows);
204 tab_text (table, 0, 0, TAB_CENTER, var_to_string ((*vp)[0]));
206 tab_joint_text (table, 1, 0, 2, 0, TAB_CENTER, var_to_string ((*vp)[1]));
207 tab_hline (table, TAL_1, 1, tab_nc (table) - 1, 1);
210 tab_text (table, 0, header_rows + 0, TAB_LEFT, ds_cstr (&val0str));
211 tab_text (table, 0, header_rows + 1, TAB_LEFT, ds_cstr (&val1str));
213 tab_text (table, header_cols + 0, 1, TAB_LEFT, ds_cstr (&val0str));
214 tab_text (table, header_cols + 1, 1, TAB_LEFT, ds_cstr (&val1str));
216 tab_double (table, header_cols + 0, header_rows + 0, TAB_RIGHT, param->n00, wfmt);
217 tab_double (table, header_cols + 0, header_rows + 1, TAB_RIGHT, param->n01, wfmt);
218 tab_double (table, header_cols + 1, header_rows + 0, TAB_RIGHT, param->n10, wfmt);
219 tab_double (table, header_cols + 1, header_rows + 1, TAB_RIGHT, param->n11, wfmt);
223 ds_destroy (&val0str);
224 ds_destroy (&val1str);
229 output_statistics_table (const struct two_sample_test *t2s,
230 const struct mcnemar *mc,
231 const struct dictionary *dict)
235 struct tab_table *table = tab_create (5, t2s->n_pairs + 1);
237 const struct variable *wv = dict_get_weight (dict);
238 const struct fmt_spec *wfmt = wv ? var_get_print_format (wv) : & F_8_0;
240 tab_title (table, _("Test Statistics"));
242 tab_headers (table, 0, 1, 0, 1);
244 tab_hline (table, TAL_2, 0, tab_nc (table) - 1, 1);
245 tab_vline (table, TAL_2, 1, 0, tab_nr (table) - 1);
248 /* Vertical lines inside the box */
249 tab_box (table, -1, -1, -1, TAL_1,
251 tab_nc (table) - 1, tab_nr (table) - 1);
253 /* Box around entire table */
254 tab_box (table, TAL_2, TAL_2, -1, -1,
255 0, 0, tab_nc (table) - 1,
258 tab_text (table, 1, 0, TAT_TITLE | TAB_CENTER,
261 tab_text (table, 2, 0, TAT_TITLE | TAB_CENTER,
262 _("Exact Sig. (2-tailed)"));
264 tab_text (table, 3, 0, TAT_TITLE | TAB_CENTER,
265 _("Exact Sig. (1-tailed)"));
267 tab_text (table, 4, 0, TAT_TITLE | TAB_CENTER,
268 _("Point Probability"));
270 for (i = 0 ; i < t2s->n_pairs; ++i)
273 variable_pair *vp = &t2s->pairs[i];
275 struct string pair_name;
276 ds_init_cstr (&pair_name, var_to_string ((*vp)[0]));
277 ds_put_cstr (&pair_name, " & ");
278 ds_put_cstr (&pair_name, var_to_string ((*vp)[1]));
280 tab_text (table, 0, 1 + i, TAB_LEFT, ds_cstr (&pair_name));
281 ds_destroy (&pair_name);
283 tab_double (table, 1, 1 + i, TAB_RIGHT, mc[i].n00 + mc[i].n01 + mc[i].n10 + mc[i].n11, wfmt);
285 sig = gsl_cdf_binomial_P (mc[i].n01, 0.5, mc[i].n01 + mc[i].n10);
287 tab_double (table, 2, 1 + i, TAB_RIGHT, 2 * sig, NULL);
288 tab_double (table, 3, 1 + i, TAB_RIGHT, sig, NULL);
290 tab_double (table, 4, 1 + i, TAB_RIGHT, gsl_ran_binomial_pdf (mc[i].n01, 0.5, mc[i].n01 + mc[i].n10),