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;
141 if (!lex_force_match_id ("T"))
145 lex_match_id ("TEST");
147 if ( !parse_t_test(&cmd) )
151 if (! cmd.sbc_criteria)
155 if ( cmd.sbc_testval + cmd.sbc_groups + cmd.sbc_pairs != 1 )
158 _("Exactly one of TESTVAL, GROUPS or PAIRS subcommands is required")
165 else if (cmd.sbc_groups)
170 if ( mode == T_PAIRED && cmd.sbc_variables)
172 msg(SE, _("VARIABLES subcommand is not appropriate with PAIRS"));
178 t_test_pool = pool_create ();
180 ssbox_create(&stat_summary_box,&cmd,mode);
181 trbox_create(&test_results_box,&cmd,mode);
183 ssbox_populate(&stat_summary_box,&cmd);
184 trbox_populate(&test_results_box,&cmd);
186 ssbox_finalize(&stat_summary_box);
187 trbox_finalize(&test_results_box);
189 pool_destroy (t_test_pool);
199 tts_custom_groups (struct cmd_t_test *cmd unused)
203 if (token != T_ALL &&
204 (token != T_ID || dict_lookup_var (default_dict, tokid) == NULL)
207 msg(SE,_("`%s' is not a variable name"),tokid);
211 groups = parse_variable ();
214 lex_error ("expecting variable name in GROUPS subcommand");
218 if (groups->type == T_STRING && groups->width > MAX_SHORT_STRING)
220 msg (SE, _("Long string variable %s is not valid here."),
225 if (!lex_match ('('))
228 if (groups->type == NUMERIC)
231 groups_values[0].f = 1;
232 groups_values[1].f = 2;
237 msg (SE, _("When applying GROUPS to a string variable, at "
238 "least one value must be specified."));
243 if (!parse_value (&groups_values[0],groups->type))
252 if (!parse_value (&groups_values[1],groups->type))
256 if (!lex_force_match (')'))
263 tts_custom_pairs (struct cmd_t_test *cmd unused)
265 struct variable **vars;
268 int n_after_WITH =-1;
269 int paired ; /* Was the PAIRED keyword given ? */
273 if ((token != T_ID || dict_lookup_var (default_dict, tokid) == NULL)
276 msg(SE,_("`%s' is not a variable name"),tokid);
281 if (!parse_variables (default_dict, &vars, &n_vars,
282 PV_DUPLICATE | PV_NUMERIC | PV_NO_SCRATCH))
292 if (lex_match (T_WITH))
294 n_before_WITH = n_vars;
296 if (!parse_variables (default_dict, &vars, &n_vars,
297 PV_DUPLICATE | PV_APPEND
298 | PV_NUMERIC | PV_NO_SCRATCH))
304 n_after_WITH = n_vars - n_before_WITH;
308 paired = (lex_match ('(') && lex_match_id ("PAIRED") && lex_match (')'));
311 /* Determine the number of pairs needed */
315 if (n_before_WITH != n_after_WITH)
318 msg (SE, _("PAIRED was specified but the number of variables "
319 "preceding WITH (%d) did not match the number "
321 n_before_WITH, n_after_WITH );
325 n_pairs=n_before_WITH;
328 else if (n_before_WITH > 0) /* WITH keyword given, but not PAIRED keyword */
330 n_pairs=n_before_WITH * n_after_WITH ;
332 else /* Neither WITH nor PAIRED keyword given */
337 msg (SE, _("At least two variables must be specified "
342 /* how many ways can you pick 2 from n_vars ? */
343 n_pairs = n_vars * (n_vars -1 ) /2 ;
346 /* Allocate storage for the pairs */
348 pairs = xrealloc(pairs,sizeof(pair_t) *n_pairs);
351 /* Populate the pairs with the appropriate variables */
357 assert(n_pairs == n_vars/2);
358 for (i = 0; i < n_pairs ; ++i)
360 pairs[i][0] = vars[i];
361 pairs[i][1] = vars[i+n_pairs];
364 else if (n_before_WITH > 0) /* WITH keyword given, but not PAIRED keyword */
369 for(i=0 ; i < n_before_WITH ; ++i )
371 for(j=0 ; j < n_after_WITH ; ++j)
373 pairs[p][0] = vars[i];
374 pairs[p][1] = vars[j+n_before_WITH];
379 else /* Neither WITH nor PAIRED given */
384 for(i=0 ; i < n_vars ; ++i )
386 for(j=i+1 ; j < n_vars ; ++j)
388 pairs[p][0] = vars[i];
389 pairs[p][1] = vars[j];
399 /* Parses the current token (numeric or string, depending on type)
400 value v and returns success. */
402 parse_value (union value * v, int type )
406 if (!lex_force_num ())
412 if (!lex_force_string ())
414 strncpy (v->s, ds_value (&tokstr), ds_length (&tokstr));
423 /* *******************************************************************
426 ***************************************************************** */
430 void ssbox_base_init(struct ssbox *this, int cols,int rows);
432 void ssbox_base_finalize(struct ssbox *ssb);
434 void ssbox_one_sample_init(struct ssbox *this,
435 struct cmd_t_test *cmd );
437 void ssbox_independent_samples_init(struct ssbox *this,
438 struct cmd_t_test *cmd);
440 void ssbox_paired_init(struct ssbox *this,
441 struct cmd_t_test *cmd);
443 /* Factory to create an ssbox */
445 ssbox_create(struct ssbox *ssb, struct cmd_t_test *cmd, int mode)
451 ssbox_one_sample_init(ssb,cmd);
454 ssbox_independent_samples_init(ssb,cmd);
457 ssbox_paired_init(ssb,cmd);
467 ssbox_populate(struct ssbox *ssb,struct cmd_t_test *cmd)
469 ssb->populate(ssb,cmd);
474 ssbox_finalize(struct ssbox *ssb)
482 ssbox_base_finalize(struct ssbox *ssb)
489 ssbox_base_init(struct ssbox *this, int cols,int rows)
491 this->finalize = ssbox_base_finalize;
492 this->t = tab_create (cols, rows, 0);
494 tab_columns (this->t, SOM_COL_DOWN, 1);
496 tab_headers (this->t,0,0,1,0);
498 tab_box (this->t, TAL_2, TAL_2, TAL_0, TAL_1, 0, 0, cols -1, rows -1 );
500 tab_hline(this->t, TAL_2,0,cols-1,1);
502 tab_dim (this->t, tab_natural_dimensions);
508 void ssbox_one_sample_populate(struct ssbox *ssb,
509 struct cmd_t_test *cmd);
514 ssbox_one_sample_init(struct ssbox *this,
515 struct cmd_t_test *cmd )
518 const int vsize=cmd->n_variables+1;
520 this->populate = ssbox_one_sample_populate;
522 ssbox_base_init(this, hsize,vsize);
525 tab_title (this->t, 0, _("One-Sample Statistics"));
527 tab_vline(this->t, TAL_2, 1,0,vsize);
529 tab_text (this->t, 1, 0, TAB_CENTER | TAT_TITLE, _("N"));
530 tab_text (this->t, 2, 0, TAB_CENTER | TAT_TITLE, _("Mean"));
531 tab_text (this->t, 3, 0, TAB_CENTER | TAT_TITLE, _("Std. Deviation"));
532 tab_text (this->t, 4, 0, TAB_CENTER | TAT_TITLE, _("SE. Mean"));
538 void ssbox_independent_samples_populate(struct ssbox *ssb,
539 struct cmd_t_test *cmd);
543 ssbox_independent_samples_init(struct ssbox *this,
544 struct cmd_t_test *cmd)
548 int vsize = cmd->n_variables*2 +1;
550 this->populate = ssbox_independent_samples_populate;
552 ssbox_base_init(this, hsize,vsize);
554 tab_title (this->t, 0, _("Group Statistics"));
556 tab_vline(this->t,0,1,0,vsize);
558 tab_text (this->t, 1, 0, TAB_CENTER | TAT_TITLE, groups->name);
560 tab_text (this->t, 2, 0, TAB_CENTER | TAT_TITLE, _("N"));
561 tab_text (this->t, 3, 0, TAB_CENTER | TAT_TITLE, _("Mean"));
562 tab_text (this->t, 4, 0, TAB_CENTER | TAT_TITLE, _("Std. Deviation"));
563 tab_text (this->t, 5, 0, TAB_CENTER | TAT_TITLE, _("SE. Mean"));
570 ssbox_independent_samples_populate(struct ssbox *ssb,
571 struct cmd_t_test *cmd)
578 if ( groups->type == NUMERIC )
580 val_lab1 = val_labs_find( groups->val_labs,groups_values[0]);
581 val_lab2 = val_labs_find( groups->val_labs,groups_values[1]);
585 val_lab1 = groups_values[0].s;
586 val_lab2 = groups_values[1].s;
592 for (i=0; i < cmd->n_variables; ++i)
594 tab_text (ssb->t, 0, i*2+1,
595 TAB_LEFT, cmd->v_variables[i]->name);
598 tab_text (ssb->t, 1, i*2+1,
601 tab_float(ssb->t, 1 ,i*2+1,
602 TAB_LEFT, groups_values[0].f, 2,0);
606 tab_text (ssb->t, 1, i*2+1+1,
609 tab_float(ssb->t, 1 ,i*2+1+1,
610 TAB_LEFT, groups_values[1].f,2,0);
618 void ssbox_paired_populate(struct ssbox *ssb,
619 struct cmd_t_test *cmd);
623 ssbox_paired_init(struct ssbox *this,
624 struct cmd_t_test *cmd unused)
628 int vsize = n_pairs*2+1;
630 this->populate = ssbox_paired_populate;
632 ssbox_base_init(this, hsize,vsize);
634 tab_title (this->t, 0, _("Paired Sample Statistics"));
636 tab_vline(this->t,TAL_0,1,0,vsize-1);
637 tab_vline(this->t,TAL_2,2,0,vsize-1);
639 tab_text (this->t, 2, 0, TAB_CENTER | TAT_TITLE, _("Mean"));
640 tab_text (this->t, 3, 0, TAB_CENTER | TAT_TITLE, _("N"));
641 tab_text (this->t, 4, 0, TAB_CENTER | TAT_TITLE, _("Std. Deviation"));
642 tab_text (this->t, 5, 0, TAB_CENTER | TAT_TITLE, _("SE. Mean"));
649 ssbox_paired_populate(struct ssbox *ssb,
650 struct cmd_t_test *cmd unused)
657 ds_init(t_test_pool,&ds,15);
660 for (i=0; i < n_pairs; ++i)
665 ds_printf(&ds,_("Pair %d"),i);
667 tab_text (ssb->t, 0, i*2+1, TAB_LEFT, ds.string);
669 tab_text (ssb->t, 1, i*2+1, TAB_LEFT, pairs[i][0]->name);
670 tab_text (ssb->t, 1, i*2+2, TAB_LEFT, pairs[i][1]->name);
678 ssbox_one_sample_populate(struct ssbox *ssb,
679 struct cmd_t_test *cmd)
685 for (i=0; i < cmd->n_variables; ++i)
687 tab_text (ssb->t, 0, i+1,
688 TAB_LEFT, cmd->v_variables[i]->name);
694 /* ****************************************************************
696 TEST RESULT BOX Implementation
698 *****************************************************************/
700 void trbox_base_init(struct trbox *self,int n_vars, int cols);
701 void trbox_base_finalize(struct trbox *trb);
703 void trbox_independent_samples_init(struct trbox *trb,
704 struct cmd_t_test *cmd );
706 void trbox_independent_samples_populate(struct trbox *trb,
707 struct cmd_t_test *cmd);
709 void trbox_one_sample_init(struct trbox *self,
710 struct cmd_t_test *cmd );
712 void trbox_one_sample_populate(struct trbox *trb,
713 struct cmd_t_test *cmd);
715 void trbox_paired_init(struct trbox *self,
716 struct cmd_t_test *cmd );
718 void trbox_paired_populate(struct trbox *trb,
719 struct cmd_t_test *cmd);
725 trbox_create(struct trbox *trb,
726 struct cmd_t_test *cmd, int mode)
732 trbox_one_sample_init(trb,cmd);
737 trbox_independent_samples_init(trb,cmd);
742 trbox_paired_init(trb,cmd);
751 /* Populate a trbox according to cmd */
753 trbox_populate(struct trbox *trb, struct cmd_t_test *cmd)
755 trb->populate(trb,cmd);
758 /* Submit and destroy a trbox */
760 trbox_finalize(struct trbox *trb)
767 trbox_independent_samples_init(struct trbox *self,
768 struct cmd_t_test *cmd unused)
771 const int vsize=cmd->n_variables*2+3;
777 self->populate = trbox_independent_samples_populate;
779 trbox_base_init(self,cmd->n_variables*2,hsize);
781 tab_title(self->t,0,_("Independent Samples Test"));
783 tab_hline(self->t,TAL_1,2,hsize-1,1);
784 tab_vline(self->t,TAL_2,2,0,vsize-1);
786 tab_vline(self->t,TAL_1,4,0,vsize-1);
788 tab_box(self->t,-1,-1,-1,TAL_1,
789 2,1,hsize-2,vsize-1);
792 tab_hline(self->t,TAL_1,
795 tab_box(self->t,-1,-1,-1,TAL_1,
796 hsize-2,2,hsize-1,vsize-1);
799 tab_joint_text(self->t, 2,0,3,0,
800 TAB_CENTER,_("Levine's Test for Equality of Variances"));
802 tab_joint_text(self->t, 4,0,hsize-1,0,
803 TAB_CENTER,_("t-test for Equality of Means"));
806 tab_text(self->t,2,2, TAB_CENTER | TAT_TITLE,_("F"));
807 tab_text(self->t,3,2, TAB_CENTER | TAT_TITLE,_("Sig."));
808 tab_text(self->t,4,2, TAB_CENTER | TAT_TITLE,_("t"));
809 tab_text(self->t,5,2, TAB_CENTER | TAT_TITLE,_("df"));
810 tab_text(self->t,6,2, TAB_CENTER | TAT_TITLE,_("Sig. (2-tailed)"));
811 tab_text(self->t,7,2, TAB_CENTER | TAT_TITLE,_("Mean Difference"));
812 tab_text(self->t,8,2, TAB_CENTER | TAT_TITLE,_("Std. Error Difference"));
813 tab_text(self->t,9,2, TAB_CENTER | TAT_TITLE,_("Lower"));
814 tab_text(self->t,10,2, TAB_CENTER | TAT_TITLE,_("Upper"));
817 ds_init(t_test_pool,&ds,80);
819 ds_printf(&ds,_("%d%% Confidence Interval of the Difference"),
820 (int)round(cmd->criteria*100.0));
822 tab_joint_text(self->t,9,1,10,1,TAB_CENTER,
833 trbox_independent_samples_populate(struct trbox *self,
834 struct cmd_t_test *cmd )
840 for (i=0; i < cmd->n_variables; ++i)
842 tab_text (self->t, 0, i*2+3,
843 TAB_LEFT, cmd->v_variables[i]->name);
845 tab_text (self->t, 1, i*2+3,
846 TAB_LEFT, _("Equal variances assumed"));
848 tab_text (self->t, 1, i*2+3+1,
849 TAB_LEFT, _("Equal variances not assumed"));
858 trbox_paired_init(struct trbox *self,
859 struct cmd_t_test *cmd unused)
863 const int vsize=n_pairs*2+3;
867 self->populate = trbox_paired_populate;
869 trbox_base_init(self,n_pairs*2,hsize);
872 tab_title (self->t, 0, _("Paired Samples Test"));
875 tab_hline(self->t,TAL_1,2,6,1);
876 tab_vline(self->t,TAL_2,2,0,vsize);
880 tab_joint_text(self->t,2,0,6,0,TAB_CENTER,_("Paired Differences"));
883 tab_box(self->t,-1,-1,-1,TAL_1,
887 tab_box(self->t,-1,-1,-1,TAL_1,
888 6,0,hsize-1,vsize-1);
892 tab_hline(self->t,TAL_1,5,6, 2);
893 tab_vline(self->t,TAL_0,6,0,1);
896 ds_init(t_test_pool,&ds,80);
898 ds_printf(&ds,_("%d%% Confidence Interval of the Difference"),
899 (int)round(cmd->criteria*100.0));
901 tab_joint_text(self->t,5,1,6,1,TAB_CENTER,
907 tab_text (self->t, 2, 2, TAB_CENTER | TAT_TITLE, _("Mean"));
908 tab_text (self->t, 3, 2, TAB_CENTER | TAT_TITLE, _("Std. Deviation"));
909 tab_text (self->t, 4, 2, TAB_CENTER | TAT_TITLE, _("Std. Error Mean"));
910 tab_text (self->t, 5, 2, TAB_CENTER | TAT_TITLE, _("Lower"));
911 tab_text (self->t, 6, 2, TAB_CENTER | TAT_TITLE, _("Upper"));
912 tab_text (self->t, 7, 2, TAB_CENTER | TAT_TITLE, _("t"));
913 tab_text (self->t, 8, 2, TAB_CENTER | TAT_TITLE, _("df"));
914 tab_text (self->t, 9, 2, TAB_CENTER | TAT_TITLE, _("Sig. (2-tailed)"));
926 trbox_paired_populate(struct trbox *trb,
927 struct cmd_t_test *cmd unused)
933 ds_init(t_test_pool,&ds,15);
935 for (i=0; i < n_pairs; ++i)
940 ds_printf(&ds,_("Pair %d"),i);
942 tab_text (trb->t, 0, i*2+3, TAB_LEFT, ds.string);
944 tab_text (trb->t, 1, i*2+3, TAB_LEFT, pairs[i][0]->name);
945 tab_text (trb->t, 1, i*2+4, TAB_LEFT, pairs[i][1]->name);
955 trbox_one_sample_init(struct trbox *self,
956 struct cmd_t_test *cmd )
959 const int vsize=cmd->n_variables+3;
963 self->populate = trbox_one_sample_populate;
965 trbox_base_init(self,cmd->n_variables,hsize);
968 tab_title (self->t, 0, _("One-Sample Test"));
970 tab_hline(self->t,TAL_1,1,hsize-1,1);
971 tab_vline(self->t,TAL_2,1,0,vsize);
973 ds_init(t_test_pool,&ds,80);
975 ds_printf(&ds,_("Test Value = %f"),cmd->n_testval);
977 tab_joint_text(self->t,1,0,hsize-1,0,TAB_CENTER,ds.string);
979 tab_box(self->t,-1,-1,-1,TAL_1,
980 1,1,hsize-1,vsize-1);
985 ds_printf(&ds,_("%d%% Confidence Interval of the Difference"),
986 (int)round(cmd->criteria*100.0));
988 tab_joint_text(self->t,5,1,6,1,TAB_CENTER,
993 tab_vline(self->t,TAL_0,6,1,1);
994 tab_hline(self->t,TAL_1,5,6,2);
997 tab_text (self->t, 1, 2, TAB_CENTER | TAT_TITLE, _("t"));
998 tab_text (self->t, 2, 2, TAB_CENTER | TAT_TITLE, _("df"));
999 tab_text (self->t, 3, 2, TAB_CENTER | TAT_TITLE, _("Sig. (2-tailed)"));
1000 tab_text (self->t, 4, 2, TAB_CENTER | TAT_TITLE, _("Mean Difference"));
1001 tab_text (self->t, 5, 2, TAB_CENTER | TAT_TITLE, _("Lower"));
1002 tab_text (self->t, 6, 2, TAB_CENTER | TAT_TITLE, _("Upper"));
1010 trbox_one_sample_populate(struct trbox *trb,
1011 struct cmd_t_test *cmd)
1017 for (i=0; i < cmd->n_variables; ++i)
1019 tab_text (trb->t, 0, i+3,
1020 TAB_LEFT, cmd->v_variables[i]->name);
1027 trbox_base_init(struct trbox *self, int data_rows,int cols)
1029 const int rows=3+data_rows;
1031 self->finalize = trbox_base_finalize;
1032 self->t = tab_create (cols, rows, 0);
1035 tab_headers (self->t,0,0,3,0);
1038 tab_box (self->t, TAL_2, TAL_2, TAL_0, TAL_0, 0, 0, cols -1, rows -1);
1040 tab_hline(self->t, TAL_2,0,cols-1,3);
1042 tab_dim (self->t, tab_natural_dimensions);
1048 trbox_base_finalize(struct trbox *trb)