1 /* PSPP - computes sample statistics. -*-c-*-
3 Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
4 Written by John Williams <johnr.williams@stonebow.otago.ac.nz>.
5 Almost completly re-written by John Darrington 2004
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the
10 License, or (at your option) any later version.
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
29 #include "dcdflib/cdflib.h"
36 #include "value-labels.h"
45 variables=varlist("PV_NO_SCRATCH | PV_NUMERIC");
47 +missing=miss:!analysis/listwise,
48 incl:include/!exclude;
49 format=fmt:!labels/nolabels;
50 criteria=:cin(d:criteria,"%s > 0. && %s < 1.").
55 static struct cmd_t_test cmd;
58 static struct pool *t_test_pool ;
60 /* Variable for the GROUPS subcommand, if given. */
61 static struct variable *groups;
63 /* GROUPS: Number of values specified by the user; the values
65 static int n_groups_values;
66 static union value groups_values[2];
68 /* PAIRS: Number of pairs to be compared ; each pair. */
70 typedef struct variable *pair_t[2] ;
74 static int parse_value (union value * v, int type) ;
77 /* Structures and Functions for the Statistics Summary Box */
79 typedef void populate_ssbox_func(struct ssbox *ssb,
80 struct cmd_t_test *cmd);
81 typedef void finalize_ssbox_func(struct ssbox *ssb);
87 populate_ssbox_func *populate;
88 finalize_ssbox_func *finalize;
93 void ssbox_create(struct ssbox *ssb, struct cmd_t_test *cmd, int mode);
95 /* Populate a ssbox according to cmd */
96 void ssbox_populate(struct ssbox *ssb, struct cmd_t_test *cmd);
98 /* Submit and destroy a ssbox */
99 void ssbox_finalize(struct ssbox *ssb);
103 /* Structures and Functions for the Test Results Box */
106 typedef void populate_trbox_func(struct trbox *trb,
107 struct cmd_t_test *cmd);
108 typedef void finalize_trbox_func(struct trbox *trb);
112 populate_trbox_func *populate;
113 finalize_trbox_func *finalize;
117 void trbox_create(struct trbox *trb, struct cmd_t_test *cmd, int mode);
119 /* Populate a ssbox according to cmd */
120 void trbox_populate(struct trbox *trb, struct cmd_t_test *cmd);
122 /* Submit and destroy a ssbox */
123 void trbox_finalize(struct trbox *trb);
125 /* Which mode was T-TEST invoked */
137 struct ssbox stat_summary_box;
138 struct trbox test_results_box;
140 if (!lex_force_match_id ("T"))
144 lex_match_id ("TEST");
146 if ( !parse_t_test(&cmd) )
149 if (! cmd.sbc_criteria)
152 if ( cmd.sbc_testval + cmd.sbc_groups + cmd.sbc_pairs != 1 )
155 _("Exactly one of TESTVAL, GROUPS or PAIRS subcommands is required")
162 else if (cmd.sbc_groups)
167 if ( mode == T_PAIRED && cmd.sbc_variables)
169 msg(SE, _("VARIABLES subcommand is not appropriate with PAIRS"));
173 t_test_pool = pool_create ();
175 ssbox_create(&stat_summary_box,&cmd,mode);
176 trbox_create(&test_results_box,&cmd,mode);
178 ssbox_populate(&stat_summary_box,&cmd);
179 trbox_populate(&test_results_box,&cmd);
181 ssbox_finalize(&stat_summary_box);
182 trbox_finalize(&test_results_box);
184 pool_destroy (t_test_pool);
192 tts_custom_groups (struct cmd_t_test *cmd unused)
196 if (token != T_ALL &&
197 (token != T_ID || dict_lookup_var (default_dict, tokid) == NULL)
200 msg(SE,_("`%s' is not a variable name"),tokid);
204 groups = parse_variable ();
207 lex_error ("expecting variable name in GROUPS subcommand");
211 if (groups->type == T_STRING && groups->width > MAX_SHORT_STRING)
213 msg (SE, _("Long string variable %s is not valid here."),
218 if (!lex_match ('('))
220 if (groups->type == NUMERIC)
223 groups_values[0].f = 1;
224 groups_values[1].f = 2;
229 msg (SE, _("When applying GROUPS to a string variable, at "
230 "least one value must be specified."));
235 if (!parse_value (&groups_values[0],groups->type))
243 if (!parse_value (&groups_values[1],groups->type))
247 if (!lex_force_match (')'))
254 tts_custom_pairs (struct cmd_t_test *cmd unused)
256 struct variable **vars;
259 int n_after_WITH = -1;
260 int paired ; /* Was the PAIRED keyword given ? */
264 if ((token != T_ID || dict_lookup_var (default_dict, tokid) == NULL)
267 msg(SE,_("`%s' is not a variable name"),tokid);
272 if (!parse_variables (default_dict, &vars, &n_vars,
273 PV_DUPLICATE | PV_NUMERIC | PV_NO_SCRATCH))
281 if (lex_match (T_WITH))
283 n_before_WITH = n_vars;
284 if (!parse_variables (default_dict, &vars, &n_vars,
285 PV_DUPLICATE | PV_APPEND
286 | PV_NUMERIC | PV_NO_SCRATCH))
291 n_after_WITH = n_vars - n_before_WITH;
294 paired = (lex_match ('(') && lex_match_id ("PAIRED") && lex_match (')'));
296 /* Determine the number of pairs needed */
299 if (n_before_WITH != n_after_WITH)
302 msg (SE, _("PAIRED was specified but the number of variables "
303 "preceding WITH (%d) did not match the number "
305 n_before_WITH, n_after_WITH );
308 n_pairs=n_before_WITH;
310 else if (n_before_WITH > 0) /* WITH keyword given, but not PAIRED keyword */
312 n_pairs=n_before_WITH * n_after_WITH ;
314 else /* Neither WITH nor PAIRED keyword given */
319 msg (SE, _("At least two variables must be specified "
324 /* how many ways can you pick 2 from n_vars ? */
325 n_pairs = n_vars * (n_vars -1 ) /2 ;
328 /* Allocate storage for the pairs */
329 pairs = xrealloc(pairs,sizeof(pair_t) *n_pairs);
331 /* Populate the pairs with the appropriate variables */
336 assert(n_pairs == n_vars/2);
337 for (i = 0; i < n_pairs ; ++i)
339 pairs[i][0] = vars[i];
340 pairs[i][1] = vars[i+n_pairs];
343 else if (n_before_WITH > 0) /* WITH keyword given, but not PAIRED keyword */
348 for(i=0 ; i < n_before_WITH ; ++i )
350 for(j=0 ; j < n_after_WITH ; ++j)
352 pairs[p][0] = vars[i];
353 pairs[p][1] = vars[j+n_before_WITH];
358 else /* Neither WITH nor PAIRED given */
363 for(i=0 ; i < n_vars ; ++i )
365 for(j=i+1 ; j < n_vars ; ++j)
367 pairs[p][0] = vars[i];
368 pairs[p][1] = vars[j];
377 /* Parses the current token (numeric or string, depending on type)
378 value v and returns success. */
380 parse_value (union value * v, int type )
384 if (!lex_force_num ())
390 if (!lex_force_string ())
392 strncpy (v->s, ds_value (&tokstr), ds_length (&tokstr));
401 /* Implementation of the SSBOX object */
403 void ssbox_base_init(struct ssbox *this, int cols,int rows);
405 void ssbox_base_finalize(struct ssbox *ssb);
407 void ssbox_one_sample_init(struct ssbox *this,
408 struct cmd_t_test *cmd );
410 void ssbox_independent_samples_init(struct ssbox *this,
411 struct cmd_t_test *cmd);
413 void ssbox_paired_init(struct ssbox *this,
414 struct cmd_t_test *cmd);
416 /* Factory to create an ssbox */
418 ssbox_create(struct ssbox *ssb, struct cmd_t_test *cmd, int mode)
423 ssbox_one_sample_init(ssb,cmd);
426 ssbox_independent_samples_init(ssb,cmd);
429 ssbox_paired_init(ssb,cmd);
437 /* Despatcher for the populate method */
439 ssbox_populate(struct ssbox *ssb,struct cmd_t_test *cmd)
441 ssb->populate(ssb,cmd);
445 /* Despatcher for finalize */
447 ssbox_finalize(struct ssbox *ssb)
453 /* Submit the box and clear up */
455 ssbox_base_finalize(struct ssbox *ssb)
460 /* Initialize a ssbox struct */
462 ssbox_base_init(struct ssbox *this, int cols,int rows)
464 this->finalize = ssbox_base_finalize;
465 this->t = tab_create (cols, rows, 0);
467 tab_columns (this->t, SOM_COL_DOWN, 1);
468 tab_headers (this->t,0,0,1,0);
469 tab_box (this->t, TAL_2, TAL_2, TAL_0, TAL_1, 0, 0, cols -1, rows -1 );
470 tab_hline(this->t, TAL_2,0,cols-1,1);
471 tab_dim (this->t, tab_natural_dimensions);
474 void ssbox_one_sample_populate(struct ssbox *ssb,
475 struct cmd_t_test *cmd);
477 /* Initialize the one_sample ssbox */
479 ssbox_one_sample_init(struct ssbox *this,
480 struct cmd_t_test *cmd )
483 const int vsize=cmd->n_variables+1;
485 this->populate = ssbox_one_sample_populate;
487 ssbox_base_init(this, hsize,vsize);
488 tab_title (this->t, 0, _("One-Sample Statistics"));
489 tab_vline(this->t, TAL_2, 1,0,vsize);
490 tab_text (this->t, 1, 0, TAB_CENTER | TAT_TITLE, _("N"));
491 tab_text (this->t, 2, 0, TAB_CENTER | TAT_TITLE, _("Mean"));
492 tab_text (this->t, 3, 0, TAB_CENTER | TAT_TITLE, _("Std. Deviation"));
493 tab_text (this->t, 4, 0, TAB_CENTER | TAT_TITLE, _("SE. Mean"));
496 void ssbox_independent_samples_populate(struct ssbox *ssb,
497 struct cmd_t_test *cmd);
499 /* Initialize the independent samples ssbox */
501 ssbox_independent_samples_init(struct ssbox *this,
502 struct cmd_t_test *cmd)
505 int vsize = cmd->n_variables*2 +1;
507 this->populate = ssbox_independent_samples_populate;
509 ssbox_base_init(this, hsize,vsize);
510 tab_title (this->t, 0, _("Group Statistics"));
511 tab_vline(this->t,0,1,0,vsize);
512 tab_text (this->t, 1, 0, TAB_CENTER | TAT_TITLE, groups->name);
513 tab_text (this->t, 2, 0, TAB_CENTER | TAT_TITLE, _("N"));
514 tab_text (this->t, 3, 0, TAB_CENTER | TAT_TITLE, _("Mean"));
515 tab_text (this->t, 4, 0, TAB_CENTER | TAT_TITLE, _("Std. Deviation"));
516 tab_text (this->t, 5, 0, TAB_CENTER | TAT_TITLE, _("SE. Mean"));
520 /* Populate the ssbox for independent samples */
522 ssbox_independent_samples_populate(struct ssbox *ssb,
523 struct cmd_t_test *cmd)
530 if ( groups->type == NUMERIC )
532 val_lab1 = val_labs_find( groups->val_labs,groups_values[0]);
533 val_lab2 = val_labs_find( groups->val_labs,groups_values[1]);
537 val_lab1 = groups_values[0].s;
538 val_lab2 = groups_values[1].s;
543 for (i=0; i < cmd->n_variables; ++i)
545 tab_text (ssb->t, 0, i*2+1, TAB_LEFT, cmd->v_variables[i]->name);
548 tab_text (ssb->t, 1, i*2+1, TAB_LEFT, val_lab1);
550 tab_float(ssb->t, 1 ,i*2+1, TAB_LEFT, groups_values[0].f, 2,0);
553 tab_text (ssb->t, 1, i*2+1+1, TAB_LEFT, val_lab2);
555 tab_float(ssb->t, 1 ,i*2+1+1, TAB_LEFT, groups_values[1].f,2,0);
560 void ssbox_paired_populate(struct ssbox *ssb,
561 struct cmd_t_test *cmd);
563 /* Initialize the paired values ssbox */
565 ssbox_paired_init(struct ssbox *this, struct cmd_t_test *cmd unused)
569 int vsize = n_pairs*2+1;
571 this->populate = ssbox_paired_populate;
573 ssbox_base_init(this, hsize,vsize);
574 tab_title (this->t, 0, _("Paired Sample Statistics"));
575 tab_vline(this->t,TAL_0,1,0,vsize-1);
576 tab_vline(this->t,TAL_2,2,0,vsize-1);
577 tab_text (this->t, 2, 0, TAB_CENTER | TAT_TITLE, _("Mean"));
578 tab_text (this->t, 3, 0, TAB_CENTER | TAT_TITLE, _("N"));
579 tab_text (this->t, 4, 0, TAB_CENTER | TAT_TITLE, _("Std. Deviation"));
580 tab_text (this->t, 5, 0, TAB_CENTER | TAT_TITLE, _("SE. Mean"));
584 /* Populate the ssbox for paired values */
586 ssbox_paired_populate(struct ssbox *ssb,struct cmd_t_test *cmd unused)
592 ds_init(t_test_pool,&ds,15);
594 for (i=0; i < n_pairs; ++i)
598 ds_printf(&ds,_("Pair %d"),i);
600 tab_text (ssb->t, 0, i*2+1, TAB_LEFT, ds.string);
601 tab_text (ssb->t, 1, i*2+1, TAB_LEFT, pairs[i][0]->name);
602 tab_text (ssb->t, 1, i*2+2, TAB_LEFT, pairs[i][1]->name);
608 /* Populate the one sample ssbox */
610 ssbox_one_sample_populate(struct ssbox *ssb, struct cmd_t_test *cmd)
616 for (i=0; i < cmd->n_variables; ++i)
618 tab_text (ssb->t, 0, i+1, TAB_LEFT, cmd->v_variables[i]->name);
625 /* Implementation of the Test Results box struct */
627 void trbox_base_init(struct trbox *self,int n_vars, int cols);
628 void trbox_base_finalize(struct trbox *trb);
630 void trbox_independent_samples_init(struct trbox *trb,
631 struct cmd_t_test *cmd );
633 void trbox_independent_samples_populate(struct trbox *trb,
634 struct cmd_t_test *cmd);
636 void trbox_one_sample_init(struct trbox *self,
637 struct cmd_t_test *cmd );
639 void trbox_one_sample_populate(struct trbox *trb,
640 struct cmd_t_test *cmd);
642 void trbox_paired_init(struct trbox *self,
643 struct cmd_t_test *cmd );
645 void trbox_paired_populate(struct trbox *trb,
646 struct cmd_t_test *cmd);
650 /* Create a trbox according to mode*/
652 trbox_create(struct trbox *trb,
653 struct cmd_t_test *cmd, int mode)
658 trbox_one_sample_init(trb,cmd);
661 trbox_independent_samples_init(trb,cmd);
664 trbox_paired_init(trb,cmd);
671 /* Populate a trbox according to cmd */
673 trbox_populate(struct trbox *trb, struct cmd_t_test *cmd)
675 trb->populate(trb,cmd);
678 /* Submit and destroy a trbox */
680 trbox_finalize(struct trbox *trb)
685 /* Initialize the independent samples trbox */
687 trbox_independent_samples_init(struct trbox *self,
688 struct cmd_t_test *cmd unused)
691 const int vsize=cmd->n_variables*2+3;
696 self->populate = trbox_independent_samples_populate;
698 trbox_base_init(self,cmd->n_variables*2,hsize);
699 tab_title(self->t,0,_("Independent Samples Test"));
700 tab_hline(self->t,TAL_1,2,hsize-1,1);
701 tab_vline(self->t,TAL_2,2,0,vsize-1);
702 tab_vline(self->t,TAL_1,4,0,vsize-1);
703 tab_box(self->t,-1,-1,-1,TAL_1, 2,1,hsize-2,vsize-1);
704 tab_hline(self->t,TAL_1, hsize-2,hsize-1,2);
705 tab_box(self->t,-1,-1,-1,TAL_1, hsize-2,2,hsize-1,vsize-1);
706 tab_joint_text(self->t, 2, 0, 3, 0,
707 TAB_CENTER,_("Levine's Test for Equality of Variances"));
708 tab_joint_text(self->t, 4,0,hsize-1,0,
709 TAB_CENTER,_("t-test for Equality of Means"));
711 tab_text(self->t,2,2, TAB_CENTER | TAT_TITLE,_("F"));
712 tab_text(self->t,3,2, TAB_CENTER | TAT_TITLE,_("Sig."));
713 tab_text(self->t,4,2, TAB_CENTER | TAT_TITLE,_("t"));
714 tab_text(self->t,5,2, TAB_CENTER | TAT_TITLE,_("df"));
715 tab_text(self->t,6,2, TAB_CENTER | TAT_TITLE,_("Sig. (2-tailed)"));
716 tab_text(self->t,7,2, TAB_CENTER | TAT_TITLE,_("Mean Difference"));
717 tab_text(self->t,8,2, TAB_CENTER | TAT_TITLE,_("Std. Error Difference"));
718 tab_text(self->t,9,2, TAB_CENTER | TAT_TITLE,_("Lower"));
719 tab_text(self->t,10,2, TAB_CENTER | TAT_TITLE,_("Upper"));
721 ds_init(t_test_pool,&ds,80);
723 ds_printf(&ds,_("%d%% Confidence Interval of the Difference"),
724 (int)round(cmd->criteria*100.0));
726 tab_joint_text(self->t,9,1,10,1,TAB_CENTER, ds.string);
731 /* Populate the independent samples trbox */
733 trbox_independent_samples_populate(struct trbox *self,
734 struct cmd_t_test *cmd )
739 for (i=0; i < cmd->n_variables; ++i)
741 tab_text (self->t, 0, i*2+3, TAB_LEFT, cmd->v_variables[i]->name);
743 tab_text (self->t, 1, i*2+3, TAB_LEFT, _("Equal variances assumed"));
745 tab_text (self->t, 1, i*2+3+1,
746 TAB_LEFT, _("Equal variances not assumed"));
750 /* Initialize the paired samples trbox */
752 trbox_paired_init(struct trbox *self,
753 struct cmd_t_test *cmd unused)
757 const int vsize=n_pairs*2+3;
761 self->populate = trbox_paired_populate;
763 trbox_base_init(self,n_pairs*2,hsize);
764 tab_title (self->t, 0, _("Paired Samples Test"));
765 tab_hline(self->t,TAL_1,2,6,1);
766 tab_vline(self->t,TAL_2,2,0,vsize);
767 tab_joint_text(self->t,2,0,6,0,TAB_CENTER,_("Paired Differences"));
768 tab_box(self->t,-1,-1,-1,TAL_1, 2,1,6,vsize-1);
769 tab_box(self->t,-1,-1,-1,TAL_1, 6,0,hsize-1,vsize-1);
770 tab_hline(self->t,TAL_1,5,6, 2);
771 tab_vline(self->t,TAL_0,6,0,1);
773 ds_init(t_test_pool,&ds,80);
775 ds_printf(&ds,_("%d%% Confidence Interval of the Difference"),
776 (int)round(cmd->criteria*100.0));
778 tab_joint_text(self->t,5,1,6,1,TAB_CENTER, ds.string);
782 tab_text (self->t, 2, 2, TAB_CENTER | TAT_TITLE, _("Mean"));
783 tab_text (self->t, 3, 2, TAB_CENTER | TAT_TITLE, _("Std. Deviation"));
784 tab_text (self->t, 4, 2, TAB_CENTER | TAT_TITLE, _("Std. Error Mean"));
785 tab_text (self->t, 5, 2, TAB_CENTER | TAT_TITLE, _("Lower"));
786 tab_text (self->t, 6, 2, TAB_CENTER | TAT_TITLE, _("Upper"));
787 tab_text (self->t, 7, 2, TAB_CENTER | TAT_TITLE, _("t"));
788 tab_text (self->t, 8, 2, TAB_CENTER | TAT_TITLE, _("df"));
789 tab_text (self->t, 9, 2, TAB_CENTER | TAT_TITLE, _("Sig. (2-tailed)"));
792 /* Populate the paired samples trbox */
794 trbox_paired_populate(struct trbox *trb,
795 struct cmd_t_test *cmd unused)
800 ds_init(t_test_pool,&ds,15);
802 for (i=0; i < n_pairs; ++i)
805 ds_printf(&ds,_("Pair %d"),i);
807 tab_text (trb->t, 0, i*2+3, TAB_LEFT, ds.string);
808 tab_text (trb->t, 1, i*2+3, TAB_LEFT, pairs[i][0]->name);
809 tab_text (trb->t, 1, i*2+4, TAB_LEFT, pairs[i][1]->name);
814 /* Initialize the one sample trbox */
816 trbox_one_sample_init(struct trbox *self, struct cmd_t_test *cmd )
819 const int vsize=cmd->n_variables+3;
823 self->populate = trbox_one_sample_populate;
825 trbox_base_init(self, cmd->n_variables,hsize);
826 tab_title (self->t, 0, _("One-Sample Test"));
827 tab_hline(self->t, TAL_1, 1, hsize - 1, 1);
828 tab_vline(self->t, TAL_2, 1, 0, vsize);
829 ds_init(t_test_pool, &ds, 80);
830 ds_printf(&ds,_("Test Value = %f"),cmd->n_testval);
831 tab_joint_text(self->t, 1, 0, hsize-1,0, TAB_CENTER,ds.string);
832 tab_box(self->t, -1, -1, -1, TAL_1, 1,1,hsize-1,vsize-1);
835 ds_printf(&ds,_("%d%% Confidence Interval of the Difference"),
836 (int)round(cmd->criteria*100.0));
837 tab_joint_text(self->t,5,1,6,1,TAB_CENTER, ds.string);
839 tab_vline(self->t,TAL_0,6,1,1);
840 tab_hline(self->t,TAL_1,5,6,2);
841 tab_text (self->t, 1, 2, TAB_CENTER | TAT_TITLE, _("t"));
842 tab_text (self->t, 2, 2, TAB_CENTER | TAT_TITLE, _("df"));
843 tab_text (self->t, 3, 2, TAB_CENTER | TAT_TITLE, _("Sig. (2-tailed)"));
844 tab_text (self->t, 4, 2, TAB_CENTER | TAT_TITLE, _("Mean Difference"));
845 tab_text (self->t, 5, 2, TAB_CENTER | TAT_TITLE, _("Lower"));
846 tab_text (self->t, 6, 2, TAB_CENTER | TAT_TITLE, _("Upper"));
850 /* Populate the one sample trbox */
852 trbox_one_sample_populate(struct trbox *trb, struct cmd_t_test *cmd)
858 for (i=0; i < cmd->n_variables; ++i)
860 tab_text (trb->t, 0, i+3, TAB_LEFT, cmd->v_variables[i]->name);
864 /* Base initializer for the generalized trbox */
866 trbox_base_init(struct trbox *self, int data_rows, int cols)
868 const int rows = 3 + data_rows;
870 self->finalize = trbox_base_finalize;
871 self->t = tab_create (cols, rows, 0);
872 tab_headers (self->t,0,0,3,0);
873 tab_box (self->t, TAL_2, TAL_2, TAL_0, TAL_0, 0, 0, cols -1, rows -1);
874 tab_hline(self->t, TAL_2,0,cols-1,3);
875 tab_dim (self->t, tab_natural_dimensions);
879 /* Base finalizer for the trbox */
881 trbox_base_finalize(struct trbox *trb)