[gnumeric] Improve Mann-Whitney test to allow for two separate data ranges.



commit 1b382d765c3d6915c1cffb90a7f97056862d6617
Author: Andreas J Guelzow <aguelzow pyrshep ca>
Date:   Tue Jun 12 14:48:21 2012 -0600

    Improve Mann-Whitney test to allow for two separate data ranges.
    
    2012-06-12  Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* analysis-wilcoxon-mann-whitney.c (analysis_tool_combine_area): new
    	(analysis_tool_wilcoxon_mann_whitney_engine_run): adjust to use
    	analysis_tools_data_generic_b_t
    	(analysis_tool_wilcoxon_mann_whitney_engine): ditto
    
    2012-06-12  Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* wilcoxon-mann-whitney.ui: use two input entries
    	* dialog-analysis-tool-wilcoxon-mann-whitney.c (dialog_wilcoxon_m_w_tool):
    	adjust to two input fields
    	(wilcoxon_mann_whitney_tool_ok_clicked_cb): ditto
    	(wilcoxon_mann_whitney_tool_update_sensitivity_cb): ditto

 NEWS                                               |    1 +
 src/dialogs/ChangeLog                              |    8 ++
 .../dialog-analysis-tool-wilcoxon-mann-whitney.c   |   67 +++++-------
 src/dialogs/wilcoxon-mann-whitney.ui               |   70 +-----------
 src/tools/ChangeLog                                |    7 ++
 src/tools/analysis-wilcoxon-mann-whitney.c         |  114 +++++++++++++-------
 6 files changed, 125 insertions(+), 142 deletions(-)
---
diff --git a/NEWS b/NEWS
index 72e6e05..7432cc7 100644
--- a/NEWS
+++ b/NEWS
@@ -22,6 +22,7 @@ Andreas:
 	* Fix Wilcoxon Mann Whitney Test in the presence of empty cells.
 	* Add single sample t-test.
 	* Fix random generator/new view combination crash. [#677956]
+	* Improve Mann-Whitney test to allow for two separate data ranges.
 
 Jean:
 	* Fix graph series headers when a multiple selection is used. [#675913]
diff --git a/src/dialogs/ChangeLog b/src/dialogs/ChangeLog
index 9762cf8..b75397e 100644
--- a/src/dialogs/ChangeLog
+++ b/src/dialogs/ChangeLog
@@ -1,5 +1,13 @@
 2012-06-12  Andreas J. Guelzow <aguelzow pyrshep ca>
 
+	* wilcoxon-mann-whitney.ui: use two input entries
+	* dialog-analysis-tool-wilcoxon-mann-whitney.c (dialog_wilcoxon_m_w_tool):
+	adjust to two input fields
+	(wilcoxon_mann_whitney_tool_ok_clicked_cb): ditto
+	(wilcoxon_mann_whitney_tool_update_sensitivity_cb): ditto
+
+2012-06-12  Andreas J. Guelzow <aguelzow pyrshep ca>
+
 	* dialog-analysis-tool-one-mean.c: we are not using Gnumeric_fninfo
 
 2012-06-11  Andreas J. Guelzow <aguelzow pyrshep ca>
diff --git a/src/dialogs/dialog-analysis-tool-wilcoxon-mann-whitney.c b/src/dialogs/dialog-analysis-tool-wilcoxon-mann-whitney.c
index 8a959ee..669382a 100644
--- a/src/dialogs/dialog-analysis-tool-wilcoxon-mann-whitney.c
+++ b/src/dialogs/dialog-analysis-tool-wilcoxon-mann-whitney.c
@@ -67,36 +67,31 @@ wilcoxon_mann_whitney_tool_update_sensitivity_cb (G_GNUC_UNUSED GtkWidget *dummy
 						 GenericToolState *state)
 {
         GnmValue *input_range;
+        GnmValue *input_range_2;
+	gboolean input_1_ready  = FALSE;
+	gboolean input_2_ready  = FALSE;
 
-	/* Checking Input Range */
+	/* Checking Input Ranges */
         input_range = gnm_expr_entry_parse_as_value (
 		GNM_EXPR_ENTRY (state->input_entry), state->sheet);
-	if (input_range == NULL) {
+	input_range_2 = gnm_expr_entry_parse_as_value
+		(GNM_EXPR_ENTRY (state->input_entry_2), state->sheet);
+
+	input_1_ready = (input_range != NULL);
+	input_2_ready = ((state->input_entry_2 == NULL) || (input_range_2 != NULL));
+        value_release (input_range);
+        value_release (input_range_2);
+
+	if (!input_1_ready) {
 		gtk_label_set_text (GTK_LABEL (state->warning),
-				    _("The input range is invalid."));
+				    _("The input range for variable 1 is invalid."));
 		gtk_widget_set_sensitive (state->ok_button, FALSE);
 		return;
-	} else {
-		GnmRangeRef const *rr = value_get_rangeref (input_range);
-		guint len = 0;
-		GnmRange r;
-
-		if (rr != NULL) {
-			group_by_t group_by
-				= gnm_gui_group_value
-				(state->gui, grouped_by_group);
-			range_init_rangeref (&r, rr);
-			len = (group_by == GROUPED_BY_ROW)
-				? range_height (&r) : range_width (&r);
-		}
-
-		value_release (input_range);
-		if (len != 2) {
-			gtk_label_set_text (GTK_LABEL (state->warning),
-					    _("The input range should consists of 2 groups."));
-			gtk_widget_set_sensitive (state->ok_button, FALSE);
-			return;
-		}
+	} else if (!input_2_ready) {
+		gtk_label_set_text (GTK_LABEL (state->warning),
+				    _("The input range for variable 2 is invalid."));
+		gtk_widget_set_sensitive (state->ok_button, FALSE);
+		return;		
 	}
 
 	/* Checking Output Page */
@@ -125,19 +120,23 @@ wilcoxon_mann_whitney_tool_ok_clicked_cb (G_GNUC_UNUSED GtkWidget *button,
 			GenericToolState *state)
 {
 	data_analysis_output_t  *dao;
-	analysis_tools_data_generic_t  *data;
+	analysis_tools_data_generic_b_t  *data;
 
  	GtkWidget *w;
 
 	if (state->warning_dialog != NULL)
 		gtk_widget_destroy (state->warning_dialog);
 
-	data = g_new0 (analysis_tools_data_generic_t, 1);
+	data = g_new0 (analysis_tools_data_generic_b_t, 1);
 	dao  = parse_output (state, NULL);
 
-	data->input = gnm_expr_entry_parse_as_list (
-		GNM_EXPR_ENTRY (state->input_entry), state->sheet);
-	data->group_by = gnm_gui_group_value (state->gui, grouped_by_group);
+	data->wbc = WORKBOOK_CONTROL (state->wbcg);
+
+	data->range_1 = gnm_expr_entry_parse_as_value
+		(GNM_EXPR_ENTRY (state->input_entry), state->sheet);
+
+	data->range_2 =  gnm_expr_entry_parse_as_value
+		(GNM_EXPR_ENTRY (state->input_entry_2), state->sheet);
 
 	w = go_gtk_builder_get_widget (state->gui, "labels_button");
         data->labels = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
@@ -148,8 +147,7 @@ wilcoxon_mann_whitney_tool_ok_clicked_cb (G_GNUC_UNUSED GtkWidget *button,
 		char   *text;
 		text = g_strdup_printf (
 			_("An unexpected error has occurred."));
-		error_in_entry ((GenericToolState *) state,
-				GTK_WIDGET (state->input_entry), text);
+		error_in_entry (state, GTK_WIDGET (state->input_entry), text);
 		g_free (text);
 	} else
 		gtk_widget_destroy (state->dialog);
@@ -195,13 +193,6 @@ dialog_wilcoxon_m_w_tool (WBCGtk *wbcg, Sheet *sheet)
 			      GNM_EE_SINGLE_RANGE))
 		return 0;
 
-	g_signal_connect_after
-		(G_OBJECT (go_gtk_builder_get_widget
-			   (state->gui,
-			    "grouped_by_row")), "toggled",
-		 G_CALLBACK (wilcoxon_mann_whitney_tool_update_sensitivity_cb),
-		 state);
-
 	gnm_dao_set_put (GNM_DAO (state->gdao), TRUE, TRUE);
 	wilcoxon_mann_whitney_tool_update_sensitivity_cb (NULL, state);
 	tool_load_selection ((GenericToolState *)state, TRUE);
diff --git a/src/dialogs/wilcoxon-mann-whitney.ui b/src/dialogs/wilcoxon-mann-whitney.ui
index 9e18817..f2410b5 100644
--- a/src/dialogs/wilcoxon-mann-whitney.ui
+++ b/src/dialogs/wilcoxon-mann-whitney.ui
@@ -93,7 +93,7 @@
                     <property name="can_focus">False</property>
                     <property name="xalign">0</property>
                     <property name="xpad">5</property>
-                    <property name="label" translatable="yes">_Input range:</property>
+                    <property name="label" translatable="yes">Variable _1 range:</property>
                     <property name="use_underline">True</property>
                     <property name="justify">right</property>
                   </object>
@@ -105,13 +105,13 @@
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkLabel" id="label2">
+                  <object class="GtkLabel" id="var2-label">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="xalign">0</property>
-                    <property name="xpad">5</property>
-                    <property name="label" translatable="yes">Grouped by:</property>
-                    <property name="justify">center</property>
+                    <property name="label" translatable="yes">Variable _2 range:</property>
+                    <property name="use_underline">True</property>
+                    <property name="justify">right</property>
                   </object>
                   <packing>
                     <property name="left_attach">0</property>
@@ -166,66 +166,6 @@
                     <property name="height">1</property>
                   </packing>
                 </child>
-                <child>
-                  <object class="GtkRadioButton" id="grouped_by_col">
-                    <property name="label" translatable="yes" context="groupby" comments="Group by Columns">_Columns</property>
-                    <property name="use_action_appearance">False</property>
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">False</property>
-                    <property name="use_action_appearance">False</property>
-                    <property name="use_underline">True</property>
-                    <property name="xalign">0</property>
-                    <property name="active">True</property>
-                    <property name="draw_indicator">True</property>
-                  </object>
-                  <packing>
-                    <property name="left_attach">1</property>
-                    <property name="top_attach">1</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkRadioButton" id="grouped_by_row">
-                    <property name="label" translatable="yes" context="groupby" comments="Group by Rows">_Rows</property>
-                    <property name="use_action_appearance">False</property>
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">False</property>
-                    <property name="use_action_appearance">False</property>
-                    <property name="use_underline">True</property>
-                    <property name="xalign">0</property>
-                    <property name="draw_indicator">True</property>
-                    <property name="group">grouped_by_col</property>
-                  </object>
-                  <packing>
-                    <property name="left_attach">1</property>
-                    <property name="top_attach">2</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkRadioButton" id="grouped_by_area">
-                    <property name="label" translatable="yes">_Areas</property>
-                    <property name="use_action_appearance">False</property>
-                    <property name="sensitive">False</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">False</property>
-                    <property name="use_action_appearance">False</property>
-                    <property name="use_underline">True</property>
-                    <property name="xalign">0</property>
-                    <property name="draw_indicator">True</property>
-                    <property name="group">grouped_by_col</property>
-                  </object>
-                  <packing>
-                    <property name="left_attach">1</property>
-                    <property name="top_attach">3</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
-                  </packing>
-                </child>
               </object>
             </child>
             <child type="tab">
diff --git a/src/tools/ChangeLog b/src/tools/ChangeLog
index 20f4911..cd34a63 100644
--- a/src/tools/ChangeLog
+++ b/src/tools/ChangeLog
@@ -1,3 +1,10 @@
+2012-06-12  Andreas J. Guelzow <aguelzow pyrshep ca>
+
+	* analysis-wilcoxon-mann-whitney.c (analysis_tool_combine_area): new
+	(analysis_tool_wilcoxon_mann_whitney_engine_run): adjust to use
+	analysis_tools_data_generic_b_t
+	(analysis_tool_wilcoxon_mann_whitney_engine): ditto
+
 2012-06-11  Andreas J. Guelzow <aguelzow pyrshep ca>
 
 	* analysis-one-mean-test.c: new
diff --git a/src/tools/analysis-wilcoxon-mann-whitney.c b/src/tools/analysis-wilcoxon-mann-whitney.c
index 0690c70..3aee39b 100644
--- a/src/tools/analysis-wilcoxon-mann-whitney.c
+++ b/src/tools/analysis-wilcoxon-mann-whitney.c
@@ -34,9 +34,62 @@
 #include "func.h"
 #include "numbers.h"
 
+static
+GnmExpr const *analysis_tool_combine_area (GnmValue *val_1, GnmValue *val_2, Workbook *wb)
+{
+	GnmFunc *fd_array;
+	GnmExpr const *expr;
+
+	if (val_1->type == VALUE_CELLRANGE && val_2->type == VALUE_CELLRANGE &&
+	    val_1->v_range.cell.a.sheet == val_2->v_range.cell.a.sheet) {
+		GnmRange r_1, r_2;
+		gboolean combined = FALSE;
+
+		range_init_rangeref (&r_1, &val_1->v_range.cell);
+		range_init_rangeref (&r_2, &val_2->v_range.cell);
+		
+		if (r_1.start.row == r_2.start.row &&
+		    range_height (&r_1) == range_height (&r_2)) {
+			if (r_1.end.col == r_2.start.col - 1) {
+				combined = TRUE;
+				r_1.end.col = r_2.end.col;
+			} else if (r_2.end.col == r_1.start.col - 1) {
+				combined = TRUE;
+				r_1.start.col = r_2.start.col;
+			} 
+		} else if (r_1.start.col == r_2.start.col &&
+			   range_width (&r_1) == range_width (&r_2)) {
+			if (r_1.end.row == r_2.start.row - 1) {
+				combined = TRUE;
+				r_1.end.row = r_2.end.row;
+			} else if (r_2.end.row == r_1.start.row - 1) {
+				combined = TRUE;
+				r_1.start.row = r_2.start.row;
+			} 			
+		}
+
+		if (combined) {
+			GnmValue *val = value_new_cellrange_r (val_1->v_range.cell.a.sheet, &r_1);
+			return gnm_expr_new_constant (val);
+		}
+	}
+	
+	fd_array = gnm_func_lookup_or_add_placeholder
+		("ARRAY", wb, FALSE);
+	gnm_func_ref (fd_array);
+
+	expr = gnm_expr_new_funcall2 (fd_array, 
+				      gnm_expr_new_constant (value_dup (val_1)),
+				      gnm_expr_new_constant (value_dup (val_2)));
+
+	gnm_func_unref (fd_array);
+	
+	return expr;
+}
+
 static gboolean
 analysis_tool_wilcoxon_mann_whitney_engine_run (data_analysis_output_t *dao,
-				      analysis_tools_data_generic_t *info)
+				      analysis_tools_data_generic_b_t *info)
 {
 	GnmFunc *fd_count;
 	GnmFunc *fd_sum;
@@ -55,43 +108,31 @@ analysis_tool_wilcoxon_mann_whitney_engine_run (data_analysis_output_t *dao,
 	GnmExpr const *expr_u;
 	GnmExpr const *expr_count_total;
 
-	GnmValue *total_pop = value_dup (info->input->data);
+	GnmValue *val_1 = value_dup (info->range_1);
+	GnmValue *val_2 = value_dup (info->range_2);
+	Workbook *wb = dao->sheet ? dao->sheet->workbook : NULL;
 
-	GSList *input = g_slist_append (NULL, value_dup (info->input->data));
-
-	prepare_input_range (&input, info->group_by);
-
-	fd_count = gnm_func_lookup_or_add_placeholder
-		("COUNT", dao->sheet ? dao->sheet->workbook : NULL, FALSE);
+	fd_count = gnm_func_lookup_or_add_placeholder ("COUNT", wb, FALSE);
 	gnm_func_ref (fd_count);
-	fd_sum = gnm_func_lookup_or_add_placeholder
-		("SUM", dao->sheet ? dao->sheet->workbook : NULL, FALSE);
+	fd_sum = gnm_func_lookup_or_add_placeholder ("SUM", wb, FALSE);
 	gnm_func_ref (fd_sum);
-	fd_rows = gnm_func_lookup_or_add_placeholder
-		("ROWS", dao->sheet ? dao->sheet->workbook : NULL, FALSE);
+	fd_rows = gnm_func_lookup_or_add_placeholder ("ROWS", wb, FALSE);
 	gnm_func_ref (fd_rows);
-	fd_rank_avg = gnm_func_lookup_or_add_placeholder
-		("RANK.AVG", dao->sheet ? dao->sheet->workbook : NULL, FALSE);
+	fd_rank_avg = gnm_func_lookup_or_add_placeholder ("RANK.AVG", wb, FALSE);
 	gnm_func_ref (fd_rank_avg);
-	fd_rank = gnm_func_lookup_or_add_placeholder
-		("RANK", dao->sheet ? dao->sheet->workbook : NULL, FALSE);
+	fd_rank = gnm_func_lookup_or_add_placeholder ("RANK", wb, FALSE);
 	gnm_func_ref (fd_rank);
-	fd_min = gnm_func_lookup_or_add_placeholder
-		("MIN", dao->sheet ? dao->sheet->workbook : NULL, FALSE);
+	fd_min = gnm_func_lookup_or_add_placeholder ("MIN", wb, FALSE);
 	gnm_func_ref (fd_min);
-	fd_normdist = gnm_func_lookup_or_add_placeholder
-		("NORMDIST", dao->sheet ? dao->sheet->workbook : NULL, FALSE);
+	fd_normdist = gnm_func_lookup_or_add_placeholder ("NORMDIST", wb, FALSE);
 	gnm_func_ref (fd_normdist);
-	fd_sqrt = gnm_func_lookup_or_add_placeholder
-		("SQRT", dao->sheet ? dao->sheet->workbook : NULL, FALSE);
+	fd_sqrt = gnm_func_lookup_or_add_placeholder ("SQRT", wb, FALSE);
 	gnm_func_ref (fd_sqrt);
-	fd_if = gnm_func_lookup_or_add_placeholder
-		("IF", dao->sheet ? dao->sheet->workbook : NULL, FALSE);
+	fd_if = gnm_func_lookup_or_add_placeholder ("IF", wb, FALSE);
 	gnm_func_ref (fd_if);
-	fd_isblank = gnm_func_lookup_or_add_placeholder
-		("ISBLANK", dao->sheet ? dao->sheet->workbook : NULL, FALSE);
+	fd_isblank = gnm_func_lookup_or_add_placeholder ("ISBLANK", wb, FALSE);
 	gnm_func_ref (fd_isblank);
-
+	
 	dao_set_italic (dao, 0, 0, 0, 8);
 	dao_set_italic (dao, 0, 1, 3, 1);
 	dao_set_merge (dao, 0, 0, 3, 0);
@@ -105,18 +146,13 @@ analysis_tool_wilcoxon_mann_whitney_engine_run (data_analysis_output_t *dao,
 					"/p-Value"));
 	dao_set_cell (dao, 3, 1, _("Total"));
 
-	analysis_tools_remove_label (total_pop, info->labels, info->group_by);
-	expr_total = gnm_expr_new_constant (total_pop);
-	analysis_tools_write_a_label (input->data, dao,
-				      info->labels, info->group_by,
-				      1, 1);
-	expr_pop_1 = gnm_expr_new_constant (input->data);
-	analysis_tools_write_a_label (input->next->data, dao,
-				      info->labels, info->group_by,
-				      2, 1);
-	expr_pop_2 = gnm_expr_new_constant (input->next->data);
+	/* Label */
+	analysis_tools_write_label_ftest (val_1, dao, 1, 1, info->labels, 1);
+	analysis_tools_write_label_ftest (val_2, dao, 2, 1, info->labels, 2);
 
-	g_slist_free (input);
+	expr_total = analysis_tool_combine_area (val_1, val_2, wb);
+	expr_pop_1 = gnm_expr_new_constant (val_1);
+	expr_pop_2 = gnm_expr_new_constant (val_2);
 
 	/* =sum(if(isblank(region1),0,rank.avg(region1,combined_regions,1))) */
 
@@ -320,7 +356,7 @@ analysis_tool_wilcoxon_mann_whitney_engine
 		dao_adjust (dao, 4, 9);
 		return FALSE;
 	case TOOL_ENGINE_CLEAN_UP:
-		return analysis_tool_generic_clean (specs);
+		return analysis_tool_generic_b_clean (specs);
 	case TOOL_ENGINE_LAST_VALIDITY_CHECK:
 		return FALSE;
 	case TOOL_ENGINE_PREPARE_OUTPUT_RANGE:



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]