The R Project SVN R-packages

Rev

Rev 3684 | Rev 4160 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3684 Rev 3808
Line 1... Line 1...
1
#define __SQLITE_MATRIX__
1
#define __SQLITE_MATRIX__
2
#include "sqlite_dataframe.h"
2
#include "sqlite_dataframe.h"
3
 
3
 
4
/****************************************************************************
4
/****************************************************************************
-
 
5
 * UTILITY FUNCTIONS
-
 
6
 ****************************************************************************/
-
 
7
static SEXP _create_smat_sexp(const char *mat_iname, const char *type, 
-
 
8
        int nrows, int ncols, SEXP colnames) {
-
 
9
    SEXP ret, tmp;
-
 
10
    int i;
-
 
11
 
-
 
12
    /* return smat sexp */
-
 
13
    PROTECT(ret = NEW_LIST(3)); i = 1; /* 1 for names sexp above */
-
 
14
    SET_VECTOR_ELT(ret, 0, mkString(mat_iname));
-
 
15
    SET_VECTOR_ELT(ret, 1, mkString("sdf_data"));
-
 
16
    SET_VECTOR_ELT(ret, 2, mkString("V1"));
-
 
17
 
-
 
18
    /* set smat data name */
-
 
19
    PROTECT(tmp = NEW_CHARACTER(3)); i++;
-
 
20
    SET_STRING_ELT(tmp, 0, mkChar("iname"));
-
 
21
    SET_STRING_ELT(tmp, 1, mkChar("tblname"));
-
 
22
    SET_STRING_ELT(tmp, 2, mkChar("varname"));
-
 
23
    SET_NAMES(ret, tmp);
-
 
24
 
-
 
25
    /* set class */
-
 
26
    PROTECT(tmp = mkString("sqlite.matrix")); i++;
-
 
27
    SET_CLASS(ret, tmp);
-
 
28
 
-
 
29
    /* set smat dim */
-
 
30
    PROTECT(tmp = NEW_INTEGER(2)); i++;
-
 
31
    INTEGER(tmp)[0] = nrows;
-
 
32
    INTEGER(tmp)[1] = ncols;  /* mind [row names], w/c is not included in the count */
-
 
33
    setAttrib(ret, SDF_DimSymbol, tmp);
-
 
34
 
-
 
35
    /* set smat dimname */
-
 
36
    PROTECT(tmp = NEW_LIST(2)); i++;
-
 
37
    SET_VECTOR_ELT(tmp, 0, _create_svector_sexp(mat_iname, 
-
 
38
                "sdf_matrix_rownames", "name", "character"));
-
 
39
    SET_VECTOR_ELT(tmp, 1, colnames);
-
 
40
    setAttrib(ret, SDF_DimNamesSymbol, tmp);
-
 
41
 
-
 
42
    /* set sdf.vector.type */
-
 
43
    setAttrib(ret, SDF_VectorTypeSymbol, mkString(type));
-
 
44
 
-
 
45
    UNPROTECT(i);
-
 
46
 
-
 
47
    return ret;
-
 
48
}
-
 
49
 
-
 
50
/****************************************************************************
5
 * SMAT FUNCTIONS
51
 * SMAT FUNCTIONS
6
 ****************************************************************************/
52
 ****************************************************************************/
7
SEXP sdf_as_matrix(SEXP sdf, SEXP name) {
53
SEXP sdf_as_matrix(SEXP sdf, SEXP name) {
8
    char *iname, *mat_iname, *type;
54
    char *iname, *mat_iname, *type;
9
    const char *dectype, *colname;
55
    const char *dectype, *colname, *vectype;
10
    sqlite3_stmt *stmt, *stmt2;
56
    sqlite3_stmt *stmt, *stmt2;
11
    int ncols, nrows, i;
57
    int ncols, nrows, i;
12
    SEXP ret, tmp, names;
58
    SEXP ret, tmp, names;
13
 
59
 
14
    iname = SDF_INAME(sdf);
60
    iname = SDF_INAME(sdf);
Line 24... Line 70...
24
    type = NULL;
70
    type = NULL;
25
    for (i = 1; i < ncols; i++) {
71
    for (i = 1; i < ncols; i++) {
26
        dectype = sqlite3_column_decltype(stmt, i);
72
        dectype = sqlite3_column_decltype(stmt, i);
27
        colname = sqlite3_column_name(stmt, i);
73
        colname = sqlite3_column_name(stmt, i);
28
        if (strcmp(dectype, "double") == 0) {
74
        if (strcmp(dectype, "double") == 0) {
29
            type = "double";
75
            type = "double"; vectype = "numeric";
30
        } else if (strcmp(dectype, "int") == 0) {
76
        } else if (strcmp(dectype, "int") == 0) {
31
            if (_is_factor2(iname, "factor", colname) || _is_factor2(iname, "ordered", colname)) {
77
            if (_is_factor2(iname, "factor", colname) || _is_factor2(iname, "ordered", colname)) {
32
                type = "text"; break;
78
                type = "text"; vectype = "character"; break;
33
            }
79
            } 
34
            type = "double";
80
            type = "double";
35
        } else if (strcmp(dectype, "bit") == 0) {
81
        } else if (strcmp(dectype, "bit") == 0) {
36
            if (type == NULL) type = "bit";
82
            if (type == NULL) { type = "bit"; vectype = "logical";  }
37
        } else if (strcmp(dectype, "text") == 0) {
83
        } else if (strcmp(dectype, "text") == 0) {
38
            type = "text"; break;
84
            type = "text"; vectype = "character"; break;
39
        }
85
        }
40
    }
86
    }
41
 
87
 
42
 
88
 
43
    /* create sdf with 1 column */
89
    /* create sdf with 1 column */
Line 86... Line 132...
86
    sqlite3_finalize(stmt2);
132
    sqlite3_finalize(stmt2);
87
    sqlite3_finalize(stmt);
133
    sqlite3_finalize(stmt);
88
    _sqlite_commit;
134
    _sqlite_commit;
89
 
135
 
90
    /* return smat sexp */
136
    /* return smat sexp */
91
    PROTECT(ret = NEW_LIST(3)); i = 1; /* 1 for names sexp above */
137
    ret = _create_smat_sexp(mat_iname, vectype, nrows, ncols - 1, names);
92
    SET_VECTOR_ELT(ret, 0, mkString(mat_iname));
-
 
93
    SET_VECTOR_ELT(ret, 1, mkString("sdf_data"));
-
 
94
    SET_VECTOR_ELT(ret, 2, mkString("V1"));
-
 
95
 
138
 
96
    /* set smat data name */
139
    UNUSE_SDF2(iname);
97
    PROTECT(tmp = NEW_CHARACTER(3)); i++;
140
    UNUSE_SDF2(mat_iname);
-
 
141
    return ret;
-
 
142
}
-
 
143
 
-
 
144
/* "decorate" passed svec w/ rownames & colnames to make it a sqlite.matrix */
98
    SET_STRING_ELT(tmp, 0, mkChar("iname"));
145
SEXP sdf_create_smat(SEXP svec, SEXP dimnames) {
99
    SET_STRING_ELT(tmp, 1, mkChar("tblname"));
146
    SEXP tmp, ret = svec;
-
 
147
    sqlite3_stmt *stmt;
100
    SET_STRING_ELT(tmp, 2, mkChar("varname"));
148
    char *mat_iname;
101
    SET_NAMES(ret, tmp);
149
    int i, nrows, ncols;
102
 
150
 
-
 
151
    mat_iname = SDF_INAME(svec);
-
 
152
    if (!USE_SDF1(mat_iname, TRUE, TRUE)) return R_NilValue;
-
 
153
 
-
 
154
    /* create and set sdf_matrix_rownames */
-
 
155
    sprintf(g_sql_buf[0], "create table [%s].sdf_matrix_rownames(name text)", mat_iname);
-
 
156
    _sqlite_error(_sqlite_exec(g_sql_buf[0]));
-
 
157
 
-
 
158
    sprintf(g_sql_buf[0], "insert into [%s].sdf_matrix_rownames(name) values (?)", mat_iname);
-
 
159
    sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt, NULL);
-
 
160
    tmp = VECTOR_ELT(dimnames, 0);
-
 
161
 
-
 
162
    if (inherits(tmp, "sqlite.vector")) {
-
 
163
        char *iname = SDF_INAME(tmp), *tblname = SVEC_TBLNAME(tmp),
-
 
164
             *varname = SVEC_VARNAME(tmp);
-
 
165
        USE_SDF1(iname, TRUE, TRUE);
-
 
166
        nrows = _get_row_count2(iname, TRUE);
-
 
167
        sprintf(g_sql_buf[0], "insert into [%s].sdf_matrix_rownames(name) "
-
 
168
                "select [%s] from [%s].[%s]", mat_iname, varname, iname, tblname);
-
 
169
        _sqlite_error(_sqlite_exec(g_sql_buf[0]));
-
 
170
        UNUSE_SDF2(iname);
-
 
171
    } else {
-
 
172
        nrows = LENGTH(tmp);
-
 
173
        _sqlite_begin;
-
 
174
        for (i = 0; i < nrows; i++) {
-
 
175
            sqlite3_reset(stmt);
-
 
176
            sqlite3_bind_text(stmt, 1, CHAR_ELT(tmp, i), -1, SQLITE_STATIC);
-
 
177
            sqlite3_step(stmt);
-
 
178
        }
-
 
179
        _sqlite_commit;
-
 
180
    }
-
 
181
 
-
 
182
    /* create and set sdf_matrix_colnames */
-
 
183
    sprintf(g_sql_buf[0], "create table [%s].sdf_matrix_colnames(name text)", mat_iname);
-
 
184
    _sqlite_error(_sqlite_exec(g_sql_buf[0]));
-
 
185
 
-
 
186
    sprintf(g_sql_buf[0], "insert into [%s].sdf_matrix_rownames(name) values (?)", mat_iname);
-
 
187
    sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt, NULL);
-
 
188
    tmp = VECTOR_ELT(dimnames, 1);
-
 
189
    ncols = LENGTH(tmp);
-
 
190
    _sqlite_begin;
-
 
191
    for (i = 0; i < ncols; i++) {
-
 
192
        sqlite3_reset(stmt);
-
 
193
        sqlite3_bind_text(stmt, 1, CHAR_ELT(tmp, i), -1, SQLITE_STATIC);
-
 
194
        sqlite3_step(stmt);
-
 
195
    }
-
 
196
    _sqlite_commit;
-
 
197
 
-
 
198
    /* modify the passed svec sexp to smat */
103
    /* set class */
199
    /* set class */
104
    PROTECT(tmp = mkString("sqlite.matrix")); i++;
200
    PROTECT(tmp = mkString("sqlite.matrix")); i = 1;
105
    SET_CLASS(ret, tmp);
201
    SET_CLASS(ret, tmp);
106
 
202
 
107
    /* set smat dim */
203
    /* set smat dim */
108
    PROTECT(tmp = NEW_INTEGER(2)); i++;
204
    PROTECT(tmp = NEW_INTEGER(2)); i++;
109
    INTEGER(tmp)[0] = nrows;
205
    INTEGER(tmp)[0] = nrows;
110
    INTEGER(tmp)[1] = ncols - 1;  /* ncols includes [row names] */
206
    INTEGER(tmp)[1] = ncols; 
111
    setAttrib(ret, SDF_DimSymbol, tmp);
207
    setAttrib(ret, SDF_DimSymbol, tmp);
112
 
208
 
113
    /* set smat dimname */
209
    /* set smat dimname */
114
    PROTECT(tmp = NEW_LIST(2)); i++;
210
    PROTECT(tmp = NEW_LIST(2)); i++;
115
    SET_VECTOR_ELT(tmp, 0, _create_svector_sexp(mat_iname, 
211
    SET_VECTOR_ELT(tmp, 0, _create_svector_sexp(mat_iname, 
116
                "sdf_matrix_rownames", "name", "character"));
212
                "sdf_matrix_rownames", "name", "character"));
117
    SET_VECTOR_ELT(tmp, 1, names);
213
    SET_VECTOR_ELT(tmp, 1, duplicate(VECTOR_ELT(dimnames, 1)));
118
    setAttrib(ret, SDF_DimNamesSymbol, tmp);
214
    setAttrib(ret, SDF_DimNamesSymbol, tmp);
119
 
215
 
-
 
216
    /* sdf.vector.type already set */
-
 
217
 
120
    UNPROTECT(i);
218
    UNPROTECT(i);
-
 
219
    UNUSE_SDF2(mat_iname);
121
 
220
 
-
 
221
    return ret;
-
 
222
}
-
 
223
 
-
 
224
SEXP sdf_get_matrix_columns(SEXP smat, SEXP cols) {
-
 
225
    SEXP colnames, ret;
-
 
226
    sqlite3_stmt *stmt1, *stmt2;
-
 
227
    char *mat_iname, *mat2_iname, *type;
-
 
228
    const char *coltype, *vectype;
-
 
229
    int i, nrows, ncols, index, idxlen, ci_len, ci_actual_len;
-
 
230
    int *col_indices;
-
 
231
 
-
 
232
    mat_iname = SDF_INAME(smat);
-
 
233
    if (!USE_SDF1(mat_iname, TRUE, TRUE)) return R_NilValue;
-
 
234
 
-
 
235
    idxlen = LENGTH(cols);
-
 
236
    sprintf(g_sql_buf[0], "[%s].sdf_matrix_colnames", mat_iname);
-
 
237
    ncols = _get_row_count2(g_sql_buf[0], FALSE);
-
 
238
    sprintf(g_sql_buf[0], "[%s].sdf_matrix_rownames", mat_iname);
-
 
239
    nrows = _get_row_count2(g_sql_buf[0], FALSE);
-
 
240
 
-
 
241
 
-
 
242
    /* get column indices selected */
-
 
243
    ci_len = (ncols > idxlen) ? ncols : idxlen;
-
 
244
    col_indices = (int *)R_alloc(ci_len, sizeof(int));
-
 
245
    ci_actual_len = 0;
-
 
246
 
-
 
247
    if (IS_NUMERIC(cols)) {
-
 
248
        for (i = 0; i < idxlen; i++) {
-
 
249
            index = (int) REAL(cols)[i];
-
 
250
            if (index <= ncols && index > 0) col_indices[ci_actual_len++] = index-1;
-
 
251
        }
-
 
252
    } else if (IS_INTEGER(cols)) {
-
 
253
        for (i = 0; i < idxlen; i++) {
-
 
254
            index = INTEGER(cols)[i];
-
 
255
            if (index <= ncols && index > 0) col_indices[ci_actual_len++] = index-1;
-
 
256
        }
-
 
257
    } else if (IS_LOGICAL(cols)) {
-
 
258
        for (i = 0; i < ncols; i++) {
-
 
259
            if (LOGICAL(cols)[i % ncols]) col_indices[ci_actual_len++] = INTEGER(cols)[i];
-
 
260
        }
-
 
261
    }
-
 
262
 
-
 
263
    /* get matrix "mode" / type */
-
 
264
    sprintf(g_sql_buf[1], "select [row name], V1 from [%s].[sdf_data] limit ?,?", mat_iname);
-
 
265
    sqlite3_prepare(g_workspace, g_sql_buf[1], -1, &stmt1, NULL);
-
 
266
    sqlite3_bind_int(stmt1, 1, 1);  /* limit 1,1 */
-
 
267
    sqlite3_bind_int(stmt1, 2, 1);
-
 
268
    sqlite3_step(stmt1);
-
 
269
    coltype = (const char*) strcpy(g_sql_buf[0], sqlite3_column_decltype(stmt1, 1));
-
 
270
    sqlite3_finalize(stmt1);
-
 
271
 
-
 
272
    PROTECT(colnames = NEW_CHARACTER(ci_actual_len));
-
 
273
 
-
 
274
    /* create new matrix */
-
 
275
    mat2_iname = _create_svector1(mkString(mat_iname), coltype, NULL, TRUE);
-
 
276
    coltype = strcpy(g_sql_buf[3], g_sql_buf[0]);
-
 
277
 
-
 
278
    _sqlite_begin;
-
 
279
 
-
 
280
    /* create sdf_matrix_rownames and sdf_matrix_colnames */
-
 
281
    sprintf(g_sql_buf[0], "create table [%s].sdf_matrix_rownames(name text)", mat2_iname);
-
 
282
    _sqlite_error(_sqlite_exec(g_sql_buf[0]));
-
 
283
    sprintf(g_sql_buf[0], "create table [%s].sdf_matrix_colnames(name text)", mat2_iname);
-
 
284
    _sqlite_error(_sqlite_exec(g_sql_buf[0]));
-
 
285
 
-
 
286
    /* stmt to insert-select to the new matrix */
-
 
287
    sprintf(g_sql_buf[0], "insert into [%s].sdf_data([row name], V1) "
-
 
288
            " select [row name], V1 from [%s].[sdf_data] limit ?,?",
-
 
289
            mat2_iname, mat_iname);
-
 
290
    sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt1, NULL);
-
 
291
 
-
 
292
    /* stmt to insert-select to the new matrix-column table */
-
 
293
    sprintf(g_sql_buf[0], "insert into [%s].sdf_matrix_colnames "
-
 
294
            " select name from [%s].sdf_matrix_colnames limit ?, 1", mat2_iname, mat_iname);
-
 
295
    sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt2, NULL); 
-
 
296
 
-
 
297
    for (i = 0; i < ci_actual_len; i++) {
-
 
298
        sqlite3_reset(stmt1);
-
 
299
        sqlite3_bind_int(stmt1, 1, col_indices[i]*nrows);
-
 
300
        sqlite3_bind_int(stmt1, 2, nrows);
-
 
301
        sqlite3_step(stmt1);
-
 
302
 
-
 
303
        sqlite3_reset(stmt2);
-
 
304
        sqlite3_bind_int(stmt2, 1, col_indices[i]+1);
-
 
305
        sqlite3_step(stmt2);
-
 
306
    }
-
 
307
 
-
 
308
    sqlite3_finalize(stmt1);
-
 
309
    sqlite3_finalize(stmt2);
-
 
310
 
-
 
311
    /* copy colnames to a sexp, as the sexp's names() */
-
 
312
    sprintf(g_sql_buf[0], "select name from [%s].sdf_matrix_colnames", mat2_iname);
-
 
313
    sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt1, NULL);
-
 
314
 
-
 
315
    for (i = 0; sqlite3_step(stmt1) == SQLITE_ROW; i++) {
-
 
316
        SET_STRING_ELT(colnames, i, mkChar((char *)sqlite3_column_text(stmt1, 0)));
-
 
317
    }
-
 
318
 
-
 
319
    sqlite3_finalize(stmt1);
-
 
320
 
-
 
321
    /* copy matrix-rows table */
-
 
322
    sprintf(g_sql_buf[0], "insert into [%s].sdf_matrix_rownames "
-
 
323
            "select * from [%s].sdf_matrix_rownames", mat2_iname, mat_iname);
-
 
324
    _sqlite_error(_sqlite_exec(g_sql_buf[0]));
-
 
325
 
-
 
326
    _sqlite_commit;
-
 
327
 
-
 
328
    /* return matrix SEXP */
-
 
329
    if (strcmp(coltype, "text") == 0) vectype = "character";
-
 
330
    else if (strcmp(coltype, "int") == 0) vectype = "integer";
-
 
331
    else if (strcmp(coltype, "double") == 0) vectype = "numeric";
-
 
332
    ret = _create_smat_sexp(mat2_iname, coltype, nrows, ci_actual_len, colnames);
-
 
333
 
-
 
334
    
-
 
335
 
122
    UNUSE_SDF2(iname);
336
    UNPROTECT(1);
123
    UNUSE_SDF2(mat_iname);
337
    UNUSE_SDF2(mat_iname);
-
 
338
    UNUSE_SDF2(mat2_iname);
124
    return ret;
339
    return ret;
125
}
340
}