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