The R Project SVN R

Rev

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

Rev 27365 Rev 27383
Line 224... Line 224...
224
{
224
{
225
    int canstretch, count, i, nmax;
225
    int canstretch, count, i, nmax;
226
    SEXP indx;
226
    SEXP indx;
227
    canstretch = *stretch;
227
    canstretch = *stretch;
228
    if (!canstretch && ns > nx)
228
    if (!canstretch && ns > nx)
229
        error("(subscript) logical subscript too long");
229
	error("(subscript) logical subscript too long");
230
    nmax = (ns > nx) ? ns : nx;
230
    nmax = (ns > nx) ? ns : nx;
231
    *stretch = (ns > nx) ? ns : 0;
231
    *stretch = (ns > nx) ? ns : 0;
232
    if (ns == 0)
232
    if (ns == 0)
233
        return(allocVector(INTSXP, 0));
233
	return(allocVector(INTSXP, 0));
234
    count = 0;
234
    count = 0;
235
    for (i = 0; i < nmax; i++)
235
    for (i = 0; i < nmax; i++)
236
        if (LOGICAL(s)[i%ns] != FALSE)
236
	if (LOGICAL(s)[i%ns])
237
            count++;
237
	    count++;
238
    indx = allocVector(INTSXP, count);
238
    indx = allocVector(INTSXP, count);
239
    count = 0;
239
    count = 0;
240
    for (i = 0; i < nmax; i++) {
240
    for (i = 0; i < nmax; i++)
241
        int tmp = LOGICAL(s)[i%ns];
241
	if (LOGICAL(s)[i%ns]) {
242
        if (tmp == NA_LOGICAL)
242
	    if (LOGICAL(s)[i%ns] == NA_LOGICAL)
243
            INTEGER(indx)[count++] = NA_INTEGER;
243
		INTEGER(indx)[count++] = NA_INTEGER;
-
 
244
	    else
244
        else if (tmp == TRUE) INTEGER(indx)[count++] = i + 1;
245
		INTEGER(indx)[count++] = i + 1;
245
    }
246
	}
246
    return indx;
247
    return indx;
247
}
248
}
248
 
249
 
249
static SEXP negativeSubscript(SEXP s, int ns, int nx)
250
static SEXP negativeSubscript(SEXP s, int ns, int nx)
250
{
251
{
-
 
252
    SEXP indx;
251
    int count, i;
253
    int stretch = 0;
-
 
254
    int i;
252
    SEXP indx = PROTECT(allocVector(LGLSXP, nx));
255
    PROTECT(indx = allocVector(INTSXP, nx));
253
 
-
 
254
    for (i = 0; i < nx; i++)
256
    for (i = 0; i < nx; i++)
255
        LOGICAL(indx)[i] = TRUE;
257
	INTEGER(indx)[i] = 1;
256
    count = nx;
-
 
257
    for (i = 0; i < ns; i++)
258
    for (i = 0; i < ns; i++)
258
        if (INTEGER(s)[i] != 0) {
259
	if (INTEGER(s)[i] != 0)
259
            LOGICAL(indx)[-INTEGER(s)[i] - 1] = FALSE;
260
	    INTEGER(indx)[-INTEGER(s)[i] - 1] = 0;
260
            count--;
-
 
261
        }
-
 
262
    s = allocVector(INTSXP, count);
261
    s = logicalSubscript(indx, nx, nx, &stretch);
263
    count = 0;
-
 
264
    for (i = 0; i < nx; i++)
-
 
265
        if (LOGICAL(indx)[i])
-
 
266
            INTEGER(s)[count++] = i + 1;
-
 
267
 
-
 
268
    UNPROTECT(1);
262
    UNPROTECT(1);
269
    return s;
263
    return s;
270
}
264
}
271
 
265
 
272
static SEXP positiveSubscript(SEXP s, int ns, int nx)
266
static SEXP positiveSubscript(SEXP s, int ns, int nx)
273
{
267
{
274
    SEXP indx;
268
    SEXP indx;
275
    int i, zct = 0;
269
    int i, zct = 0;
276
    for (i = 0; i < ns; i++) {
270
    for (i = 0; i < ns; i++) {
277
        if (INTEGER(s)[i] == 0)
271
	if (INTEGER(s)[i] == 0)
278
            zct++;
272
	    zct++;
279
    }
273
    }
280
    if (zct) {
274
    if (zct) {
281
        indx = allocVector(INTSXP, (ns - zct));
275
	indx = allocVector(INTSXP, (ns - zct));
282
        for (i = 0, zct = 0; i < ns; i++)
276
	for (i = 0, zct = 0; i < ns; i++)
283
            if (INTEGER(s)[i] != 0)
277
	    if (INTEGER(s)[i] != 0)
284
                INTEGER(indx)[zct++] = INTEGER(s)[i];
278
		INTEGER(indx)[zct++] = INTEGER(s)[i];
285
        return indx;
279
	return indx;
-
 
280
    }
-
 
281
    else
286
    } else return s;
282
	return s;
287
}
283
}
288
 
284
 
289
static SEXP integerSubscript(SEXP s, int ns, int nx, int *stretch)
285
static SEXP integerSubscript(SEXP s, int ns, int nx, int *stretch)
290
{
286
{
291
    int i, ii, min, max, canstretch;
287
    int i, ii, min, max, canstretch;
292
    int have_na = 0;
-
 
293
    canstretch = *stretch;
288
    canstretch = *stretch;
294
    *stretch = 0;
289
    *stretch = 0;
295
    min = 1;
290
    min = 0;
296
    max = 0;
291
    max = 0;
297
    for (i = 0; i < ns; i++) {
292
    for (i = 0; i < ns; i++) {
298
        ii = INTEGER(s)[i];
293
	ii = INTEGER(s)[i];
299
        if (ii == NA_INTEGER) {
294
	if (ii != NA_INTEGER) {
300
            have_na = 1;
-
 
301
        } else {
-
 
302
            if (ii < min)
295
	    if (ii < min)
303
                min = ii;
296
		min = ii;
304
            if (ii > max)
297
	    if (ii > max)
305
                max = ii;
298
		max = ii;
306
        }
299
	}
307
    }
300
    }
308
    if (min < -nx)
301
    if (min < -nx)
309
        error("subscript out of bounds");
302
	error("subscript out of bounds");
310
    if (max > nx) {
303
    if (max > nx) {
311
        if(canstretch) *stretch = max;
304
	if(canstretch) *stretch = max;
312
        else error("subscript out of bounds");
305
	else error("subscript out of bounds");
313
    }
306
    }
314
    if (min < 0) {
307
    if (min < 0) {
315
        if (max != 0 || have_na)
308
	if (max == 0) return negativeSubscript(s, ns, nx);
316
            error("only 0's may mix with negative subscripts");
309
	else error("only 0's may mix with negative subscripts");
317
        return negativeSubscript(s, ns, nx);
-
 
318
    }
310
    }
319
    if (have_na || min == 0)
-
 
320
        return positiveSubscript(s, ns, nx);
311
    else return positiveSubscript(s, ns, nx);
321
    else return s;
312
    return R_NilValue;
322
}
313
}
323
 
314
 
324
typedef SEXP (*StringEltGetter)(SEXP x, int i); 
315
typedef SEXP (*StringEltGetter)(SEXP x, int i);
325
 
316
 
326
static SEXP stringSubscript(SEXP s, int ns, int nx, SEXP names,
317
static SEXP stringSubscript(SEXP s, int ns, int nx, SEXP names,
327
                            StringEltGetter strg,
-
 
328
                            int *stretch)
318
			    StringEltGetter strg, int *stretch)
329
{
319
{
330
    SEXP indx, indexnames;
320
    SEXP indx, indexnames;
331
    int i, j, nnames, sub, extra;
321
    int i, j, nnames, sub, extra;
332
    int canstretch = *stretch;
322
    int canstretch = *stretch;
333
    PROTECT(s);
323
    PROTECT(s);
Line 344... Line 334...
344
 
334
 
345
    for (i = 0; i < ns; i++) {
335
    for (i = 0; i < ns; i++) {
346
	sub = 0;
336
	sub = 0;
347
	if (names != R_NilValue) {
337
	if (names != R_NilValue) {
348
	    for (j = 0; j < nnames; j++) {
338
	    for (j = 0; j < nnames; j++) {
349
        SEXP name_j = strg(names, j);
339
	        SEXP names_j = strg(names, j);
350
        if (TYPEOF(name_j) != CHARSXP)
340
		if (TYPEOF(names_j) != CHARSXP)
351
            error("character vector element does not have type CHARSXP");
341
		    error("character vector element does not have type CHARSXP");
352
		if (NonNullStringMatch(STRING_ELT(s, i), name_j)) {
342
		if (NonNullStringMatch(STRING_ELT(s, i), names_j)) {
353
		    sub = j + 1;
343
		    sub = j + 1;
354
		    SET_STRING_ELT(indexnames, i, R_NilValue);
344
		    SET_STRING_ELT(indexnames, i, R_NilValue);
355
		    break;
345
		    break;
356
		}
346
		}
357
        }
347
	    }
358
	}
348
	}
359
	if (sub == 0) {
349
	if (sub == 0) {
360
	    for (j = 0 ; j < i ; j++)
350
	    for (j = 0 ; j < i ; j++)
361
		if (NonNullStringMatch(STRING_ELT(s, i), STRING_ELT(s, j))) {
351
		if (NonNullStringMatch(STRING_ELT(s, i), STRING_ELT(s, j))) {
362
		    sub = INTEGER(indx)[j];
352
		    sub = INTEGER(indx)[j];
Line 389... Line 379...
389
    dim is the dimension (0 to k-1)
379
    dim is the dimension (0 to k-1)
390
    s is the subscript list, 
380
    s is the subscript list, 
391
    dims is the dimensions of x
381
    dims is the dimensions of x
392
    dng is a function (usually getAttrib) that obtains the dimnames
382
    dng is a function (usually getAttrib) that obtains the dimnames
393
    x is the array to be subscripted. 
383
    x is the array to be subscripted. 
394
   strg extracts elements of a string vector, either obtained by using
-
 
395
   dng(x, R_NamesSymbol) or from one of the elements of an VECSXP
-
 
396
   obtained from dng(x, R_DimNamesSymbol).
-
 
397
*/
384
*/
398
 
385
 
399
typedef SEXP (*AttrGetter)(SEXP x, SEXP data);
386
typedef SEXP AttrGetter(SEXP x, SEXP data);
400
 
387
 
401
SEXP arraySubscript(int dim, SEXP s, SEXP dims,
388
SEXP arraySubscript(int dim, SEXP s, SEXP dims, AttrGetter dng,
402
                    AttrGetter dng, StringEltGetter strg, SEXP x)
389
		    StringEltGetter strg, SEXP x)
403
{
390
{
404
    int nd, ns, stretch = 0;
391
    int nd, ns, stretch = 0;
405
    SEXP dnames, tmp;
392
    SEXP dnames, tmp;
406
    ns = length(s);
393
    ns = length(s);
407
    nd = INTEGER(dims)[dim];
394
    nd = INTEGER(dims)[dim];
Line 421... Line 408...
421
    case STRSXP:
408
    case STRSXP:
422
	dnames = dng(x, R_DimNamesSymbol);
409
	dnames = dng(x, R_DimNamesSymbol);
423
	if (dnames == R_NilValue)
410
	if (dnames == R_NilValue)
424
	    error("no dimnames attribute for array");
411
	    error("no dimnames attribute for array");
425
	dnames = VECTOR_ELT(dnames, dim);
412
	dnames = VECTOR_ELT(dnames, dim);
426
	return stringSubscript(s, ns, nd, dnames, strg,
413
	return stringSubscript(s, ns, nd, dnames, strg, &stretch);
427
                           &stretch);
-
 
428
    case SYMSXP:
414
    case SYMSXP:
429
	if (s == R_MissingArg)
415
	if (s == R_MissingArg)
430
	    return nullSubscript(nd);
416
	    return nullSubscript(nd);
431
    default:
417
    default:
432
	error("invalid subscript");
418
	error("invalid subscript");
Line 449... Line 435...
449
 
435
 
450
    ans = R_NilValue;
436
    ans = R_NilValue;
451
    if (isVector(x) || isList(x) || isLanguage(x)) {
437
    if (isVector(x) || isList(x) || isLanguage(x)) {
452
	nx = length(x);
438
	nx = length(x);
453
 
439
 
454
	ans = vectorSubscript(nx, s, stretch, getAttrib,
440
	ans = vectorSubscript(nx, s, stretch, getAttrib, (STRING_ELT), x);
455
                          (STRING_ELT), x);
-
 
456
    }
441
    }
457
    else error("subscripting on non-vector");
442
    else error("subscripting on non-vector");
458
    return ans;
443
    return ans;
459
 
444
 
460
}
445
}
461
 
446
 
462
/* nx is the length of the object being subscripted,
447
/* nx is the length of the object being subscripted,
463
   s is the R subscript value,
448
   s is the R subscript value,
464
   dng gets a given attrib for x, which is the object we are
449
   dng gets a given attrib for x, which is the object we are
465
   subsetting,
450
   subsetting,
466
   strg extracts elements of a string vector, either obtained by using
-
 
467
   dng(x, R_NamesSymbol) or from one of the elements of an VECSXP
-
 
468
   obtained from dng(x, R_DimNamesSymbol).
-
 
469
*/
451
*/
470
 
452
 
471
SEXP vectorSubscript(int nx, SEXP s, int *stretch,
453
SEXP vectorSubscript(int nx, SEXP s, int *stretch, AttrGetter dng,
472
                     AttrGetter dng, StringEltGetter strg, SEXP x)
454
		     StringEltGetter strg, SEXP x) 
473
{
455
{
474
    int ns;
456
    int ns;
475
    SEXP ans=R_NilValue, tmp;
457
    SEXP ans=R_NilValue, tmp;
476
 
458
 
477
    ns = length(s);
459
    ns = length(s);
Line 504... Line 486...
504
	break;
486
	break;
505
    case STRSXP:
487
    case STRSXP:
506
    {
488
    {
507
	SEXP names = dng(x, R_NamesSymbol);
489
	SEXP names = dng(x, R_NamesSymbol);
508
	/* *stretch = 0; */
490
	/* *stretch = 0; */
509
	ans = stringSubscript(s, ns, nx, names, strg,
491
	ans = stringSubscript(s, ns, nx, names, strg, stretch);
510
                          stretch);
-
 
511
    }
492
    }
512
    break;
493
    break;
513
    case SYMSXP:
494
    case SYMSXP:
514
	*stretch = 0;
495
	*stretch = 0;
515
	if (s == R_MissingArg) {
496
	if (s == R_MissingArg) {
Line 520... Line 501...
520
	error("invalid subscript type");
501
	error("invalid subscript type");
521
    }
502
    }
522
    UNPROTECT(1);
503
    UNPROTECT(1);
523
    return ans;
504
    return ans;
524
}
505
}
-
 
506
 
-
 
507
 
-
 
508