From 3c52a21736b3777ced3e47148fa2fc8f9eff59c8 Mon Sep 17 00:00:00 2001 From: John Darrington Date: Fri, 3 Apr 2009 18:16:57 +0800 Subject: [PATCH] Binomial tests can now be specified by a cutpoint. This change extends the NPAR TEST /BINOMIAL subcommand so that binomial tests can be specified by cutpoint. The manual had previously, incorrectly stated that this was supported. Now it actually is. Fixes bug #26056 --- src/language/stats/binomial.c | 57 ++++++++++++++++++++++++---------- src/language/stats/npar.q | 27 +++++++--------- tests/command/npar-binomial.sh | 48 ++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+), 31 deletions(-) diff --git a/src/language/stats/binomial.c b/src/language/stats/binomial.c index b62b4dce..b7b672ef 100644 --- a/src/language/stats/binomial.c +++ b/src/language/stats/binomial.c @@ -114,22 +114,32 @@ do_binomial (const struct dictionary *dict, if (var_is_value_missing (var, value, exclude)) continue; - if ( NULL == cat1[v].value ) + if (bst->cutpoint != SYSMIS) { - cat1[v].value = value_dup (value, width); - cat1[v].count = w; + if ( compare_values_short (cat1[v].value, value, var) >= 0 ) + cat1[v].count += w; + else + cat2[v].count += w; } - else if ( 0 == compare_values_short (cat1[v].value, value, var)) - cat1[v].count += w; - else if ( NULL == cat2[v].value ) + else { - cat2[v].value = value_dup (value, width); - cat2[v].count = w; + if ( NULL == cat1[v].value ) + { + cat1[v].value = value_dup (value, width); + cat1[v].count = w; + } + else if ( 0 == compare_values_short (cat1[v].value, value, var)) + cat1[v].count += w; + else if ( NULL == cat2[v].value ) + { + cat2[v].value = value_dup (value, width); + cat2[v].count = w; + } + else if ( 0 == compare_values_short (cat2[v].value, value, var)) + cat2[v].count += w; + else if ( bst->category1 == SYSMIS) + msg (ME, _("Variable %s is not dichotomous"), var_get_name (var)); } - else if ( 0 == compare_values_short (cat2[v].value, value, var)) - cat2[v].count += w; - else if ( bst->category1 == SYSMIS) - msg (ME, _("Variable %s is not dichotomous"), var_get_name (var)); } case_unref (c); @@ -154,9 +164,17 @@ binomial_execute (const struct dataset *ds, struct freq_mutable *cat1 = xzalloc (sizeof (*cat1) * ost->n_vars); struct freq_mutable *cat2 = xzalloc (sizeof (*cat1) * ost->n_vars); - assert ((bst->category1 == SYSMIS) == (bst->category2 == SYSMIS) ); + assert ((bst->category1 == SYSMIS) == (bst->category2 == SYSMIS) || bst->cutpoint != SYSMIS); - if ( bst->category1 != SYSMIS ) + if ( bst->cutpoint != SYSMIS ) + { + int i; + union value v; + v.f = bst->cutpoint; + for (i = 0; i < ost->n_vars; i++) + cat1[i].value = value_dup (&v, 0); + } + else if ( bst->category1 != SYSMIS ) { int i; union value v; @@ -197,8 +215,15 @@ binomial_execute (const struct dataset *ds, ds_init_empty (&catstr1); ds_init_empty (&catstr2); - var_append_value_name (var, cat1[v].value, &catstr1); - var_append_value_name (var, cat2[v].value, &catstr2); + if ( bst->cutpoint != SYSMIS) + { + ds_put_format (&catstr1, "<= %g", bst->cutpoint); + } + else + { + var_append_value_name (var, cat1[v].value, &catstr1); + var_append_value_name (var, cat2[v].value, &catstr2); + } tab_hline (table, TAL_1, 0, tab_nc (table) -1, 1 + v * 3); diff --git a/src/language/stats/npar.q b/src/language/stats/npar.q index 34e03677..4caa112a 100644 --- a/src/language/stats/npar.q +++ b/src/language/stats/npar.q @@ -356,27 +356,24 @@ npar_custom_binomial (struct lexer *lexer, struct dataset *ds, { lex_force_num (lexer); btp->category1 = lex_number (lexer); - lex_get (lexer); - if ( ! lex_force_match (lexer, ',')) return 2; - if ( ! lex_force_num (lexer) ) return 2; - btp->category2 = lex_number (lexer); - lex_get (lexer); + lex_get (lexer); + if ( lex_match (lexer, ',')) + { + if ( ! lex_force_num (lexer) ) return 2; + btp->category2 = lex_number (lexer); + lex_get (lexer); + } + else + { + btp->cutpoint = btp->category1; + } + lex_force_match (lexer, ')'); } } else return 2; } - else - { - if ( lex_match (lexer, '(') ) - { - lex_force_num (lexer); - btp->cutpoint = lex_number (lexer); - lex_get (lexer); - lex_force_match (lexer, ')'); - } - } specs->n_tests++; specs->test = pool_realloc (specs->pool, diff --git a/tests/command/npar-binomial.sh b/tests/command/npar-binomial.sh index 63696929..29ad2fab 100755 --- a/tests/command/npar-binomial.sh +++ b/tests/command/npar-binomial.sh @@ -208,6 +208,36 @@ WEIGHT BY w. NPAR TESTS /BINOMIAL(0.5) = x . + +ECHO 'P == 0.5; N1/N2 == 1 Cutpoint' . + +DATA LIST LIST NOTABLE /x * w *. +BEGIN DATA. +9 3 +10 7 +11 16 +END DATA. + +WEIGHT BY w. + +NPAR TESTS + /BINOMIAL(0.5) = x (10) + . + +ECHO 'P == 0.5; N1/N2 == 1 Named values' . + +DATA LIST LIST NOTABLE /x * w *. +BEGIN DATA. +10 10 +15 45 +20 13 +END DATA. + +WEIGHT BY w. + +NPAR TESTS + /BINOMIAL(0.5) = x (10, 20) + . EOF if [ $? -ne 0 ] ; then no_result ; fi @@ -300,6 +330,24 @@ P == 0.5; N1/N2 == 1 | |Group2# 2.00|10| .500| | | | |Total # |20| 1.00| | | +-+------#--------+--+--------------+----------+---------------------+ +P == 0.5; N1/N2 == 1 Cutpoint +10.1 NPAR TESTS. Binomial Test ++-+------#--------+--+--------------+----------+---------------------+ +| | #Category| N|Observed Prop.|Test Prop.|Exact Sig. (2-tailed)| ++-+------#--------+--+--------------+----------+---------------------+ +|x|Group1# <= 10|10| .385| .500| .327| +| |Group2# |16| .615| | | +| |Total # |26| 1.00| | | ++-+------#--------+--+--------------+----------+---------------------+ +P == 0.5; N1/N2 == 1 Named values +11.1 NPAR TESTS. Binomial Test ++-+------#--------+--+--------------+----------+---------------------+ +| | #Category| N|Observed Prop.|Test Prop.|Exact Sig. (2-tailed)| ++-+------#--------+--+--------------+----------+---------------------+ +|x|Group1# 10.00|10| .435| .500| .678| +| |Group2# 20.00|13| .565| | | +| |Total # |23| 1.00| | | ++-+------#--------+--+--------------+----------+---------------------+ EOF if [ $? -ne 0 ] ; then fail ; fi -- 2.30.2