2 * analysis-signed-rank-test.c:
5 * Andreas J. Guelzow <aguelzow@pyrshep.ca>
7 * (C) Copyright 2010, 2016 by Andreas J. Guelzow <aguelzow@pyrshep.ca>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see <https://www.gnu.org/licenses/>.
24 #include <gnumeric-config.h>
25 #include <glib/gi18n-lib.h>
27 #include <tools/analysis-signed-rank-test.h>
28 #include <tools/analysis-tools.h>
35 static inline GnmExpr
const *
38 return gnm_expr_new_constant (value_new_int (n
));
40 static inline GnmExpr
const *
41 make_float (gnm_float x
)
43 return gnm_expr_new_constant (value_new_float (x
));
49 analysis_tool_signed_rank_test_engine_run (data_analysis_output_t
*dao
,
50 analysis_tools_data_sign_test_t
*info
)
53 GSList
*data
= info
->base
.input
;
54 gboolean first
= TRUE
;
57 GnmExpr
const *expr_isnumber
;
58 GnmExpr
const *expr_diff
;
59 GnmExpr
const *expr_expect
;
60 GnmExpr
const *expr_var
;
61 GnmExpr
const *expr_abs
;
62 GnmExpr
const *expr_big
;
64 GnmFunc
*fd_median
= analysis_tool_get_function ("MEDIAN", dao
);
65 GnmFunc
*fd_if
= analysis_tool_get_function ("IF", dao
);
66 GnmFunc
*fd_sum
= analysis_tool_get_function ("SUM", dao
);
67 GnmFunc
*fd_min
= analysis_tool_get_function ("MIN", dao
);
68 GnmFunc
*fd_normdist
= analysis_tool_get_function ("NORMDIST", dao
);
69 GnmFunc
*fd_isnumber
= analysis_tool_get_function ("ISNUMBER", dao
);
70 GnmFunc
*fd_iferror
= analysis_tool_get_function ("IFERROR", dao
);
71 GnmFunc
*fd_rank
= analysis_tool_get_function ("RANK.AVG", dao
);
72 GnmFunc
*fd_abs
= analysis_tool_get_function ("ABS", dao
);
73 GnmFunc
*fd_sqrt
= analysis_tool_get_function ("SQRT", dao
);
74 GnmFunc
*fd_max
= analysis_tool_get_function ("MAX", dao
);
76 dao_set_italic (dao
, 0, 0, 0, 9);
77 set_cell_text_col (dao
, 0, 0, _("/Wilcoxon Signed Rank Test"
85 "/P(T\xe2\x89\xa4t) one-tailed"
86 "/P(T\xe2\x89\xa4t) two-tailed"));
88 for (col
= 0; data
!= NULL
; data
= data
->next
, col
++) {
89 GnmValue
*val_org
= value_dup (data
->data
);
90 GnmExpr
const *expr_org
;
92 /* Note that analysis_tools_write_label may modify val_org */
93 dao_set_italic (dao
, col
+ 1, 0, col
+1, 0);
94 analysis_tools_write_label (val_org
, dao
, &info
->base
, col
+ 1, 0, col
+ 1);
95 expr_org
= gnm_expr_new_constant (val_org
);
98 dao_set_cell_float (dao
, col
+ 1, 2, info
->median
);
99 dao_set_cell_float (dao
, col
+ 1, 7, info
->alpha
);
102 dao_set_cell_expr (dao
, col
+ 1, 2, make_cellref (-1,0));
103 dao_set_cell_expr (dao
, col
+ 1, 7, make_cellref (-1,0));
106 expr_isnumber
= gnm_expr_new_funcall3
107 (fd_if
, gnm_expr_new_funcall1
108 (fd_isnumber
, gnm_expr_copy (expr_org
)),
112 expr
= gnm_expr_new_funcall1
114 gnm_expr_copy (expr_org
));
115 dao_set_cell_expr (dao
, col
+ 1, 1, expr
);
117 expr_diff
= gnm_expr_new_binary
118 (gnm_expr_copy (expr_org
), GNM_EXPR_OP_SUB
, make_cellref (0,-2));
119 expr_abs
= gnm_expr_new_funcall1
120 (fd_abs
, gnm_expr_copy (expr_diff
));
121 expr_big
= gnm_expr_new_binary
122 (gnm_expr_new_funcall1
123 (fd_max
, gnm_expr_copy (expr_abs
)),
126 expr
= gnm_expr_new_funcall3
128 gnm_expr_new_funcall1
129 (fd_isnumber
, gnm_expr_copy (expr_org
)),
130 gnm_expr_new_funcall3
133 (gnm_expr_copy (expr_org
),
135 make_cellref (0,-2)),
136 gnm_expr_copy (expr_big
),
139 expr
= gnm_expr_new_funcall3
141 gnm_expr_new_unary (GNM_EXPR_OP_UNARY_NEG
,
146 dao_set_cell_array_expr
148 gnm_expr_new_funcall1
151 (gnm_expr_copy (expr_isnumber
),
153 gnm_expr_new_funcall3
156 (gnm_expr_copy (expr_org
),
158 make_cellref (0,-2)),
162 expr
= gnm_expr_new_funcall1
163 (fd_sum
, gnm_expr_new_binary
164 (expr_isnumber
, GNM_EXPR_OP_MULT
,
165 gnm_expr_new_funcall2
166 (fd_iferror
, gnm_expr_new_funcall3
167 (fd_if
, gnm_expr_new_binary (expr_org
,
168 GNM_EXPR_OP_NOT_EQUAL
, make_cellref (0,-1)),
172 dao_set_cell_array_expr (dao
, col
+ 1, 3, expr
);
174 dao_set_cell_expr (dao
, col
+ 1, 5,
178 (make_cellref (0,-2),
181 (make_cellref (0,-2),
187 make_cellref (0,-1)));
188 dao_set_cell_expr (dao
, col
+ 1, 6,
189 gnm_expr_new_funcall2
190 (fd_min
, make_cellref (0,-1), make_cellref (0,-2)));
192 expr_expect
= gnm_expr_new_binary
194 (make_cellref (0,-5),
197 (make_cellref (0,-5),
202 expr_var
= gnm_expr_new_binary
204 (gnm_expr_copy (expr_expect
),
210 make_cellref (0,-5)),
215 expr
= gnm_expr_new_funcall4
216 (fd_normdist
, gnm_expr_new_binary
217 (make_cellref (0,-2),
221 gnm_expr_new_funcall1 (fd_sqrt
, expr_var
),
222 gnm_expr_new_constant (value_new_bool (TRUE
)));
223 dao_set_cell_expr (dao
, col
+ 1, 8,
224 gnm_expr_new_funcall3
227 (make_cellref (0,-5),
230 gnm_expr_new_constant (value_new_error_NA (NULL
)),
232 dao_set_cell_comment (dao
, col
+ 1, 8,
233 _("This p-value is calculated by a normal approximation.\n"
234 "It is only valid if the sample size is at least 12."));
236 expr
= gnm_expr_new_binary (make_int (2),
237 GNM_EXPR_OP_MULT
, make_cellref (0,-1));
238 dao_set_cell_expr (dao
, col
+ 1, 9, expr
);
241 gnm_func_dec_usage (fd_median
);
242 gnm_func_dec_usage (fd_if
);
243 gnm_func_dec_usage (fd_min
);
244 gnm_func_dec_usage (fd_sum
);
245 gnm_func_dec_usage (fd_normdist
);
246 gnm_func_dec_usage (fd_isnumber
);
247 gnm_func_dec_usage (fd_iferror
);
248 gnm_func_dec_usage (fd_rank
);
249 gnm_func_dec_usage (fd_abs
);
250 gnm_func_dec_usage (fd_sqrt
);
251 gnm_func_dec_usage (fd_max
);
253 dao_redraw_respan (dao
);
259 analysis_tool_signed_rank_test_two_engine_run (data_analysis_output_t
*dao
,
260 analysis_tools_data_sign_test_two_t
*info
)
265 GnmExpr
const *expr_1
;
266 GnmExpr
const *expr_2
;
269 GnmExpr
const *expr_diff
;
270 GnmExpr
const *expr_diff_pred
;
271 GnmExpr
const *expr_isnumber_1
;
272 GnmExpr
const *expr_isnumber_2
;
273 GnmExpr
const *expr_isnumber
;
274 GnmExpr
const *expr_expect
;
275 GnmExpr
const *expr_var
;
276 GnmExpr
const *expr_abs
;
277 GnmExpr
const *expr_big
;
279 GnmFunc
*fd_median
= analysis_tool_get_function ("MEDIAN", dao
);
280 GnmFunc
*fd_if
= analysis_tool_get_function ("IF", dao
);
281 GnmFunc
*fd_sum
= analysis_tool_get_function ("SUM", dao
);
282 GnmFunc
*fd_min
= analysis_tool_get_function ("MIN", dao
);
283 GnmFunc
*fd_normdist
= analysis_tool_get_function ("NORMDIST", dao
);
284 GnmFunc
*fd_isnumber
= analysis_tool_get_function ("ISNUMBER", dao
);
285 GnmFunc
*fd_iferror
= analysis_tool_get_function ("IFERROR", dao
);
286 GnmFunc
*fd_rank
= analysis_tool_get_function ("RANK.AVG", dao
);
287 GnmFunc
*fd_abs
= analysis_tool_get_function ("ABS", dao
);
288 GnmFunc
*fd_sqrt
= analysis_tool_get_function ("SQRT", dao
);
289 GnmFunc
*fd_max
= analysis_tool_get_function ("MAX", dao
);
291 dao_set_italic (dao
, 0, 0, 0, 10);
292 set_cell_text_col (dao
, 0, 0, _("/Wilcoxon Signed Rank Test"
294 "/Observed Median Difference"
295 "/Predicted Median Difference"
301 "/P(T\xe2\x89\xa4t) one-tailed"
302 "/P(T\xe2\x89\xa4t) two-tailed"));
303 val_1
= value_dup (info
->base
.range_1
);
304 val_2
= value_dup (info
->base
.range_2
);
307 dao_set_italic (dao
, 1, 0, 2, 0);
308 analysis_tools_write_label_ftest (val_1
, dao
, 1, 0,
309 info
->base
.labels
, 1);
310 analysis_tools_write_label_ftest (val_2
, dao
, 2, 0,
311 info
->base
.labels
, 2);
313 expr_1
= gnm_expr_new_constant (value_dup (val_1
));
314 expr_2
= gnm_expr_new_constant (value_dup (val_2
));
316 dao_set_cell_float (dao
, 1, 3, info
->median
);
317 dao_set_cell_float (dao
, 1, 8, info
->base
.alpha
);
319 expr_isnumber_1
= gnm_expr_new_funcall3
320 (fd_if
, gnm_expr_new_funcall1
321 (fd_isnumber
, gnm_expr_copy (expr_1
)),
324 expr_isnumber_2
= gnm_expr_new_funcall3
325 (fd_if
, gnm_expr_new_funcall1
326 (fd_isnumber
, gnm_expr_copy (expr_2
)),
329 expr_isnumber
= gnm_expr_new_binary
334 expr
= gnm_expr_new_funcall1
336 gnm_expr_new_funcall3
339 (gnm_expr_copy (expr_isnumber
),
342 gnm_expr_copy (expr_1
),
343 gnm_expr_new_constant (value_new_string(""))));
344 dao_set_cell_array_expr (dao
, 1, 1, expr
);
346 expr
= gnm_expr_new_funcall1
348 gnm_expr_new_funcall3
351 (gnm_expr_copy (expr_isnumber
),
354 gnm_expr_copy (expr_2
),
355 gnm_expr_new_constant (value_new_string(""))));
356 dao_set_cell_array_expr (dao
, 2, 1, expr
);
358 expr_diff
= gnm_expr_new_binary (gnm_expr_copy (expr_1
),
360 gnm_expr_copy (expr_2
));
361 dao_set_cell_array_expr
363 gnm_expr_new_funcall1
365 gnm_expr_new_funcall3
368 (gnm_expr_copy (expr_isnumber
),
371 gnm_expr_copy (expr_diff
),
372 gnm_expr_new_constant (value_new_string("")))));
374 expr
= gnm_expr_new_funcall1
375 (fd_sum
, gnm_expr_new_binary
376 (gnm_expr_copy (expr_isnumber
),
378 gnm_expr_new_funcall2
379 (fd_iferror
, gnm_expr_new_funcall3
380 (fd_if
, gnm_expr_new_binary
381 (gnm_expr_copy (expr_diff
),
382 GNM_EXPR_OP_NOT_EQUAL
, make_cellref (0,-1)),
386 dao_set_cell_array_expr (dao
, 1, 4, expr
);
388 expr_diff_pred
= gnm_expr_new_binary
389 (gnm_expr_copy (expr_diff
),
391 make_cellref (0,-2));
392 expr_abs
= gnm_expr_new_funcall1
393 (fd_abs
, gnm_expr_copy (expr_diff_pred
));
394 expr_big
= gnm_expr_new_binary
395 (gnm_expr_new_funcall1
396 (fd_max
, gnm_expr_copy (expr_abs
)),
399 expr
= gnm_expr_new_funcall3
401 gnm_expr_new_funcall1
402 (fd_isnumber
, expr_1
),
403 gnm_expr_new_funcall3
405 gnm_expr_new_funcall1
406 (fd_isnumber
, expr_2
),
407 gnm_expr_new_funcall3
410 (gnm_expr_copy (expr_diff
),
412 make_cellref (0,-2)),
413 gnm_expr_copy (expr_big
),
415 gnm_expr_copy (expr_big
)),
417 expr
= gnm_expr_new_funcall3
419 gnm_expr_new_unary (GNM_EXPR_OP_UNARY_NEG
,
423 expr
= gnm_expr_new_funcall1
428 gnm_expr_new_funcall3
433 make_cellref (0,-2)),
437 dao_set_cell_array_expr (dao
, 1, 5, expr
);
439 dao_set_cell_expr (dao
, 1, 6,
443 (make_cellref (0,-2),
446 (make_cellref (0,-2),
452 make_cellref (0,-1)));
456 gnm_expr_new_funcall2
457 (fd_min
, make_cellref (0,-1), make_cellref (0,-2)));
459 expr_expect
= gnm_expr_new_binary
461 (make_cellref (0,-5),
464 (make_cellref (0,-5),
469 expr_var
= gnm_expr_new_binary
471 (gnm_expr_copy (expr_expect
),
477 make_cellref (0,-5)),
482 expr
= gnm_expr_new_funcall4
483 (fd_normdist
, gnm_expr_new_binary
484 (make_cellref (0,-2),
488 gnm_expr_new_funcall1 (fd_sqrt
, expr_var
),
489 gnm_expr_new_constant (value_new_bool (TRUE
)));
490 dao_set_cell_expr (dao
, 1, 9,
491 gnm_expr_new_funcall3
494 (make_cellref (0,-5),
497 gnm_expr_new_constant (value_new_error_NA (NULL
)),
501 _("This p-value is calculated by a normal approximation.\n"
502 "It is only valid if the sample size is at least 12."));
504 expr
= gnm_expr_new_binary (make_int (2),
505 GNM_EXPR_OP_MULT
, make_cellref (0,-1));
506 dao_set_cell_array_expr (dao
, 1, 10, expr
);
508 gnm_func_dec_usage (fd_median
);
509 gnm_func_dec_usage (fd_if
);
510 gnm_func_dec_usage (fd_min
);
511 gnm_func_dec_usage (fd_sum
);
512 gnm_func_dec_usage (fd_normdist
);
513 gnm_func_dec_usage (fd_isnumber
);
514 gnm_func_dec_usage (fd_iferror
);
515 gnm_func_dec_usage (fd_rank
);
516 gnm_func_dec_usage (fd_abs
);
517 gnm_func_dec_usage (fd_sqrt
);
518 gnm_func_dec_usage (fd_max
);
520 value_release (val_1
);
521 value_release (val_2
);
523 dao_redraw_respan (dao
);
529 analysis_tool_signed_rank_test_engine (G_GNUC_UNUSED GOCmdContext
*gcc
, data_analysis_output_t
*dao
, gpointer specs
,
530 analysis_tool_engine_t selector
, gpointer result
)
532 analysis_tools_data_sign_test_t
*info
= specs
;
535 case TOOL_ENGINE_UPDATE_DESCRIPTOR
:
536 return (dao_command_descriptor
537 (dao
, _("Wilcoxon Signed Rank Test (%s)"), result
)
539 case TOOL_ENGINE_UPDATE_DAO
:
540 prepare_input_range (&info
->base
.input
, info
->base
.group_by
);
541 dao_adjust (dao
, 1 + g_slist_length (info
->base
.input
), 10);
543 case TOOL_ENGINE_CLEAN_UP
:
544 return analysis_tool_generic_clean (specs
);
545 case TOOL_ENGINE_LAST_VALIDITY_CHECK
:
547 case TOOL_ENGINE_PREPARE_OUTPUT_RANGE
:
548 dao_prepare_output (NULL
, dao
, _("Wilcoxon Signed Rank Test"));
550 case TOOL_ENGINE_FORMAT_OUTPUT_RANGE
:
551 return dao_format_output (dao
, _("Wilcoxon Signed Rank Test"));
552 case TOOL_ENGINE_PERFORM_CALC
:
554 return analysis_tool_signed_rank_test_engine_run (dao
, specs
);
560 analysis_tool_signed_rank_test_two_engine (G_GNUC_UNUSED GOCmdContext
*gcc
, data_analysis_output_t
*dao
, gpointer specs
,
561 analysis_tool_engine_t selector
, gpointer result
)
564 case TOOL_ENGINE_UPDATE_DESCRIPTOR
:
565 return (dao_command_descriptor
566 (dao
, _("Wilcoxon Signed Rank Test (%s)"), result
)
568 case TOOL_ENGINE_UPDATE_DAO
:
569 dao_adjust (dao
, 3, 11);
571 case TOOL_ENGINE_CLEAN_UP
:
572 return analysis_tool_generic_b_clean (specs
);
573 case TOOL_ENGINE_LAST_VALIDITY_CHECK
:
575 case TOOL_ENGINE_PREPARE_OUTPUT_RANGE
:
576 dao_prepare_output (NULL
, dao
, _("Wilcoxon Signed Rank Test"));
578 case TOOL_ENGINE_FORMAT_OUTPUT_RANGE
:
579 return dao_format_output (dao
, _("Wilcoxon Signed Rank Test"));
580 case TOOL_ENGINE_PERFORM_CALC
:
582 return analysis_tool_signed_rank_test_two_engine_run (dao
, specs
);
584 return TRUE
; /* We shouldn't get here */