1 /* missing.c */
2 /*
3  * ggobi
4  * Copyright (C) AT&T, Duncan Temple Lang, Dianne Cook 1999-2005
5  *
6  * ggobi is free software; you may use, redistribute, and/or modify it
7  * under the terms of the Eclipse Public License, which is distributed
8  * with the source code and displayed on the ggobi web site,
9  * www.ggobi.org.  For more information, contact the authors:
10  *
11  *   Deborah F. Swayne   dfs@research.att.com
12  *   Di Cook             dicook@iastate.edu
13  *   Duncan Temple Lang  duncan@wald.ucdavis.edu
14  *   Andreas Buja        andreas.buja@wharton.upenn.edu
15 */
16 
17 #include <stdlib.h>
18 #include <stdio.h>
19 #include <unistd.h>
20 #include <errno.h>
21 #include <sys/types.h>
22 #include <sys/stat.h>
23 /*#include <limits.h>*/
24 /*#include <float.h>*/
25 #include <math.h>
26 
27 #include <gtk/gtk.h>
28 #include "vars.h"
29 #include "externs.h"
30 
31 /*--------------------------------------------------------------------*/
32 /*             Memory management routines                             */
33 /*--------------------------------------------------------------------*/
34 
35 void
missing_arrays_add_cols(GGobiData * d)36 missing_arrays_add_cols (GGobiData * d)
37 {
38   if (d->missing.ncols < d->ncols) {
39     arrays_add_cols (&d->missing, d->ncols);
40   }
41 }
42 
43 void
missing_arrays_add_rows(gint nrows,GGobiData * d)44 missing_arrays_add_rows (gint nrows, GGobiData * d)
45 {
46   arrays_add_rows (&d->missing, nrows);
47 }
48 
49 /*------------------------------------------------------------------*/
50 /*      Scaling and jittering missing value plots                   */
51 /*------------------------------------------------------------------*/
52 
53 /*
54  * For the datad currently selected in gg->impute.notebook,
55  * generate a new datad using d->missing.  Maybe I should only
56  * create missingness variables for those variables which have
57  * missing values ...
58  *
59 */
60 // FIXME: create with the GGobiData api
61 void
missings_datad_cb(GtkWidget * w,ggobid * gg)62 missings_datad_cb (GtkWidget * w, ggobid * gg)
63 {
64   GObject *obj = G_OBJECT (gg->impute.window);
65   GtkWidget *tree_view = get_tree_view_from_object (obj);
66   GGobiData *d =
67     (GGobiData *) g_object_get_data (G_OBJECT (tree_view), "datad");
68   static gchar *lnames[] = { "present", "missing" };
69 
70   if (!ggobi_data_has_missings(d)) return;
71 
72   GtkWidget *notebook;
73   GGobiData *dnew;
74   gint i, j, k;
75   vartabled *vt, *vtnew;
76   gint *cols;
77   gint *cols_with_missings, ncols_with_missings;
78 
79   ncols_with_missings = 0;
80   cols_with_missings = g_malloc (d->ncols * sizeof (gint));
81   for (j = 0; j < d->ncols; j++) {
82     if (ggobi_data_get_col_n_missing(d, j))
83       cols_with_missings[ncols_with_missings++] = j;
84   }
85 
86   notebook = (GtkWidget *) g_object_get_data (obj, "notebook");
87   dnew = ggobi_data_new (d->nrows, ncols_with_missings);
88   dnew->name = g_strdup_printf ("%s (missing)", d->name);
89 
90   for (i = 0; i < d->nrows; i++) {
91     for (j = 0; j < ncols_with_missings; j++) {
92       k = cols_with_missings[j];
93       dnew->raw.vals[i][j] = (gfloat) ggobi_data_is_missing(d, i, k);
94     }
95   }
96 
97   /*
98    * ids to support linking: if the current datad doesn't
99    * have ids, they need to be assigned.
100    */
101   if (d->rowIds == NULL) {
102     gchar **rowids = (gchar **) g_malloc (d->nrows * sizeof (gchar *));
103     for (i = 0; i < d->nrows; i++)
104       rowids[i] = g_strdup_printf ("%d", i);
105     datad_record_ids_set (d, rowids, true);
106     for (i = 0; i < d->nrows; i++)
107       g_free (rowids[i]);
108     g_free (rowids);
109   }
110   datad_record_ids_set (dnew, d->rowIds, true);
111   /*-- --*/
112 
113 /*
114 * I'm going to make all the variables categorical.  For the moment,
115 * there can be only two categories: present (0), missing (1).  In
116 * the future, we might want to support other categories:  censored,
117 * left-censored, etc.
118 */
119 
120   for (j = 0; j < ncols_with_missings; j++) {
121     k = cols_with_missings[j];
122     vt = vartable_element_get (k, d);
123     vtnew = vartable_element_get (j, dnew);
124     vtnew->collab = g_strdup (vt->collab);
125     vtnew->collab_tform = g_strdup (vtnew->collab);
126 
127     /*-- categorical variable definitions --*/
128     vtnew->vartype = categorical;
129     vtnew->nlevels = 2;
130     vtnew->level_values = (gint *) g_malloc (sizeof (gint) * 2);
131     vtnew->level_counts = (gint *) g_malloc (sizeof (gchar *) * 2);
132     vtnew->level_names = (gchar **) g_malloc (sizeof (gchar *) * 2);
133     for (i = 0; i < 2; i++) {
134       vtnew->level_values[i] = i;
135       vtnew->level_names[i] = g_strdup (lnames[i]);
136     }
137     vtnew->level_counts[0] = d->nrows - ggobi_data_get_col_n_missing(d, j);
138     vtnew->level_counts[1] = ggobi_data_get_col_n_missing(d, j);
139 
140     /*-- prepare to jitter, and set limits to [0,1] --*/
141     vtnew->lim_specified_p = true;  /*-- user-specified limits --*/
142     vtnew->lim_specified.min = 0.0;
143     vtnew->lim_specified_tform.min = 0.0;
144     vtnew->lim_specified.max = 1.0;
145     vtnew->lim_specified_tform.max = 1.0;
146     vtnew->jitter_factor = .2;
147   }
148 
149   for (i = 0; i < d->nrows; i++) {
150     g_array_append_val (dnew->rowlab,
151                         g_array_index (d->rowlab, gchar *, i));
152   }
153 
154   datad_init (dnew, gg, false);
155 
156   /*-- jitter the data --*/
157   /*-- forces unnecessary redisplay, unfortunately --*/
158   cols = g_malloc (dnew->ncols * sizeof (gint));
159   for (i = 0; i < dnew->ncols; i++)
160     cols[i] = i;
161   rejitter (cols, dnew->ncols, dnew, gg);
162 
163   /*-- copy the existing glyph and color --*/
164   for (i = 0; i < d->nrows; i++) {
165     dnew->color.els[i] = d->color.els[i];
166     dnew->color_now.els[i] = d->color_now.els[i];
167     dnew->glyph.els[i].type = d->glyph.els[i].type;
168     dnew->glyph_now.els[i].type = d->glyph_now.els[i].type;
169     dnew->glyph.els[i].size = d->glyph.els[i].size;
170     dnew->glyph_now.els[i].size = d->glyph_now.els[i].size;
171   }
172 
173   /*-- this should be executed in response to any datad_added event --*/
174   display_menu_build (gg);
175 
176   g_free (cols);
177   g_free (cols_with_missings);
178 }
179