gnumeric r16966 - in trunk: . src/dialogs src/tools



Author: guelzow
Date: Sat Nov 15 23:02:53 2008
New Revision: 16966
URL: http://svn.gnome.org/viewvc/gnumeric?rev=16966&view=rev

Log:
2008-11-15  Andreas J. Guelzow <aguelzow pyrshep ca>

	* kaplan-meier.glade: add logrank checkbox
	* dialog-analysis-tool-kaplan-meier.c (kaplan_meier_tool_ok_clicked_cb): 
	  handle logrank checkbox
	(dialog_kaplan_meier_tool): ditto
	(KaplanMeierToolState): add new field

2008-11-15  Andreas J. Guelzow <aguelzow pyrshep ca>

	* analysis-kaplan-meier.c (analysis_tool_kaplan_meier_engine_run):
	  calculate log-rank statistics if requested
	(analysis_tool_kaplan_meier_engine): adjust dao size for test output
	* analysis-kaplan-meier.h (analysis_tools_data_kaplan_meier_t): add 
	  new field




Modified:
   trunk/NEWS
   trunk/src/dialogs/ChangeLog
   trunk/src/dialogs/dialog-analysis-tool-kaplan-meier.c
   trunk/src/dialogs/kaplan-meier.glade
   trunk/src/tools/ChangeLog
   trunk/src/tools/analysis-kaplan-meier.c
   trunk/src/tools/analysis-kaplan-meier.h

Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS	(original)
+++ trunk/NEWS	Sat Nov 15 23:02:53 2008
@@ -9,6 +9,7 @@
 	* Add functional seealso links in the function browser
 	* Allow ranges of censor marks in Kaplan-Meier tool and
 	  multiple groups. Output median survival times. [#558582]
+	* Add Log-Rank Test to Kaplan-Meier tool. [#558582]
 
 Hib Eris:
 	* Fix problems with toolbars when no handle bar present.  [#559249]

Modified: trunk/src/dialogs/dialog-analysis-tool-kaplan-meier.c
==============================================================================
--- trunk/src/dialogs/dialog-analysis-tool-kaplan-meier.c	(original)
+++ trunk/src/dialogs/dialog-analysis-tool-kaplan-meier.c	Sat Nov 15 23:02:53 2008
@@ -62,6 +62,7 @@
 	GtkWidget *censor_spin_from;
 	GtkWidget *censor_spin_to;
 	GtkWidget *graph_button;
+	GtkWidget *logrank_button;
 	GtkWidget *tick_button;
 	GtkWidget *add_group_button;
 	GtkWidget *remove_group_button;
@@ -271,8 +272,15 @@
 	data->censor_mark_to = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (state->censor_spin_to));
 
 	data->group_list = kaplan_meier_tool_get_groups (state);
-	data->range_3 = ((data->group_list == NULL) ? NULL : gnm_expr_entry_parse_as_value
-			 (GNM_EXPR_ENTRY (state->groups_input), state->base.sheet)); 
+	if (data->group_list == NULL) {
+		data->range_3 = NULL;
+		data->logrank_test = FALSE;
+	} else {
+		data->range_3 = gnm_expr_entry_parse_as_value
+			(GNM_EXPR_ENTRY (state->groups_input), state->base.sheet);
+		data->logrank_test = gtk_toggle_button_get_active (
+			GTK_TOGGLE_BUTTON (state->logrank_button));
+	}
 
 	data->median = gtk_toggle_button_get_active (
 		GTK_TOGGLE_BUTTON (glade_xml_get_widget
@@ -454,11 +462,13 @@
 	gtk_widget_set_sensitive (state->add_group_button, groups);
 	gtk_widget_set_sensitive (GTK_WIDGET (state->groups_treeview), groups);
 
-	if (groups)
+	if (groups) {
 		cb_selection_changed (selection, state);
-	else {
+		gtk_widget_set_sensitive (state->logrank_button, TRUE);
+	} else {
 		gtk_tree_selection_unselect_all (selection);
 		gtk_widget_set_sensitive (state->remove_group_button, FALSE);
+		gtk_widget_set_sensitive (state->logrank_button, FALSE);
 	}
 }
 
@@ -637,6 +647,9 @@
 	state->std_error_button = GTK_WIDGET (glade_xml_get_widget
 						  (state->base.gui,
 						   "std-error-button"));
+	state->logrank_button = GTK_WIDGET (glade_xml_get_widget
+						  (state->base.gui,
+						   "logrank-button"));
 
 	state->groups_check = GTK_WIDGET (glade_xml_get_widget
 						  (state->base.gui,

Modified: trunk/src/dialogs/kaplan-meier.glade
==============================================================================
--- trunk/src/dialogs/kaplan-meier.glade	(original)
+++ trunk/src/dialogs/kaplan-meier.glade	Sat Nov 15 23:02:53 2008
@@ -43,45 +43,52 @@
                       <placeholder/>
                     </child>
                     <child>
-                      <widget class="GtkSpinButton" id="censored-spinbutton2">
+                      <widget class="GtkCheckButton" id="censor-button">
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
-                        <property name="adjustment">0 0 1000 1 10 10</property>
-                        <property name="climb_rate">1</property>
+                        <property name="label" translatable="yes">Permit censorship</property>
+                        <property name="response_id">0</property>
+                        <property name="active">True</property>
+                        <property name="draw_indicator">True</property>
                       </widget>
                       <packing>
-                        <property name="left_attach">2</property>
                         <property name="right_attach">3</property>
-                        <property name="top_attach">4</property>
-                        <property name="bottom_attach">5</property>
+                        <property name="top_attach">1</property>
+                        <property name="bottom_attach">2</property>
+                        <property name="x_options">GTK_FILL</property>
+                        <property name="y_options">GTK_FILL</property>
                       </packing>
                     </child>
                     <child>
-                      <widget class="GtkSpinButton" id="censored-spinbutton1">
+                      <widget class="GtkLabel" id="var2-label">
                         <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="adjustment">0 0 1000 1 10 10</property>
-                        <property name="climb_rate">1</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">Censor co_lumn:</property>
+                        <property name="use_underline">True</property>
+                        <property name="justify">GTK_JUSTIFY_RIGHT</property>
                       </widget>
                       <packing>
-                        <property name="left_attach">2</property>
-                        <property name="right_attach">3</property>
-                        <property name="top_attach">3</property>
-                        <property name="bottom_attach">4</property>
+                        <property name="left_attach">1</property>
+                        <property name="right_attach">2</property>
+                        <property name="top_attach">2</property>
+                        <property name="bottom_attach">3</property>
+                        <property name="x_options">GTK_FILL</property>
+                        <property name="y_options">GTK_FILL</property>
                       </packing>
                     </child>
                     <child>
-                      <widget class="GtkLabel" id="label5">
+                      <widget class="GtkLabel" id="var1-label">
                         <property name="visible">True</property>
-                        <property name="xalign">1</property>
-                        <property name="label" translatable="yes">to:</property>
+                        <property name="xalign">0</property>
+                        <property name="xpad">5</property>
+                        <property name="label" translatable="yes">_Time column:</property>
+                        <property name="use_underline">True</property>
                         <property name="justify">GTK_JUSTIFY_RIGHT</property>
                       </widget>
                       <packing>
-                        <property name="left_attach">1</property>
                         <property name="right_attach">2</property>
-                        <property name="top_attach">4</property>
-                        <property name="bottom_attach">5</property>
+                        <property name="x_options">GTK_FILL</property>
+                        <property name="y_options">GTK_FILL</property>
                       </packing>
                     </child>
                     <child>
@@ -99,52 +106,45 @@
                       </packing>
                     </child>
                     <child>
-                      <widget class="GtkLabel" id="var1-label">
+                      <widget class="GtkLabel" id="label5">
                         <property name="visible">True</property>
-                        <property name="xalign">0</property>
-                        <property name="xpad">5</property>
-                        <property name="label" translatable="yes">_Time column:</property>
-                        <property name="use_underline">True</property>
+                        <property name="xalign">1</property>
+                        <property name="label" translatable="yes">to:</property>
                         <property name="justify">GTK_JUSTIFY_RIGHT</property>
                       </widget>
                       <packing>
+                        <property name="left_attach">1</property>
                         <property name="right_attach">2</property>
-                        <property name="x_options">GTK_FILL</property>
-                        <property name="y_options">GTK_FILL</property>
+                        <property name="top_attach">4</property>
+                        <property name="bottom_attach">5</property>
                       </packing>
                     </child>
                     <child>
-                      <widget class="GtkLabel" id="var2-label">
+                      <widget class="GtkSpinButton" id="censored-spinbutton1">
                         <property name="visible">True</property>
-                        <property name="xalign">0</property>
-                        <property name="label" translatable="yes">Censor co_lumn:</property>
-                        <property name="use_underline">True</property>
-                        <property name="justify">GTK_JUSTIFY_RIGHT</property>
+                        <property name="can_focus">True</property>
+                        <property name="adjustment">0 0 1000 1 10 10</property>
+                        <property name="climb_rate">1</property>
                       </widget>
                       <packing>
-                        <property name="left_attach">1</property>
-                        <property name="right_attach">2</property>
-                        <property name="top_attach">2</property>
-                        <property name="bottom_attach">3</property>
-                        <property name="x_options">GTK_FILL</property>
-                        <property name="y_options">GTK_FILL</property>
+                        <property name="left_attach">2</property>
+                        <property name="right_attach">3</property>
+                        <property name="top_attach">3</property>
+                        <property name="bottom_attach">4</property>
                       </packing>
                     </child>
                     <child>
-                      <widget class="GtkCheckButton" id="censor-button">
+                      <widget class="GtkSpinButton" id="censored-spinbutton2">
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
-                        <property name="label" translatable="yes">Permit censorship</property>
-                        <property name="response_id">0</property>
-                        <property name="active">True</property>
-                        <property name="draw_indicator">True</property>
+                        <property name="adjustment">0 0 1000 1 10 10</property>
+                        <property name="climb_rate">1</property>
                       </widget>
                       <packing>
+                        <property name="left_attach">2</property>
                         <property name="right_attach">3</property>
-                        <property name="top_attach">1</property>
-                        <property name="bottom_attach">2</property>
-                        <property name="x_options">GTK_FILL</property>
-                        <property name="y_options">GTK_FILL</property>
+                        <property name="top_attach">4</property>
+                        <property name="bottom_attach">5</property>
                       </packing>
                     </child>
                   </widget>
@@ -212,66 +212,66 @@
                       <placeholder/>
                     </child>
                     <child>
-                      <widget class="GtkScrolledWindow" id="groups-scrolled">
+                      <widget class="GtkLabel" id="groups-label">
                         <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-                        <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-                        <property name="shadow_type">GTK_SHADOW_IN</property>
-                        <child>
-                          <placeholder/>
-                        </child>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">Groups column:</property>
                       </widget>
                       <packing>
-                        <property name="right_attach">2</property>
-                        <property name="top_attach">1</property>
-                        <property name="bottom_attach">7</property>
+                        <property name="y_options">GTK_FILL</property>
                       </packing>
                     </child>
                     <child>
-                      <widget class="GtkButton" id="remove-button">
+                      <widget class="GtkButton" id="add-button">
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
                         <property name="receives_default">True</property>
-                        <property name="label" translatable="yes">gtk-remove</property>
+                        <property name="label" translatable="yes">gtk-add</property>
                         <property name="use_stock">True</property>
                         <property name="response_id">0</property>
                       </widget>
                       <packing>
                         <property name="left_attach">2</property>
                         <property name="right_attach">3</property>
-                        <property name="top_attach">2</property>
-                        <property name="bottom_attach">3</property>
+                        <property name="top_attach">1</property>
+                        <property name="bottom_attach">2</property>
                         <property name="x_options">GTK_FILL</property>
                         <property name="y_options">GTK_SHRINK | GTK_FILL</property>
                       </packing>
                     </child>
                     <child>
-                      <widget class="GtkButton" id="add-button">
+                      <widget class="GtkButton" id="remove-button">
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
                         <property name="receives_default">True</property>
-                        <property name="label" translatable="yes">gtk-add</property>
+                        <property name="label" translatable="yes">gtk-remove</property>
                         <property name="use_stock">True</property>
                         <property name="response_id">0</property>
                       </widget>
                       <packing>
                         <property name="left_attach">2</property>
                         <property name="right_attach">3</property>
-                        <property name="top_attach">1</property>
-                        <property name="bottom_attach">2</property>
+                        <property name="top_attach">2</property>
+                        <property name="bottom_attach">3</property>
                         <property name="x_options">GTK_FILL</property>
                         <property name="y_options">GTK_SHRINK | GTK_FILL</property>
                       </packing>
                     </child>
                     <child>
-                      <widget class="GtkLabel" id="groups-label">
+                      <widget class="GtkScrolledWindow" id="groups-scrolled">
                         <property name="visible">True</property>
-                        <property name="xalign">0</property>
-                        <property name="label" translatable="yes">Groups column:</property>
+                        <property name="can_focus">True</property>
+                        <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+                        <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+                        <property name="shadow_type">GTK_SHADOW_IN</property>
+                        <child>
+                          <placeholder/>
+                        </child>
                       </widget>
                       <packing>
-                        <property name="y_options">GTK_FILL</property>
+                        <property name="right_attach">2</property>
+                        <property name="top_attach">1</property>
+                        <property name="bottom_attach">7</property>
                       </packing>
                     </child>
                   </widget>
@@ -310,34 +310,34 @@
                       <placeholder/>
                     </child>
                     <child>
-                      <widget class="GtkCheckButton" id="graph-button">
+                      <widget class="GtkCheckButton" id="tick-button">
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
-                        <property name="label" translatable="yes">Show graph </property>
+                        <property name="label" translatable="yes">Include censorship ticks</property>
                         <property name="response_id">0</property>
                         <property name="active">True</property>
                         <property name="draw_indicator">True</property>
                       </widget>
                       <packing>
+                        <property name="left_attach">1</property>
                         <property name="right_attach">2</property>
+                        <property name="top_attach">1</property>
+                        <property name="bottom_attach">2</property>
                         <property name="x_options">GTK_FILL</property>
                         <property name="y_options">GTK_FILL</property>
                       </packing>
                     </child>
                     <child>
-                      <widget class="GtkCheckButton" id="tick-button">
+                      <widget class="GtkCheckButton" id="graph-button">
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
-                        <property name="label" translatable="yes">Include censorship ticks</property>
+                        <property name="label" translatable="yes">Show graph </property>
                         <property name="response_id">0</property>
                         <property name="active">True</property>
                         <property name="draw_indicator">True</property>
                       </widget>
                       <packing>
-                        <property name="left_attach">1</property>
                         <property name="right_attach">2</property>
-                        <property name="top_attach">1</property>
-                        <property name="bottom_attach">2</property>
                         <property name="x_options">GTK_FILL</property>
                         <property name="y_options">GTK_FILL</property>
                       </packing>
@@ -377,6 +377,21 @@
                     <property name="position">2</property>
                   </packing>
                 </child>
+                <child>
+                  <widget class="GtkCheckButton" id="logrank-button">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="label" translatable="yes">Perform Log-Rank (Mantel-Haenszel) Test</property>
+                    <property name="response_id">0</property>
+                    <property name="active">True</property>
+                    <property name="draw_indicator">True</property>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">3</property>
+                  </packing>
+                </child>
               </widget>
               <packing>
                 <property name="position">2</property>

Modified: trunk/src/tools/analysis-kaplan-meier.c
==============================================================================
--- trunk/src/tools/analysis-kaplan-meier.c	(original)
+++ trunk/src/tools/analysis-kaplan-meier.c	Sat Nov 15 23:02:53 2008
@@ -57,6 +57,7 @@
 			   : g_slist_length (info->group_list));
 	int colspan = ((info->std_err ? 4 : 3) + (info->censored ? 1 : 0));
 	int i;
+	int logrank_test_y_offset = 0;
 
 	GnmExpr const *expr_data;
 	GnmExpr const *expr_group_data = NULL;
@@ -478,6 +479,7 @@
 		gl = info->group_list;
 
 		for (i = 0; i < repetitions; i++) {
+			/* the next involves (colspan-1) since the median field moves to the right. */
 			gint prob_dx = - (repetitions - i)* (colspan - 1) - 1;
 			gint times_dx = - colspan * repetitions - i - 3;
 			GnmExpr const *expr_median;
@@ -518,7 +520,104 @@
 			
 			dao->offset_col += 1;
 		}
+		logrank_test_y_offset = 5;
+		dao->offset_col -= (2 + repetitions);
 	}
+
+	if (info->logrank_test) {		
+		GnmFunc *fd_chidist;
+		GnmExpr const *expr_statistics = gnm_expr_new_constant (value_new_int (0));
+		GnmExpr const *expr_p;
+		GnmExpr const *expr_n_total = gnm_expr_new_constant (value_new_int (0));
+		GnmExpr const *expr_death_total = gnm_expr_new_constant (value_new_int (0));
+
+		fd_chidist = gnm_func_lookup ("CHIDIST", NULL);
+		gnm_func_ref (fd_chidist);
+
+		dao_set_italic (dao, 1, logrank_test_y_offset, 1, logrank_test_y_offset+3);
+		set_cell_text_col (dao, 1, logrank_test_y_offset, 
+				   _("/Log-Rank Test:"
+				     "/Statistics:"
+				     "/Degrees of Freedom:"
+				     "/p-Value:"));
+		
+		/* Test Statistics */
+		for (i = 0; i < repetitions; i++) {
+			gint atrisk_dx = - (repetitions - i)* colspan - 2;
+			expr_n_total = gnm_expr_new_binary 
+				(expr_n_total, GNM_EXPR_OP_ADD, 
+				 make_rangeref ( atrisk_dx, 
+						 - logrank_test_y_offset + 1, 
+						 atrisk_dx, 
+						 - logrank_test_y_offset + rows));
+			expr_death_total = gnm_expr_new_binary 
+				(expr_death_total, GNM_EXPR_OP_ADD, 
+				 make_rangeref ( atrisk_dx + 1, 
+						 - logrank_test_y_offset + 1, 
+						 atrisk_dx + 1, 
+						 - logrank_test_y_offset + rows));
+		}
+
+		for (i = 0; i < repetitions; i++) {
+			GnmExpr const *expr_expect;
+			gint atrisk_dx = - (repetitions - i)* colspan - 2;
+
+			expr_expect = gnm_expr_new_binary 
+				(gnm_expr_new_binary 
+				 (gnm_expr_copy (expr_death_total),
+				  GNM_EXPR_OP_MULT,
+				  make_rangeref (atrisk_dx, 
+						 - logrank_test_y_offset + 1, 
+						 atrisk_dx, 
+						 - logrank_test_y_offset + rows)), 
+				 GNM_EXPR_OP_DIV, 
+				 gnm_expr_copy (expr_n_total));
+			
+			expr_expect = gnm_expr_new_funcall3 (
+				fd_if,
+				gnm_expr_new_funcall1 (fd_iserror,
+						       gnm_expr_copy (expr_expect)),
+				gnm_expr_new_constant (value_new_int (0)),
+				expr_expect);
+			expr_expect = gnm_expr_new_funcall1 (fd_sum,
+							     expr_expect);
+			expr_expect = gnm_expr_new_binary (
+				gnm_expr_new_binary (
+					gnm_expr_new_binary (
+						gnm_expr_new_funcall1 (
+							fd_sum,
+							make_rangeref 
+							(atrisk_dx + 1, 
+							 - logrank_test_y_offset + 1, 
+							 atrisk_dx + 1, 
+							 - logrank_test_y_offset + rows)),
+						GNM_EXPR_OP_SUB,
+						gnm_expr_copy (expr_expect)),
+					GNM_EXPR_OP_EXP,
+					gnm_expr_new_constant (value_new_int (2))),
+				GNM_EXPR_OP_DIV,
+				expr_expect);
+			expr_statistics =  gnm_expr_new_binary (
+				expr_statistics, GNM_EXPR_OP_ADD, expr_expect);
+		}
+		gnm_expr_free (expr_n_total);					
+		gnm_expr_free (expr_death_total);					
+
+		dao_set_cell_array_expr (dao, 2, logrank_test_y_offset + 1, expr_statistics);
+
+		/* Degree of Freedoms */
+		dao_set_cell_int (dao, 2, logrank_test_y_offset + 2, repetitions - 1);
+
+		/* p Value */
+		expr_p = gnm_expr_new_funcall2 (fd_chidist,
+						make_cellref (0,-2),
+						make_cellref (0,-1));
+		dao_set_cell_expr (dao, 2, logrank_test_y_offset + 3, expr_p);
+		
+		gnm_func_unref (fd_chidist);		
+	}
+
+	
 	
 
 
@@ -568,6 +667,8 @@
 	case TOOL_ENGINE_UPDATE_DAO:
 		multiple = ((info->group_list == NULL) ? 1 :  g_slist_length (info->group_list));
 		median   = (info->median ? (2 + multiple) : 0);
+		if (median == 0 && info->logrank_test)
+			median = 3;
 		dao_adjust (dao, median + 1 + multiple * ((info->std_err ? 4 : 3) + (info->censored ? 1 : 0)), 
 			    info->base.range_1->v_range.cell.b.row 
 			    - info->base.range_1->v_range.cell.a.row + 3);

Modified: trunk/src/tools/analysis-kaplan-meier.h
==============================================================================
--- trunk/src/tools/analysis-kaplan-meier.h	(original)
+++ trunk/src/tools/analysis-kaplan-meier.h	Sat Nov 15 23:02:53 2008
@@ -52,6 +52,7 @@
 	gboolean ticks;
 	gboolean std_err;
 	gboolean median;
+	gboolean logrank_test;
 	GSList *group_list;
 } analysis_tools_data_kaplan_meier_t;
 



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