示例#1
0
文件: coredata.c 项目: corwinjoy/xts
SEXP coredata (SEXP x, SEXP copyAttr)
{
  /* copyAttr is a LGLSXP flag to indicate whether all
     attributes are to be left intact.  This provides
     compatability with xts, by stripping all attributes
     if desired, without the overhead or adding then
     removing
  */
  SEXP result;
  int i, j, ncs, nrs;
  int P=0;
  PROTECT(result = allocVector(TYPEOF(x), length(x))); P++;
  switch( TYPEOF(x)) {
    case REALSXP:
      memcpy(REAL(result), REAL(x), length(result) * sizeof(double));
      break;
    case INTSXP:
      memcpy(INTEGER(result), INTEGER(x), length(result) * sizeof(int));
      break;
    case LGLSXP:
      memcpy(LOGICAL(result), LOGICAL(x), length(result) * sizeof(int));
      break;
    case CPLXSXP:
      memcpy(COMPLEX(result), COMPLEX(x), length(result) * sizeof(Rcomplex));
      break;
    case STRSXP:
      ncs = ncols(x); nrs = nrows(x);
      for(j=0; j< ncs; j++)
      for(i=0; i< nrs; i++)
        SET_STRING_ELT(result, i+j*nrs, STRING_ELT(x, i+j*nrs));
      break;
    case RAWSXP:
      memcpy(RAW(result), RAW(x), length(result) * sizeof(unsigned char));
      break;
    default:
      error("currently unsupported data type");
      break;
  }
  if( !isNull(getAttrib(x, R_DimSymbol))) {
    setAttrib(result, R_DimSymbol, getAttrib(x, R_DimSymbol));
    if( !isNull(getAttrib(x, R_DimNamesSymbol)) ) {  
      setAttrib(result, R_DimNamesSymbol, getAttrib(x,R_DimNamesSymbol));
    }
  } else {
    setAttrib(result, R_NamesSymbol, getAttrib(x, R_NamesSymbol));
  }
  if( asLogical(copyAttr)) {
    copyMostAttrib(x,result);
    setAttrib(result, R_ClassSymbol, getAttrib(x, install("oclass")));
  }
  setAttrib(result, xts_IndexSymbol,     R_NilValue);
  setAttrib(result, install("oclass"),    R_NilValue);
  setAttrib(result, install("frequency"), R_NilValue);

  UNPROTECT(P);
  return result;
}
示例#2
0
SEXP rev (SEXP x) {
  SEXP res;
  int i, r, P=0;
  PROTECT(res = allocVector(REALSXP, length(x))); P++;
  
  for(i=length(x), r=0; i>0; i--, r++) {
    REAL(res)[r] = REAL(x)[i-1];
  }
  
  copyMostAttrib(x, res);
  UNPROTECT(P);
  return res;
}
示例#3
0
SEXP R_copyTruncate(SEXP x, SEXP R_n) {
    if (isNull(x) || TYPEOF(x) != VECSXP)
	error("'x' not of type list");
    if (isNull(R_n) || TYPEOF(R_n) != INTSXP)
	error("'n' not of type integer");
    int i, k, n;
    SEXP s, r, t = 0;

    n = INTEGER(R_n)[0];
    if (n < 0)
	error("'n' invalid value");

    r = PROTECT(allocVector(VECSXP, LENGTH(x)));

    for (i = 0; i < LENGTH(x); i++) {
	s = VECTOR_ELT(x, i);
	if (TYPEOF(s) != STRSXP)
	    error("component not of type character");
	if (LENGTH(s) > n) {
	    SET_VECTOR_ELT(r, i, (t = allocVector(STRSXP, n)));
	    for (k = 0; k < n; k++)
		SET_STRING_ELT(t, k, STRING_ELT(s, k));
	    copyMostAttrib(t, s);
	    if ((s = getAttrib(s, R_NamesSymbol)) != R_NilValue) {
		SEXP v;
		setAttrib(t, R_NamesSymbol, (v = allocVector(STRSXP, n)));
		for (k = 0; k < n; k++)
		    SET_STRING_ELT(v, k, STRING_ELT(s, k));
	    }
	} else
	    SET_VECTOR_ELT(r, i, s);
    }
    UNPROTECT(1);

    if (!t)
	return x;
    
    SET_ATTRIB(r, ATTRIB(x));
    SET_OBJECT(r, OBJECT(x));
    if (IS_S4_OBJECT(x))
	SET_S4_OBJECT(r);

    return r;
}
示例#4
0
文件: gsumm.c 项目: 23data/data.table
// gmax
SEXP gmax(SEXP x, SEXP narm)
{
    if (!isLogical(narm) || LENGTH(narm)!=1 || LOGICAL(narm)[0]==NA_LOGICAL) error("na.rm must be TRUE or FALSE");
    if (!isVectorAtomic(x)) error("GForce max can only be applied to columns, not .SD or similar. To find max of all items in a list such as .SD, either add the prefix base::max(.SD) or turn off GForce optimization using options(datatable.optimize=1). More likely, you may be looking for 'DT[,lappy(.SD,max),by=,.SDcols=]'");
    R_len_t i, thisgrp=0;
    int n = LENGTH(x);
    //clock_t start = clock();
    SEXP ans;
    if (grpn != length(x)) error("grpn [%d] != length(x) [%d] in gmax", grpn, length(x));
    char *update = Calloc(ngrp, char);
    if (update == NULL) error("Unable to allocate %d * %d bytes for gmax", ngrp, sizeof(char));
    switch(TYPEOF(x)) {
    case LGLSXP: case INTSXP:
        ans = PROTECT(allocVector(INTSXP, ngrp));
        for (i=0; i<ngrp; i++) INTEGER(ans)[i] = 0;
        if (!LOGICAL(narm)[0]) { // simple case - deal in a straightforward manner first
            for (i=0; i<n; i++) {
                thisgrp = grp[i];
                if (INTEGER(x)[i] != NA_INTEGER && INTEGER(ans)[thisgrp] != NA_INTEGER) {
                    if ( update[thisgrp] != 1 || INTEGER(ans)[thisgrp] < INTEGER(x)[i] ) {
                        INTEGER(ans)[thisgrp] = INTEGER(x)[i];
                        if (update[thisgrp] != 1) update[thisgrp] = 1;
                    }
                } else  INTEGER(ans)[thisgrp] = NA_INTEGER;
            }
        } else {
            for (i=0; i<n; i++) {
                thisgrp = grp[i];
                if (INTEGER(x)[i] != NA_INTEGER) {
                    if ( update[thisgrp] != 1 || INTEGER(ans)[thisgrp] < INTEGER(x)[i] ) {
                        INTEGER(ans)[thisgrp] = INTEGER(x)[i];
                        if (update[thisgrp] != 1) update[thisgrp] = 1;
                    }
                } else {
                    if (update[thisgrp] != 1) {
                        INTEGER(ans)[thisgrp] = NA_INTEGER;
                    }
                }
            }
            for (i=0; i<ngrp; i++) {
                if (update[i] != 1)  {// equivalent of INTEGER(ans)[thisgrp] == NA_INTEGER
                    warning("No non-missing values found in at least one group. Coercing to numeric type and returning 'Inf' for such groups to be consistent with base");
                    UNPROTECT(1);
                    ans = PROTECT(coerceVector(ans, REALSXP));
                    for (i=0; i<ngrp; i++) {
                        if (update[i] != 1) REAL(ans)[i] = -R_PosInf;
                    }
                }
            }
        }
        break;
    case REALSXP:
        ans = PROTECT(allocVector(REALSXP, ngrp));
        for (i=0; i<ngrp; i++) REAL(ans)[i] = 0;
        if (!LOGICAL(narm)[0]) {
            for (i=0; i<n; i++) {
                thisgrp = grp[i];
                if ( !ISNA(REAL(x)[i]) && !ISNA(REAL(ans)[thisgrp]) ) {
                    if ( update[thisgrp] != 1 || REAL(ans)[thisgrp] < REAL(x)[i] ) {
                        REAL(ans)[thisgrp] = REAL(x)[i];
                        if (update[thisgrp] != 1) update[thisgrp] = 1;
                    }
                } else REAL(ans)[thisgrp] = NA_REAL;
            }
        } else {
            for (i=0; i<n; i++) {
                thisgrp = grp[i];
                if ( !ISNA(REAL(x)[i]) ) {
                    if ( update[thisgrp] != 1 || REAL(ans)[thisgrp] < REAL(x)[i] ) {
                        REAL(ans)[thisgrp] = REAL(x)[i];
                        if (update[thisgrp] != 1) update[thisgrp] = 1;
                    }
                } else {
                    if (update[thisgrp] != 1) {
                        REAL(ans)[thisgrp] = -R_PosInf;
                    }
                }
            }
            // everything taken care of already. Just warn if all NA groups have occurred at least once
            for (i=0; i<ngrp; i++) {
                if (update[i] != 1)  { // equivalent of REAL(ans)[thisgrp] == -R_PosInf
                    warning("No non-missing values found in at least one group. Returning '-Inf' for such groups to be consistent with base");
                    break;
                }
            }
        }
        break;
    default:
        error("Type '%s' not supported by GForce max (gmax). Either add the prefix base::max(.) or turn off GForce optimization using options(datatable.optimize=1)", type2char(TYPEOF(x)));
    }
    copyMostAttrib(x, ans); // all but names,dim and dimnames. And if so, we want a copy here, not keepattr's SET_ATTRIB.
    UNPROTECT(1);
    Free(update);
    // Rprintf("this gmax took %8.3f\n", 1.0*(clock()-start)/CLOCKS_PER_SEC);
    return(ans);
}
示例#5
0
文件: array.c 项目: kalibera/rexp
SEXP attribute_hidden do_earg_transpose(SEXP call, SEXP op, SEXP arg_x, SEXP rho)
{
    SEXP a, r, dims, dimnames, dimnamesnames = R_NilValue,
	ndimnamesnames, rnames, cnames;
    int ldim, ncol = 0, nrow = 0;
    R_xlen_t len = 0;

    a = arg_x;

    if (isVector(a)) {
	dims = getDimAttrib(a);
	ldim = length(dims);
	rnames = R_NilValue;
	cnames = R_NilValue;
	switch(ldim) {
	case 0:
	    len = nrow = LENGTH(a);
	    ncol = 1;
	    rnames = getNamesAttrib(a);
	    dimnames = rnames;/* for isNull() below*/
	    break;
	case 1:
	    len = nrow = LENGTH(a);
	    ncol = 1;
	    dimnames = getDimNamesAttrib(a);
	    if (dimnames != R_NilValue) {
		rnames = VECTOR_ELT(dimnames, 0);
		dimnamesnames = getNamesAttrib(dimnames);
	    }
	    break;
	case 2:
	    ncol = ncols(a);
	    nrow = nrows(a);
	    len = XLENGTH(a);
	    dimnames = getDimNamesAttrib(a);
	    if (dimnames != R_NilValue) {
		rnames = VECTOR_ELT(dimnames, 0);
		cnames = VECTOR_ELT(dimnames, 1);
		dimnamesnames = getNamesAttrib(dimnames);
	    }
	    break;
	default:
	    goto not_matrix;
	}
    }
    else
	goto not_matrix;
    PROTECT(r = allocVector(TYPEOF(a), len));
    R_xlen_t i, j, l_1 = len-1;
    switch (TYPEOF(a)) {
    case LGLSXP:
    case INTSXP:
	// filling in columnwise, "accessing row-wise":
        for (i = 0, j = 0; i < len; i++, j += nrow) {
            if (j > l_1) j -= l_1;
            INTEGER(r)[i] = INTEGER(a)[j];
        }
        break;
    case REALSXP:
        for (i = 0, j = 0; i < len; i++, j += nrow) {
            if (j > l_1) j -= l_1;
            REAL(r)[i] = REAL(a)[j];
        }
        break;
    case CPLXSXP:
        for (i = 0, j = 0; i < len; i++, j += nrow) {
            if (j > l_1) j -= l_1;
            COMPLEX(r)[i] = COMPLEX(a)[j];
        }
        break;
    case STRSXP:
        for (i = 0, j = 0; i < len; i++, j += nrow) {
            if (j > l_1) j -= l_1;
            SET_STRING_ELT(r, i, STRING_ELT(a,j));
        }
        break;
    case VECSXP:
        for (i = 0, j = 0; i < len; i++, j += nrow) {
            if (j > l_1) j -= l_1;
            SET_VECTOR_ELT(r, i, VECTOR_ELT(a,j));
        }
        break;
    case RAWSXP:
        for (i = 0, j = 0; i < len; i++, j += nrow) {
            if (j > l_1) j -= l_1;
            RAW(r)[i] = RAW(a)[j];
        }
        break;
    default:
        UNPROTECT(1);
        goto not_matrix;
    }
    PROTECT(dims = allocVector(INTSXP, 2));
    INTEGER(dims)[0] = ncol;
    INTEGER(dims)[1] = nrow;
    setAttrib(r, R_DimSymbol, dims);
    UNPROTECT(1);
    /* R <= 2.2.0: dropped list(NULL,NULL) dimnames :
     * if(rnames != R_NilValue || cnames != R_NilValue) */
    if(!isNull(dimnames)) {
	PROTECT(dimnames = allocVector(VECSXP, 2));
	SET_VECTOR_ELT(dimnames, 0, cnames);
	SET_VECTOR_ELT(dimnames, 1, rnames);
	if(!isNull(dimnamesnames)) {
	    PROTECT(ndimnamesnames = allocVector(VECSXP, 2));
	    SET_VECTOR_ELT(ndimnamesnames, 1, STRING_ELT(dimnamesnames, 0));
	    SET_VECTOR_ELT(ndimnamesnames, 0,
			   (ldim == 2) ? STRING_ELT(dimnamesnames, 1):
			   R_BlankString);
	    setAttrib(dimnames, R_NamesSymbol, ndimnamesnames);
	    UNPROTECT(1);
	}
	setAttrib(r, R_DimNamesSymbol, dimnames);
	UNPROTECT(1);
    }
    copyMostAttrib(a, r);
    UNPROTECT(1);
    return r;
 not_matrix:
    error(_("argument is not a matrix"));
    return call;/* never used; just for -Wall */
}
示例#6
0
SEXP copyattr(SEXP from, SEXP to)
{
    // for use by [.data.table to retain attribs such as "comments" when subsetting and j is missing
    copyMostAttrib(from, to);
    return(R_NilValue);
}
示例#7
0
文件: lag.c 项目: cran/zoo
SEXP zoo_lag (SEXP x, SEXP _k, SEXP _pad)
{
#ifdef ZOO_DEBUG
Rprintf("zoo_lag\n");
#endif
  SEXP result;
  int i,j;
  double *result_real=NULL;
  int    *result_int=NULL;

  int k=INTEGER(_k)[0] * -1; /* -1 is zoo convention */
  int k_positive = (k > 0) ? 1 : 0;
  int nr = nrows(x);
  int nc = ncols(x);
  int P=0;
  int PAD = INTEGER(coerceVector(_pad,INTSXP))[0];

  if(k > nr)
    error("abs(k) must be less than nrow(x)");

  if(k < 0 && -1*k > nr)
    error("abs(k) must be less than nrow(x)");

  PROTECT(result = allocVector(TYPEOF(x), 
          length(x) - (PAD ? 0 : abs(k)*nc))); P++;

  int nrr;
  if(length(result) > 0)
    nrr = (int)(length(result)/nc);
  else  /* handle zero-length objects */
    nrr = nr - (PAD ? 0 : abs(k));

  if(k_positive) {
  switch(TYPEOF(x)) {
    case REALSXP:
      result_real = REAL(result);
      for(j = 0; j < nc; j++) {
        if(PAD) {
          for(i = 0; i < k; i++)
            result_real[i+(j*nrr)] = NA_REAL;
          memcpy(&REAL(result)[k+(j*nrr)], 
                 &REAL(x)[(j*nrr)], 
                 (nrr-k) * sizeof(double)); 
        } else {
        memcpy(&REAL(result)[(j*nrr)], 
               &REAL(x)[(j*nr)], /* original data need the original 'nr' offset */
               nrr * sizeof(double)); 
        }
      }
      break;
    case INTSXP:
      result_int = INTEGER(result);
      for(j = 0; j < nc; j++) {
        if(PAD) {
          for(i = 0; i < k; i++)
            result_int[i+(j*nrr)] = NA_INTEGER;
          memcpy(&INTEGER(result)[k+(j*nrr)],
                 &INTEGER(x)[(j*nrr)],
                 (nrr-k) * sizeof(int));
        } else {
          memcpy(&INTEGER(result)[(j*nrr)],
                 &INTEGER(x)[(j*nr)],
                 nrr * sizeof(int));
        }
      }
      break;
    case LGLSXP:
      result_int = LOGICAL(result);
      for(j = 0; j < nc; j++) {
        if(PAD) {
          for(i = 0; i < k; i++)
            result_int[i+(j*nrr)] = NA_INTEGER;
          memcpy(&LOGICAL(result)[k+(j*nrr)],
                 &LOGICAL(x)[(j*nrr)],
                 (nrr-k) * sizeof(int));
        } else {
          memcpy(&LOGICAL(result)[(j*nrr)],
                 &LOGICAL(x)[(j*nr)],
                 nrr * sizeof(int));
        }
      }
      break;
    case CPLXSXP:
      for(j = 0; j < nc; j++) {
        if(PAD) {
          for(i = 0; i < k; i++) {
            COMPLEX(result)[i+(j*nrr)].r = NA_REAL;
            COMPLEX(result)[i+(j*nrr)].i = NA_REAL;
          }
          memcpy(&COMPLEX(result)[k+(j*nrr)],
                 &COMPLEX(x)[(j*nrr)],
                 (nrr-k) * sizeof(Rcomplex));
        } else {
          memcpy(&COMPLEX(result)[(j*nrr)],
                 &COMPLEX(x)[(j*nr)],
                 nrr * sizeof(Rcomplex));
        }
      }
      break;
    case RAWSXP:
      for(j = 0; j < nc; j++) {
        if(PAD) {
          for(i = 0; i < k; i++)
            RAW(result)[i+(j*nrr)] = (Rbyte) 0;
          memcpy(&RAW(result)[k+(j*nrr)],
                 &RAW(x)[(j*nrr)],
                 (nrr-k) * sizeof(Rbyte));
        } else {
          memcpy(&RAW(result)[(j*nrr)],
                 &RAW(x)[(j*nr)],
                 nrr * sizeof(Rbyte));
        }
      }
      break;
    case STRSXP:
      for(j = 0; j < nc; j++) {
        if(PAD) {
          for(i = 0; i < k; i++)
            SET_STRING_ELT(result, i+(j*nrr), NA_STRING);
          for(i = 0; i < nrr-k; i++) 
            SET_STRING_ELT(result, k+i+j*nrr, STRING_ELT(x, i+j*nrr));
        } else {
          for(i = 0; i < nrr; i++) 
            SET_STRING_ELT(result, i+j*nrr, STRING_ELT(x, i+j*nr));
        }
      }
      break;
    default:
      error("unsupported type");
      break;
  }
  } else
  if(!k_positive) {
  k = abs(k);
  switch(TYPEOF(x)) {
    case REALSXP:
      result_real = REAL(result);
      for(j =0; j < nc; j++) {
        if(PAD) {
          for(i = nr-k; i < nr; i++)
            result_real[i+(j*nrr)] = NA_REAL;
          memcpy(&REAL(result)[(j*nrr)], 
                 &REAL(x)[k+(j*nrr)], 
                 (nrr-k) * sizeof(double));
        } else {
        memcpy(&REAL(result)[(j*nrr)],
               &REAL(x)[k+(j*nr)],
               nrr * sizeof(double));
        }
      }
      break;
    case INTSXP:
      result_int = INTEGER(result);
      for(j = 0; j < nc; j++) {
        if(PAD) {
          for(i = nr-k; i < nr; i++)
            result_int[i+(j*nrr)] = NA_INTEGER;
          memcpy(&INTEGER(result)[(j*nrr)],
                 &INTEGER(x)[k+(j*nrr)],
                 (nrr-k) * sizeof(int));
        } else {
          memcpy(&INTEGER(result)[(j*nrr)],
                 &INTEGER(x)[k+(j*nr)],
                 nrr * sizeof(int));
        }
      }
      break;
    case LGLSXP:
      result_int = LOGICAL(result);
      for(j = 0; j < nc; j++) {
        if(PAD) {
          for(i = nr-k; i < nr; i++)
            result_int[i+(j*nrr)] = NA_INTEGER;
          memcpy(&LOGICAL(result)[(j*nrr)],
                 &LOGICAL(x)[k+(j*nrr)],
                 (nrr-k) * sizeof(int));
        } else {
          memcpy(&LOGICAL(result)[(j*nrr)],
                 &LOGICAL(x)[k+(j*nr)],
                 nrr * sizeof(int));
        }
      }
      break;
    case CPLXSXP:
      for(j = 0; j < nc; j++) {
        if(PAD) {
          for(i = nr-k; i < nr; i++) {
            COMPLEX(result)[i+(j*nrr)].r = NA_REAL;
            COMPLEX(result)[i+(j*nrr)].i = NA_REAL;
          }
          memcpy(&COMPLEX(result)[(j*nrr)],
                 &COMPLEX(x)[k+(j*nrr)],
                 (nrr-k) * sizeof(Rcomplex));
        } else {
          memcpy(&COMPLEX(result)[(j*nrr)],
                 &COMPLEX(x)[k+(j*nr)],
                 nrr * sizeof(Rcomplex));
        }
      }
      break;
    case RAWSXP:
      for(j = 0; j < nc; j++) {
        if(PAD) {
          for(i = nr-k; i < nr; i++)
            RAW(result)[i+(j*nrr)] = (Rbyte) 0;
          memcpy(&RAW(result)[(j*nrr)],
                 &RAW(x)[k+(j*nrr)],
                 (nrr-k) * sizeof(Rbyte));
        } else {
          memcpy(&RAW(result)[(j*nrr)],
                 &RAW(x)[k+(j*nr)],
                 nrr * sizeof(Rbyte));
        }
      }
      break;
    case STRSXP:
      for(j = 0; j < nc; j++) {
        if(PAD) {
          for(i = nr-k; i < nr; i++)
            SET_STRING_ELT(result, i+(j*nrr), NA_STRING);
          for(i = 0; i < nrr-k; i++)
            SET_STRING_ELT(result, i+(j*nrr), STRING_ELT(x, k+i+(j*nrr)));
        } else {
          for(i = 0; i < nr-k; i++)
            SET_STRING_ELT(result, i+(j*nrr), STRING_ELT(x, k+i+(j*nr)));
        }
      }
      break;
    default:
      error("unsupported type");
      break;
  }
  }

  copyMostAttrib(x,result);
  if(!PAD) {
    // likely unneeded as copyMostAttrib will cover
  //  setAttrib(result, install("index"), getAttrib(x, install("index")));
  //} else {
    SEXP index, newindex;
    PROTECT(index = getAttrib(x, install("index"))); P++;
    if(IS_S4_OBJECT(index)) {
      /* should make this
         1) generic for any S4 object if possible
         2) test for timeDate as this is important
      */
      if(STRING_ELT(getAttrib(index, R_ClassSymbol),0)!=mkChar("timeDate"))
        error("'S4' objects must be of class 'timeDate'");
      index = GET_SLOT(index, install("Data"));
    }
    PROTECT(newindex = allocVector(TYPEOF(index), nrr)); P++;
    switch(TYPEOF(index)) {
      case REALSXP:
        if(k_positive) {
          memcpy(REAL(newindex), &REAL(index)[k], nrr * sizeof(double));
        } else {
          memcpy(REAL(newindex), REAL(index), nrr * sizeof(double));
        }
        break;
      case INTSXP:
        if(k_positive) {
        memcpy(INTEGER(newindex), &INTEGER(index)[k], nrr * sizeof(int));
        } else {
        memcpy(INTEGER(newindex), INTEGER(index), nrr * sizeof(int));
        }
        break;
      default:
        break;
    }
    if(IS_S4_OBJECT(getAttrib(x, install("index")))) {
      /* need to assure that this is timeDate */
      SEXP tmp = PROTECT(getAttrib(x, install("index"))); P++;
      SEXP class = PROTECT(MAKE_CLASS("timeDate")); P++;
      SEXP timeDate = PROTECT(NEW_OBJECT(class)); P++;
      copyMostAttrib(index,newindex);
      SET_SLOT(timeDate,install("Data"),newindex);
      SEXP format = PROTECT(GET_SLOT(tmp, install("format"))); P++;
      SET_SLOT(timeDate,install("format"), format);
      SEXP finCenter = PROTECT(GET_SLOT(tmp, install("FinCenter"))); P++;
      SET_SLOT(timeDate,install("FinCenter"), finCenter);
      setAttrib(result, install("index"), timeDate);
    } else {
示例#8
0
SEXP readSlicePorStream(SEXP porStream, SEXP what, SEXP s_vars, SEXP s_cases, SEXP s_types){
  porStreamBuf *b = get_porStreamBuf(porStream);
  PROTECT(s_vars = coerceVector(s_vars,LGLSXP));
  PROTECT(s_cases = coerceVector(s_cases,LGLSXP));
  PROTECT(s_types = coerceVector(s_types,INTSXP));
  int nvar = length(s_types);
  int ncases = length(s_cases);
  int *types = INTEGER(s_types);
  if(LENGTH(s_vars)!=nvar) error("\'s_vars\' argument has wrong length");

  int ii,i,j,k, m=0, n = 0;
  for(j = 0; j < nvar; j++) m+=LOGICAL(s_vars)[j];
  for(i = 0; i < ncases; i++) n+=LOGICAL(s_cases)[i];

  SEXP x, y, data;
  char *charbuf;
  int charbuflen = 0;
  PROTECT(data = allocVector(VECSXP,m));
  k = 0;
  for(j = 0; j < nvar; j++){
    if(types[j] > charbuflen) charbuflen = types[j];
    if(LOGICAL(s_vars)[j]){
      if(types[j]==0)
        SET_VECTOR_ELT(data,k,allocVector(REALSXP,n));
      else {
        SET_VECTOR_ELT(data,k,allocVector(STRSXP,n));
        }
      k++;
    }
  }
  charbuf = R_alloc(charbuflen+1,sizeof(char));
  ii = 0;
  for(i = 0; i < ncases; i++){
    if(atEndPorStream(b) || (b->pos < 80 && b->buf[b->pos] == 'Z')){
      int new_length = ii;
      for(j = 0; j < m; j++){
        x = VECTOR_ELT(data,j);
        SET_VECTOR_ELT(data,j,lengthgets(x,new_length));
      }
      n = new_length;
      break;
    }
    if(LOGICAL(s_cases)[i]){
      k = 0;
      for(j = 0; j < nvar; j++){
        if(atEndPorStream(b)) {
            printPorStreamBuf(b);
            warning("\nPremature end of data");
        }
        if(types[j]==0){
          if(LOGICAL(s_vars)[j]){
            REAL(VECTOR_ELT(data,k))[ii] = readDoublePorStream1(b);
            k++;
          }
          else {
            readDoublePorStream1(b);
          }
        }
        else {
          if(LOGICAL(s_vars)[j]){
            SET_STRING_ELT(VECTOR_ELT(data,k), ii,
                              mkChar(readCHARPorStream(b,charbuf,types[j])));
            k++;
          }
          else {
            readCHARPorStream(b,charbuf,types[j]);
          }
        }
      }
      ii++;
    }
    else {
      for(j = 0; j < nvar; j++){
        if(atEndPorStream(b)) {
            printPorStreamBuf(b);
            error("\nPremature end of data");
        }
        if(types[j]==0) readDoublePorStream1(b);
        else readCHARPorStream(b,charbuf,types[j]);
      }
    }
  }
  k = 0;
  for(j = 0; j < nvar; j++){
    if(LOGICAL(s_vars)[j]){
      x = VECTOR_ELT(what,j);
      y = VECTOR_ELT(data,k);
      copyMostAttrib(x,y);
      k++;
    }
  }

  UNPROTECT(4);
  return data;
}
示例#9
0
文件: rbind.c 项目: Glanda/xts
//SEXP do_rbind_xts (SEXP x, SEXP y, SEXP env) {{{
SEXP do_rbind_xts (SEXP x, SEXP y, SEXP dup)
{
  int nrx, ncx, nry, ncy, truelen, len;
  int no_duplicate = LOGICAL(dup)[0];
  int i, j, ij, ij_x, ij_y, xp=1, yp=1, add_y=0;
  int P=0; // PROTECT counter
  int mode;
  SEXP result, xindex, yindex, newindex;


  int *int_result=NULL, *int_x=NULL, *int_y=NULL;
  int *int_newindex=NULL, *int_xindex=NULL, *int_yindex=NULL;
  double *real_result=NULL, *real_x=NULL, *real_y=NULL;
  double *real_newindex=NULL, *real_xindex=NULL, *real_yindex=NULL;

  nrx = nrows(x);
  ncx = ncols(x);

  nry = nrows(y);
  ncy = ncols(y);

  truelen = len = nrx + nry;

  if( isNull(x) || isNull(y) ) {
    /* Handle NULL values by returning non-null object */
    if(!isNull(x)) return x;
    return y;
  }

  if( !isXts(x) ) {
    PROTECT( x = tryXts(x) ); P++;
  }
  if( !isXts(y) ) {
    PROTECT( y = tryXts(y) ); P++;
  }

  /* need to convert different types of x and y if needed */
  if( TYPEOF(x) != TYPEOF(y) ) {
    warning("mismatched types: converting objects to numeric");  // FIXME  not working!!!????
    PROTECT(x = coerceVector(x, REALSXP)); P++;
    PROTECT(y = coerceVector(y, REALSXP)); P++;
  } 


  mode = TYPEOF(x);

  if(ncx != ncy)
    error("data must have same number of columns to bind by row");

  PROTECT(xindex = getAttrib(x, xts_IndexSymbol)); P++;
  PROTECT(yindex = getAttrib(y, xts_IndexSymbol)); P++;


  if( TYPEOF(xindex) != TYPEOF(yindex) ) 
  {
    PROTECT(xindex = coerceVector(xindex, REALSXP)); P++;
    PROTECT(yindex = coerceVector(yindex, REALSXP)); P++;
  }

#ifdef RBIND_APPEND
if(TYPEOF(xindex)==REALSXP) {
  if(REAL(xindex)[length(xindex)-1] < REAL(yindex)[0]) {
    UNPROTECT(P);
    return rbind_append(x,y);
    }
} else
if(TYPEOF(xindex)==INTSXP) {
  if(INTEGER(xindex)[length(xindex)-1] < INTEGER(yindex)[0]) {
    UNPROTECT(P);
    return rbind_append(x,y);
    }
}
#endif

  PROTECT(newindex = allocVector(TYPEOF(xindex), len)); P++;
  PROTECT(result   = allocVector(TYPEOF(x), len * ncx)); P++;

  copyMostAttrib(xindex, newindex);

  switch( TYPEOF(x) ) {
    case INTSXP:
        int_x = INTEGER(x);
        int_y = INTEGER(y);
        int_result = INTEGER(result);
        break;
    case REALSXP:
        real_x = REAL(x);
        real_y = REAL(y);
        real_result = REAL(result);
        break;
    default:
        break;
  }

/* 
  if( TYPEOF(xindex) == REALSXP ) {
    if(REAL(xindex)[nrx-1] < REAL(yindex)[0]) {
      memcpy(REAL(newindex), REAL(xindex), sizeof(double) * nrx);
      memcpy(REAL(newindex)+nrx, REAL(yindex), sizeof(double) * nry);
      switch(TYPEOF(x)) {
        case INTSXP:
          memcpy(INTEGER(result), INTEGER(x), sizeof(int) * (nrx*ncx));
          memcpy(INTEGER(result)+(nrx*ncx), INTEGER(y), sizeof(int) * (nry*ncy));
          break;
        case REALSXP:
          memcpy(REAL(result), REAL(x), sizeof(double) * (nrx*ncx));
          memcpy(REAL(result)+(nrx*ncx), REAL(y), sizeof(double) * (nry*ncy));
          break;
        default:
          break;
      }
UNPROTECT(P);
return(result);
    }
  } else {

  }
*/
  /*
  The main body of code to follow branches based on the type
  of index, removing the need to test at each position.
  */
  if( TYPEOF(xindex) == REALSXP ) {
  real_newindex = REAL(newindex);
  real_xindex = REAL(xindex);
  real_yindex = REAL(yindex);
  for( i = 0; i < len; i++ ) {
    if( i >= truelen ) {
      break;
    } else 
    if( xp > nrx ) { 
      real_newindex[ i ] = real_yindex[ yp-1 ];
      for(j = 0; j < ncx; j++) {
        ij = i + j * len;
        ij_y = (yp-1) + j * nry;
        switch( mode ) {
          case LGLSXP:
            LOGICAL(result)[ ij ] = LOGICAL(y)[ ij_y ];
            break;
          case INTSXP:
            int_result[ ij ] = int_y[ ij_y ];
            break;
          case REALSXP:
            real_result[ ij ] = real_y[ ij_y ];
            break;
          case CPLXSXP:
            COMPLEX(result)[ ij ] = COMPLEX(y)[ ij_y ];
            break;
          case STRSXP:
            SET_STRING_ELT(result, ij, STRING_ELT(y, ij_y));
            break;
          default:
            break;
        }
      }
      yp++;
    } else
    if( yp > nry ) {
      real_newindex[ i ] = real_xindex[ xp-1 ];
      for(j = 0; j < ncx; j++) {
        ij = i + j * len;
        ij_x = (xp-1) + j * nrx;
        switch( mode ) {
          case LGLSXP:
            LOGICAL(result)[ ij ] = LOGICAL(x)[ ij_x ];
            break;
          case INTSXP:
            int_result[ ij ] = int_x[ ij_x ];
            break;
          case REALSXP:
            real_result[ ij ] = real_x[ ij_x ];
            break;
          case CPLXSXP:
            COMPLEX(result)[ ij ] = COMPLEX(x)[ ij_x ];
            break;
          case STRSXP:
            SET_STRING_ELT(result, ij, STRING_ELT(x, ij_x));
            break;
          default:
            break;
        }
      }
      xp++;
    } else
    if( real_xindex[ xp-1 ] == real_yindex[ yp-1 ] ) {
      if( real_xindex[ xp-1 ] < real_xindex[ xp   ] )
        add_y = 1;  /* add y values only if next xindex is new */
      if(no_duplicate) {
        add_y = 0;
        truelen--;
      }
      real_newindex[ i ] = real_xindex[ xp-1 ];
      if(add_y) real_newindex[ i+ 1 ] = real_yindex[ yp-1 ];
      for(j = 0; j < ncx; j++) {
      ij = i + j * len;
      ij_x = (xp-1) + j * nrx;
      ij_y = (yp-1) + j * nry;


      switch( mode ) {
        case LGLSXP:
          LOGICAL(result)[ ij ] = LOGICAL(x)[ ij_x ];
          if(add_y) LOGICAL(result)[ ij+1 ] = LOGICAL(y)[ ij_y ];
          break;
        case INTSXP:
          int_result[ ij ] = int_x[ ij_x ];
          if(add_y) int_result[ ij+1 ] = int_y[ ij_y ];
          break;
        case REALSXP:
          real_result[ ij ] = real_x[ ij_x ];
          if(add_y) real_result[ ij+1 ] = real_y[ ij_y ];
          break;
        case CPLXSXP:
          COMPLEX(result)[ ij ] = COMPLEX(x)[ ij_x ];
          if(add_y) COMPLEX(result)[ ij+1 ] = COMPLEX(y)[ ij_y ];
          break;
        case STRSXP:
          SET_STRING_ELT(result, ij, STRING_ELT(x, ij_x));
          if(add_y) SET_STRING_ELT(result, ij+1, STRING_ELT(y, ij_y));
          break;
        default:
          break;
      }
      }
      xp++;
      if(no_duplicate || add_y) { 
        yp++;
        if(!no_duplicate) i++;  // need to increase i as we now have filled in 2 values
        add_y = 0;
      }
    } else
    if( real_xindex[ xp-1 ] < real_yindex[ yp-1 ] ) {
      real_newindex[ i ] = real_xindex[ xp-1 ];
      for(j = 0; j < ncx; j++) {
        ij = i + j * len;
        ij_x = (xp-1) + j * nrx;
        switch( mode ) {
          case LGLSXP:
            LOGICAL(result)[ ij ] = LOGICAL(x)[ ij_x ];
            break;
          case INTSXP:
            int_result[ ij ] = int_x[ ij_x ];
            break;
          case REALSXP:
            real_result[ ij ] = real_x[ ij_x ];
            break;
          case CPLXSXP:
            COMPLEX(result)[ ij ] = COMPLEX(x)[ ij_x ];
            break;
          case STRSXP:
            SET_STRING_ELT(result, ij, STRING_ELT(x, ij_x));
            break;
          default:
            break;
        }
      }
      xp++;
    } else
    if( real_xindex[ xp-1 ] > real_yindex[ yp-1 ] ) {
      real_newindex[ i ] = real_yindex[ yp-1 ];
      for(j = 0; j < ncx; j++) {
        ij = i + j * len;
        ij_y = (yp-1) + j * nry;
        switch( mode ) {
          case LGLSXP:
            LOGICAL(result)[ ij ] = LOGICAL(y)[ ij_y ];
            break;
          case INTSXP:
            int_result[ ij ] = int_y[ ij_y ];
            break;
          case REALSXP:
            real_result[ ij ] = real_y[ ij_y ];
            break;
          case CPLXSXP:
            COMPLEX(result)[ ij ] = COMPLEX(y)[ ij_y ];
            break;
          case STRSXP:
            SET_STRING_ELT(result, ij, STRING_ELT(y, ij_y));
            break;
          default:
            break;
        }
      }
      yp++;
    }
  }
  } else 
  if( TYPEOF(xindex) == INTSXP ) {
  int_newindex = INTEGER(newindex);
  int_xindex = INTEGER(xindex);
  int_yindex = INTEGER(yindex);
  for(i = 0; i < len; i++) {
    /*Rprintf("xp:%i, yp:%i, i:%i\n",xp,yp,i);*/
    if( i >= truelen ) {
      break;
    } else 
    if( xp > nrx ) { 
      int_newindex[ i ] = int_yindex[ yp-1 ];
      for(j = 0; j < ncx; j++) {
        ij = i + j * len;
        ij_y = (yp-1) + j * nry;
        switch( mode ) {
          case LGLSXP:
            LOGICAL(result)[ ij ] = LOGICAL(y)[ ij_y ];
            break;
          case INTSXP:
            int_result[ ij ] = int_y[ ij_y ];
            break;
          case REALSXP:
            real_result[ ij ] = real_y[ ij_y ];
            break;
          case CPLXSXP:
            COMPLEX(result)[ ij ] = COMPLEX(y)[ ij_y ];
            break;
          case STRSXP:
            SET_STRING_ELT(result, ij, STRING_ELT(y, ij_y));
            break;
          default:
            break;
        }
      }
      yp++;
      
    } else
    if( yp > nry ) {
      int_newindex[ i ] = int_xindex[ xp-1 ];
      for(j = 0; j < ncx; j++) {
      ij = i + j * len;
      ij_x = (xp-1) + j * nrx;
      switch( mode ) {
        case LGLSXP:
          LOGICAL(result)[ ij ] = LOGICAL(x)[ ij_x ];
          break;
        case INTSXP:
          int_result[ ij ] = int_x[ ij_x ];
          break;
        case REALSXP:
          real_result[ ij ] = real_x[ ij_x ];
          break;
        case CPLXSXP:
          COMPLEX(result)[ ij ] = COMPLEX(x)[ ij_x ];
          break;
        case STRSXP:
          SET_STRING_ELT(result, ij, STRING_ELT(x, ij_x));
          break;
        default:
          break;
      }
      }
      xp++;
    } else
    if( int_xindex[ xp-1 ] == int_yindex[ yp-1 ] ) {
      if( int_xindex[ xp-1 ] < int_xindex[ xp  ] )
        add_y = 1;
      if(no_duplicate) {
        add_y = 0;
        truelen--;
      }
      int_newindex[ i ] = int_xindex[ xp-1 ];
      if(add_y) int_newindex[ i+1 ] = int_yindex[ yp-1 ];
      for(j = 0; j < ncx; j++) {
      ij = i + j * len;
      ij_x = (xp-1) + j * nrx;
      ij_y = (yp-1) + j * nry;
      switch( mode ) {
        case LGLSXP:
          LOGICAL(result)[ ij ]     = LOGICAL(x)[ ij_x ];
          if(add_y) LOGICAL(result)[ ij+1 ]   = LOGICAL(y)[ ij_y ];
          break;
        case INTSXP:
          int_result[ ij ] = int_x[ ij_x ];
          if(add_y) int_result[ ij+1 ] = int_y[ ij_y ];
          break;
        case REALSXP:
          real_result[ ij ] = real_x[ ij_x ];
          if(add_y) real_result[ ij+1 ] = real_y[ ij_y ];
          break;
        case CPLXSXP:
          COMPLEX(result)[ ij ]     = COMPLEX(x)[ ij_x ];
          if(add_y) COMPLEX(result)[ ij+1 ]   = COMPLEX(y)[ ij_y ];
          break;
        case STRSXP:
          SET_STRING_ELT(result, ij, STRING_ELT(x, ij_x));
          if(add_y) SET_STRING_ELT(result, ij+1, STRING_ELT(y, ij_y));
          break;
        default:
          break;
      }
      }
      xp++;
      if(no_duplicate || add_y) {
        yp++;
        if(!no_duplicate) i++;  // need to increase i as we now have filled in 2 values
        add_y = 0;
      }
    } else
    if( int_xindex[ xp-1 ] < int_yindex[ yp-1 ] ) {
      int_newindex[ i ] = int_xindex[ xp-1 ];
      for(j = 0; j < ncx; j++) {
      ij = i + j * len;
      ij_x = (xp-1) + j * nrx;
      switch( mode ) {
        case LGLSXP:
          LOGICAL(result)[ ij ] = LOGICAL(x)[ ij_x ];
          break;
        case INTSXP:
          int_result[ ij ] = int_x[ ij_x ];
          break;
        case REALSXP:
          real_result[ ij ] = real_x[ ij_x ];
          break;
        case CPLXSXP:
          COMPLEX(result)[ ij ] = COMPLEX(x)[ ij_x ];
          break;
        case STRSXP:
          SET_STRING_ELT(result, ij, STRING_ELT(x, ij_x));
          break;
        default:
          break;
      }
      }
      xp++;
    } else
    if( int_xindex[ xp-1 ] > int_yindex[ yp-1 ] ) {
      int_newindex[ i ] = int_yindex[ yp-1 ];
      for(j = 0; j < ncx; j++) {
      ij = i + j * len;
      ij_y = (yp-1) + j * nry;
      switch( mode ) {
        case LGLSXP:
          LOGICAL(result)[ ij ] = LOGICAL(y)[ ij_y ];
          break;
        case INTSXP:
          int_result[ ij ] = int_y[ ij_y ];
          break;
        case REALSXP:
          real_result[ ij ] = real_y[ ij_y ];
          break;
        case CPLXSXP:
          COMPLEX(result)[ ij ] = COMPLEX(y)[ ij_y ];
          break;
        case STRSXP:
          SET_STRING_ELT(result, ij, STRING_ELT(y, ij_y));
          break;
        default:
          break;
      }
      }
      yp++;
    }}
  }

  if(truelen != len) {
    PROTECT(result = lengthgets(result, truelen * ncx)); P++;  /* reset length */
  }
  setAttrib(result, R_ClassSymbol, getAttrib(x, R_ClassSymbol));
  SEXP dim;
  PROTECT(dim = allocVector(INTSXP, 2));
  INTEGER(dim)[0] = truelen;
  INTEGER(dim)[1] = INTEGER(getAttrib(x, R_DimSymbol))[1];
  UNPROTECT(1);
  setAttrib(result, R_DimSymbol, dim);
  setAttrib(result, R_DimNamesSymbol, getAttrib(x, R_DimNamesSymbol));
  
  if(truelen != len) {
    PROTECT(newindex = lengthgets(newindex, truelen)); P++;
  }
  setAttrib(result, xts_IndexSymbol, newindex);
  setAttrib(result, xts_IndexClassSymbol, getAttrib(x, xts_IndexClassSymbol));
  setAttrib(result, xts_IndexTZSymbol, getAttrib(x, xts_IndexTZSymbol));
  setAttrib(result, xts_IndexFormatSymbol, getAttrib(x, xts_IndexFormatSymbol));
  setAttrib(result, xts_ClassSymbol, getAttrib(x, xts_ClassSymbol));
  copy_xtsAttributes(x, result);
  UNPROTECT(P);
  return result;
} //}}}
示例#10
0
SEXP fmelt(SEXP DT, SEXP id, SEXP measure, SEXP varfactor, SEXP valfactor, SEXP var_name, SEXP val_name, SEXP na_rm, SEXP drop_levels, SEXP print_out) {
    
    int i, j, k, nrow, ncol, protecti=0, lids=-1, lvalues=-1, totlen=0, counter=0, thislen=0;
    SEXP thiscol, ans, dtnames, ansnames, idcols, valuecols, levels, factorLangSxp;
    SEXP vars, target, idxkeep = R_NilValue, thisidx = R_NilValue;
    Rboolean isfactor=FALSE, isidentical=TRUE, narm = FALSE, droplevels=FALSE, verbose=FALSE;
    SEXPTYPE valtype=NILSXP;
    size_t size;

    if (TYPEOF(DT) != VECSXP) error("Input is not of type VECSXP, expected a data.table, data.frame or list");
    if (TYPEOF(valfactor) != LGLSXP) error("Argument 'value.factor' should be logical TRUE/FALSE");
    if (TYPEOF(varfactor) != LGLSXP) error("Argument 'variable.factor' should be logical TRUE/FALSE");
    if (TYPEOF(na_rm) != LGLSXP) error("Argument 'na.rm' should be logical TRUE/FALSE");
    if (LOGICAL(na_rm)[0] == TRUE) narm = TRUE;
    if (TYPEOF(print_out) != LGLSXP) error("Argument 'verbose' should be logical TRUE/FALSE");
    if (LOGICAL(print_out)[0] == TRUE) verbose = TRUE;
    // check for var and val names
    if (TYPEOF(var_name) != STRSXP || length(var_name) != 1) error("Argument 'variable.name' must be a character vector of length 1");
    if (TYPEOF(val_name) != STRSXP || length(val_name) != 1) error("Argument 'value.name' must be a character vector of length 1");

    // droplevels future feature request, maybe... should ask on data.table-help
    // if (!isLogical(drop_levels)) error("Argument 'drop.levels' should be logical TRUE/FALSE");
    // if (LOGICAL(drop_levels)[0] == TRUE) droplevels = TRUE;
    // if (droplevels && !narm) warning("Ignoring argument 'drop.levels'. 'drop.levels' should be set to remove any unused levels as a result of setting 'na.rm=TRUE'. Here there is nothing to do because 'na.rm=FALSE'");
    
    ncol = LENGTH(DT);
    nrow = length(VECTOR_ELT(DT, 0));
    if (ncol <= 0) {
        warning("ncol(data) is 0. Nothing to do, returning original data.table.");
        return(DT);
    }
    PROTECT(dtnames = getAttrib(DT, R_NamesSymbol)); protecti++;
    if (isNull(dtnames)) error("names(data) is NULL. Please report to data.table-help");
    
    vars = checkVars(DT, id, measure, verbose);
    PROTECT(idcols = VECTOR_ELT(vars, 0)); protecti++;
    PROTECT(valuecols = VECTOR_ELT(vars, 1)); protecti++; // <~~~ not protecting vars leads to  segfault (on big data)
    
    lids = length(idcols);
    lvalues = length(valuecols);
    
    // edgecase where lvalues = 0 and lids > 0
    if (lvalues == 0 && lids > 0) {
        if (verbose) Rprintf("length(measure.var) is 0. Edge case detected. Nothing to melt. Returning data.table with all 'id.vars' which are columns %s\n", CHAR(STRING_ELT(concat(dtnames, idcols), 0)));
        PROTECT(ansnames = allocVector(STRSXP, lids)); protecti++;
        PROTECT(ans = allocVector(VECSXP, lids)); protecti++;
        for (i=0; i<lids; i++) {
            SET_VECTOR_ELT(ans, i, VECTOR_ELT(DT, INTEGER(idcols)[i]-1));
            SET_STRING_ELT(ansnames, i, STRING_ELT(dtnames, INTEGER(idcols)[i]-1));
        }
        setAttrib(ans, R_NamesSymbol, ansnames);
        UNPROTECT(protecti);
        return(ans);
    }
    if (lvalues == 0 && lids == 0 && verbose)
        Rprintf("length(measure.var) and length(id.var) are both 0. Edge case detected. Nothing to melt.\n"); // <~~ don't think this will ever happen though with all the checks
    // set names for 'ans' - the output list
    PROTECT(ansnames = allocVector(STRSXP, lids+2)); protecti++;
    for (i=0; i<lids; i++) {
        SET_STRING_ELT(ansnames, i, STRING_ELT(dtnames, INTEGER(idcols)[i]-1));
    }
    SET_STRING_ELT(ansnames, lids, mkChar(CHAR(STRING_ELT(var_name, 0)))); // mkChar("variable")
    SET_STRING_ELT(ansnames, lids+1, mkChar(CHAR(STRING_ELT(val_name, 0)))); // mkChar("value")
    
    // get "value" column
    for (i=0; i<lvalues; i++) {
        thiscol = VECTOR_ELT(DT, INTEGER(valuecols)[i]-1);
        if (!isfactor && isFactor(thiscol)) isfactor = TRUE;
        if (TYPEOF(thiscol) > valtype) valtype = TYPEOF(thiscol);
    }
    if (isfactor && valtype != VECSXP) valtype = STRSXP;

    for (i=0; i<lvalues; i++) {
        thiscol = VECTOR_ELT(DT, INTEGER(valuecols)[i]-1);
        if (TYPEOF(thiscol) != valtype && isidentical) {
            if (!(isFactor(thiscol) && valtype == STRSXP)) {
                isidentical = FALSE; // for Date like column (not implemented for now)
                warning("All 'measure.vars are NOT of the SAME type. By order of hierarchy, the molten data value column will be of type '%s'. Therefore all measure variables that are not of type '%s' will be coerced to. Check the DETAILS section of ?melt.data.table for more on coercion.\n", type2char(valtype), type2char(valtype));
                break;
            }
        }
    }

    if (valtype == VECSXP && narm) {
        narm = FALSE;
        if (verbose) Rprintf("The molten data value type is a list. 'na.rm=TRUE' is therefore ignored.\n");
    }
    if (narm) {
        PROTECT(idxkeep = allocVector(VECSXP, lvalues)); protecti++;
        for (i=0; i<lvalues; i++) {
            SET_VECTOR_ELT(idxkeep, i, which_notNA(VECTOR_ELT(DT, INTEGER(valuecols)[i]-1)));
            totlen += length(VECTOR_ELT(idxkeep, i));
        }
    } else 
        totlen = nrow * lvalues;
    
    PROTECT(ans = allocVector(VECSXP, lids + 2)); protecti++;
    target = PROTECT(allocVector(valtype, totlen));
    for (i=0; i<lvalues; i++) {
        thiscol = VECTOR_ELT(DT, INTEGER(valuecols)[i]-1);
        if (isFactor(thiscol))
            thiscol = asCharacterFactor(thiscol);
        if (TYPEOF(thiscol) != valtype && !isFactor(thiscol)) {
            // thiscol = valtype == STRSXP ? PROTECT(coerce_to_char(thiscol, R_GlobalEnv)) : PROTECT(coerceVector(thiscol, valtype));
            // protecti++; // for now, no preserving of class attributes
            thiscol = PROTECT(coerceVector(thiscol, valtype)); protecti++;
        }
        size = SIZEOF(thiscol);
        if (narm) {
            thisidx = VECTOR_ELT(idxkeep, i);
            thislen = length(thisidx);
        }
        switch(valtype) {
            case VECSXP :
            if (narm) {
                for (j=0; j<thislen; j++)
                    SET_VECTOR_ELT(target, counter + j, VECTOR_ELT(thiscol, INTEGER(thisidx)[j]-1));
            } else {
                for (j=0; j<nrow; j++) SET_VECTOR_ELT(target, i*nrow + j, VECTOR_ELT(thiscol, j));
            }
            break;
            case STRSXP :
            if (narm) {
                for (j=0; j<thislen; j++)
                    SET_STRING_ELT(target, counter + j, STRING_ELT(thiscol, INTEGER(thisidx)[j]-1));
            } else {
                for (j=0; j<nrow; j++) SET_STRING_ELT(target, i*nrow + j, STRING_ELT(thiscol, j));
            }
            break;
            case REALSXP : 
            if (narm) {
                for (j=0; j<thislen; j++)
                    REAL(target)[counter + j] = REAL(thiscol)[INTEGER(thisidx)[j]-1];
            } else {
                memcpy((char *)DATAPTR(target)+i*nrow*size, (char *)DATAPTR(thiscol), nrow*size);
            }
            break;
            case INTSXP : 
            if (narm) {
                for (j=0; j<thislen; j++)
                    INTEGER(target)[counter + j] = INTEGER(thiscol)[INTEGER(thisidx)[j]-1];
            } else {
                memcpy((char *)DATAPTR(target)+i*nrow*size, (char *)DATAPTR(thiscol), nrow*size);
            }
            break;
            case LGLSXP :
            if (narm) {
                for (j=0; j<thislen; j++)
                    LOGICAL(target)[counter + j] = LOGICAL(thiscol)[INTEGER(thisidx)[j]-1];
            } else {
                memcpy((char *)DATAPTR(target)+i*nrow*size, (char *)DATAPTR(thiscol), nrow*size);
            }
            break;
            default : error("Unknown column type '%s' for column '%s' in 'data'", type2char(TYPEOF(thiscol)), CHAR(STRING_ELT(dtnames, INTEGER(valuecols)[i]-1)));
        }
        if (narm) counter += thislen;
        // if (isidentical && valtype != VECSXP) // for now, no preserving of class attributes
        //     setAttrib(target, R_ClassSymbol, getAttrib(VECTOR_ELT(DT, INTEGER(valuecols)[0]-1), R_ClassSymbol)); // for Date like column
    }
    // check for factor
    if (LOGICAL(valfactor)[0] == TRUE && valtype == VECSXP) warning("argument 'value.factor' ignored because 'value' column is a list\n");
    if (LOGICAL(valfactor)[0] == TRUE && valtype != VECSXP) {
        PROTECT(factorLangSxp = allocList(2));
        SET_TYPEOF(factorLangSxp, LANGSXP);
        SETCAR(factorLangSxp, install("factor"));
        SETCAR(CDR(factorLangSxp), target);
        SET_VECTOR_ELT(ans, lids+1, eval(factorLangSxp, R_GlobalEnv)); // last column
        UNPROTECT(1); // factorLangSxp
    } else 
        SET_VECTOR_ELT(ans, lids+1, target);    
    UNPROTECT(1); // target
    
    // get "variable" column
    counter = 0, i=0;
    target = PROTECT(allocVector(INTSXP, totlen));
     for (j=0; j<lvalues; j++) {
        if (narm) {
            thislen = length(VECTOR_ELT(idxkeep, j));
            for (k=0; k<thislen; k++)
                INTEGER(target)[counter + k] = i+1;
            counter += thislen;
            if (thislen > 0 || !droplevels) i++;
        } else {
            for (k=0; k<nrow; k++)
                INTEGER(target)[nrow*j + k] = j+1;
        }
    }
    setAttrib(target, R_ClassSymbol, mkString("factor"));
    if (narm && droplevels) {
        counter = 0;
        for (j=0; j<lvalues; j++) {
            if (length(VECTOR_ELT(idxkeep, j)) > 0) counter++;
        }
    } else counter = lvalues;
    levels = PROTECT(allocVector(STRSXP, counter));
    i = 0;
    for (j=0; j<lvalues; j++) {
        if (narm && droplevels) {
            if (length(VECTOR_ELT(idxkeep, j)) > 0)
                SET_STRING_ELT(levels, i++, STRING_ELT(dtnames, INTEGER(valuecols)[j]-1));
        } else 
            SET_STRING_ELT(levels, j, STRING_ELT(dtnames, INTEGER(valuecols)[j]-1));
    }
    setAttrib(target, R_LevelsSymbol, levels);
    UNPROTECT(1); // levels
    if (LOGICAL(varfactor)[0] == FALSE)
        target = asCharacterFactor(target);
    SET_VECTOR_ELT(ans, lids, target);
    UNPROTECT(1); // target
    
    // generate idcols (left part)
    for (i=0; i<lids; i++) {
        counter = 0;
        thiscol = VECTOR_ELT(DT, INTEGER(idcols)[i]-1);
        size = SIZEOF(thiscol);
        target = PROTECT(allocVector(TYPEOF(thiscol), totlen)); 
        switch(TYPEOF(thiscol)) {
            case REALSXP :
            if (narm) {
                for (j=0; j<lvalues; j++) {
                    thisidx = PROTECT(VECTOR_ELT(idxkeep, j));
                    thislen = length(thisidx);
                    for (k=0; k<thislen; k++)
                        REAL(target)[counter + k] = REAL(thiscol)[INTEGER(thisidx)[k]-1];
                    counter += thislen;
                    UNPROTECT(1); // thisidx
                } 
            } else { 
                for (j=0; j<lvalues; j++)
                    memcpy((char *)DATAPTR(target)+j*nrow*size, (char *)DATAPTR(thiscol), nrow*size);
            }
            break;
            case INTSXP :
            if (narm) {
                for (j=0; j<lvalues; j++) {
                    thisidx = PROTECT(VECTOR_ELT(idxkeep, j));
                    thislen = length(thisidx);
                    for (k=0; k<thislen; k++)
                        INTEGER(target)[counter + k] = INTEGER(thiscol)[INTEGER(thisidx)[k]-1];
                    counter += thislen;
                    UNPROTECT(1); // thisidx
                } 
            } else {
                for (j=0; j<lvalues; j++)
                    memcpy((char *)DATAPTR(target)+j*nrow*size, (char *)DATAPTR(thiscol), nrow*size);
            }
            break;
            case LGLSXP :
            if (narm) {
                for (j=0; j<lvalues; j++) {
                    thisidx = PROTECT(VECTOR_ELT(idxkeep, j));
                    thislen = length(thisidx);
                    for (k=0; k<thislen; k++)
                        LOGICAL(target)[counter + k] = LOGICAL(thiscol)[INTEGER(thisidx)[k]-1];
                    counter += thislen;
                    UNPROTECT(1); // thisidx
                } 
            } else {
                for (j=0; j<lvalues; j++)
                    memcpy((char *)DATAPTR(target)+j*nrow*size, (char *)DATAPTR(thiscol), nrow*size);
            }
            break;
            case STRSXP :
            if (narm) {
                for (j=0; j<lvalues; j++) {
                    thisidx = PROTECT(VECTOR_ELT(idxkeep, j));
                    thislen = length(thisidx);
                    for (k=0; k<thislen; k++)
                        SET_STRING_ELT(target, counter + k, STRING_ELT(thiscol, INTEGER(thisidx)[k]-1));
                    counter += thislen;
                    UNPROTECT(1); // thisidx
                } 
            } else {
                // SET_STRING_ELT for j=0 and memcpy for j>0, WHY?
                // From assign.c's memcrecycle - only one SET_STRING_ELT per RHS item is needed to set generations (overhead)
                for (k=0; k<nrow; k++) SET_STRING_ELT(target, k, STRING_ELT(thiscol, k));
                for (j=1; j<lvalues; j++)
                    memcpy((char *)DATAPTR(target)+j*nrow*size, (char *)DATAPTR(target), nrow*size);
            }
            break;
            case VECSXP :
            for (j=0; j<lvalues; j++) {
                for (k=0; k<nrow; k++) {
                    SET_VECTOR_ELT(target, j*nrow + k, VECTOR_ELT(thiscol, k));
                }
            }
            break;
            default : error("Unknown column type '%s' for column '%s' in 'data'", type2char(TYPEOF(thiscol)), CHAR(STRING_ELT(dtnames, INTEGER(idcols)[i]-1)));
        }
        copyMostAttrib(thiscol, target); // all but names,dim and dimnames. And if so, we want a copy here, not keepattr's SET_ATTRIB.
        SET_VECTOR_ELT(ans, i, target);
        UNPROTECT(1); // target
    }
                
    setAttrib(ans, R_NamesSymbol, ansnames);
    UNPROTECT(protecti);
    return(ans);
}
示例#11
0
// TO DO: margins
SEXP fcast(SEXP lhs, SEXP val, SEXP nrowArg, SEXP ncolArg, SEXP idxArg, SEXP fill, SEXP fill_d, SEXP is_agg) {

    int nrows=INTEGER(nrowArg)[0], ncols=INTEGER(ncolArg)[0];
    int i,j,k, nlhs=length(lhs), nval=length(val), *idx = INTEGER(idxArg), thisidx;;
    SEXP thiscol, target, ans, thisfill;
    Rboolean isfill = TRUE, count;

    ans = PROTECT(allocVector(VECSXP, nlhs + (nval * ncols)));
    // set lhs cols
    for (i=0; i < nlhs; i++) {
        SET_VECTOR_ELT(ans, i, VECTOR_ELT(lhs, i));
    }
    // get val cols
    for (i=0; i<nval; i++) {
        thiscol = VECTOR_ELT(val, i);
        thisfill = fill;
        count = FALSE;
        if (isNull(fill)) {
            isfill = FALSE;
            if (LOGICAL(is_agg)[0]) {
                thisfill = PROTECT(allocNAVector(TYPEOF(thiscol), 1));
                count = TRUE;
            } else thisfill = VECTOR_ELT(fill_d, i);
        }
        if (isfill && TYPEOF(fill) != TYPEOF(thiscol)) {
            thisfill = PROTECT(coerceVector(fill, TYPEOF(thiscol)));
            count = TRUE;
        }
        switch (TYPEOF(thiscol)) {
            case INTSXP:
                for (j=0; j<ncols; j++) {
                    target = allocVector(TYPEOF(thiscol), nrows);
                    SET_VECTOR_ELT(ans, nlhs+j+i*ncols, target);
                    copyMostAttrib(thiscol, target);
                    for (k=0; k<nrows; k++) {
                        thisidx = idx[k*ncols + j];
                        INTEGER(target)[k] = (thisidx == NA_INTEGER) ? INTEGER(thisfill)[0] : INTEGER(thiscol)[thisidx-1];
                    }
                }
            break;
            case REALSXP:
                for (j=0; j<ncols; j++) {
                    target = allocVector(TYPEOF(thiscol), nrows);
                    SET_VECTOR_ELT(ans, nlhs+j+i*ncols, target);
                    copyMostAttrib(thiscol, target);
                    for (k=0; k<nrows; k++) {
                        thisidx = idx[k*ncols + j];
                        REAL(target)[k] = (thisidx == NA_INTEGER) ? REAL(thisfill)[0] : REAL(thiscol)[thisidx-1];
                    }
                }
            break;
            case LGLSXP:
                for (j=0; j<ncols; j++) {
                    target = allocVector(TYPEOF(thiscol), nrows);
                    SET_VECTOR_ELT(ans, nlhs+j+i*ncols, target);
                    copyMostAttrib(thiscol, target);
                    for (k=0; k<nrows; k++) {
                        thisidx = idx[k*ncols + j];
                        LOGICAL(target)[k] = (thisidx == NA_INTEGER) ? LOGICAL(thisfill)[0] : LOGICAL(thiscol)[thisidx-1];
                    }
                }
            break;
            case STRSXP:
                for (j=0; j<ncols; j++) {
                    target = allocVector(TYPEOF(thiscol), nrows);
                    SET_VECTOR_ELT(ans, nlhs+j+i*ncols, target);
                    copyMostAttrib(thiscol, target);
                    for (k=0; k<nrows; k++) {
                        thisidx = idx[k*ncols + j];
                        SET_STRING_ELT(target, k, (thisidx == NA_INTEGER) ? STRING_ELT(thisfill, 0) : STRING_ELT(thiscol, thisidx-1));
                    }
                }
            break;
            case VECSXP:
                for (j=0; j<ncols; j++) {
                    target = allocVector(TYPEOF(thiscol), nrows);
                    SET_VECTOR_ELT(ans, nlhs+j+i*ncols, target);
                    copyMostAttrib(thiscol, target);
                    for (k=0; k<nrows; k++) {
                        thisidx = idx[k*ncols + j];
                        SET_VECTOR_ELT(target, k, (thisidx == NA_INTEGER) ? VECTOR_ELT(thisfill, 0) : VECTOR_ELT(thiscol, thisidx-1));
                    }
                }
            break;
        }
        if (count) UNPROTECT(1);
    }
    UNPROTECT(1);
    return(ans);
}
示例#12
0
SEXP extract_col (SEXP x, SEXP j, SEXP drop, SEXP first_, SEXP last_) {
  SEXP result, index, new_index;
  int nrs, nrsx, i, ii, jj, first, last;

  nrsx = nrows(x);

  first = asInteger(first_)-1;
  last = asInteger(last_)-1;

  /* nrs = offset_end - offset_start - 1; */
  nrs = last - first + 1;
  

  PROTECT(result = allocVector(TYPEOF(x), nrs * length(j)));

  switch(TYPEOF(x)) {
    case REALSXP:
      for(i=0; i<length(j); i++) {
/*
Rprintf("j + i*nrs + first=%i\n", (int)(INTEGER(j)[i]-1 + i*nrs + first));
Rprintf("i=%i, j=%i, nrs=%i, first=%i\n", i, INTEGER(j)[i]-1, nrs, first);
*/
        if(INTEGER(j)[i] == NA_INTEGER) {
          for(ii=0; ii < nrs; ii++) {
            REAL(result)[(i*nrs) + ii] = NA_REAL;
          }
        } else {
          memcpy(&(REAL(result)[i*nrs]),
                 &(REAL(x)[(INTEGER(j)[i]-1)*nrsx + first]),
                 nrs*sizeof(double));
        }
      }
      break;
    case INTSXP:
      for(i=0; i<length(j); i++) {
        if(INTEGER(j)[i] == NA_INTEGER) {
          for(ii=0; ii < nrs; ii++) {
            INTEGER(result)[(i*nrs) + ii] = NA_INTEGER;
          }
        } else {
          memcpy(&(INTEGER(result)[i*nrs]),
                 &(INTEGER(x)[(INTEGER(j)[i]-1)*nrsx + first]),
                 nrs*sizeof(int));
        }
      }
      break;
    case LGLSXP:
      for(i=0; i<length(j); i++) {
        if(INTEGER(j)[i] == NA_INTEGER) {
          for(ii=0; ii < nrs; ii++) {
            LOGICAL(result)[(i*nrs) + ii] = NA_LOGICAL;
          }
        } else {
          memcpy(&(LOGICAL(result)[i*nrs]),
                 &(LOGICAL(x)[(INTEGER(j)[i]-1)*nrsx + first]),
                 nrs*sizeof(int));
        }
      }
      break;
    case CPLXSXP:
      for(i=0; i<length(j); i++) {
        if(INTEGER(j)[i] == NA_INTEGER) {
          for(ii=0; ii < nrs; ii++) {
            COMPLEX(result)[(i*nrs) + ii].r = NA_REAL;
            COMPLEX(result)[(i*nrs) + ii].i = NA_REAL;
          }
        } else {
          memcpy(&(COMPLEX(result)[i*nrs]),
                 &(COMPLEX(x)[(INTEGER(j)[i]-1)*nrsx + first]),
                 nrs*sizeof(Rcomplex));
        }
      }
      break;
    case RAWSXP:
      for(i=0; i<length(j); i++) {
        if(INTEGER(j)[i] == NA_INTEGER) {
          for(ii=0; ii < nrs; ii++) {
            RAW(result)[(i*nrs) + ii] = 0;
          }
        } else {
          memcpy(&(RAW(result)[i*nrs]),
                 &(RAW(x)[(INTEGER(j)[i]-1)*nrsx + first]),
                 nrs*sizeof(Rbyte));
        }
      }
      break;
    case STRSXP:
      for(jj=0; jj<length(j); jj++) {
        if(INTEGER(j)[jj] == NA_INTEGER) {
          for(i=0; i< nrs; i++)
            SET_STRING_ELT(result, i+jj*nrs, NA_STRING);
        } else {
          for(i=0; i< nrs; i++)
            SET_STRING_ELT(result, i+jj*nrs, STRING_ELT(x, i+(INTEGER(j)[jj]-1)*nrsx+first));
        }
      }
      break;
    default:
      error("unsupported type");
  }

  if(nrs != nrows(x)) {
    copyAttributes(x, result);
    /* subset index */
    index = getAttrib(x, install("index"));
    PROTECT(new_index = allocVector(TYPEOF(index), nrs)); 
    if(TYPEOF(index) == REALSXP) {
      memcpy(REAL(new_index), &(REAL(index)[first]), nrs*sizeof(double)); 
    } else { /* INTSXP */
      memcpy(INTEGER(new_index), &(INTEGER(index)[first]), nrs*sizeof(int)); 
    }
    copyMostAttrib(index, new_index);
    setAttrib(result, install("index"), new_index);
    UNPROTECT(1);
  } else {
    copyMostAttrib(x, result); /* need an xts/zoo equal that skips 'index' */
  }

  if(!asLogical(drop)) { /* keep dimension and dimnames */
    SEXP dim;
    PROTECT(dim = allocVector(INTSXP, 2));
    INTEGER(dim)[0] = nrs;
    INTEGER(dim)[1] = length(j);
    setAttrib(result, R_DimSymbol, dim);
    UNPROTECT(1);

    SEXP dimnames, currentnames, newnames;
    PROTECT(dimnames = allocVector(VECSXP, 2));
    PROTECT(newnames = allocVector(STRSXP, length(j)));
    currentnames = getAttrib(x, R_DimNamesSymbol);

    if(!isNull(currentnames)) {
      SET_VECTOR_ELT(dimnames, 0, VECTOR_ELT(currentnames,0));
      if(!isNull(VECTOR_ELT(currentnames,1))) {
        /* if colnames isn't NULL set */
        for(i=0; i<length(j); i++) {
          SET_STRING_ELT(newnames, i, STRING_ELT(VECTOR_ELT(currentnames,1), INTEGER(j)[i]-1));
        }
        SET_VECTOR_ELT(dimnames, 1, newnames);
      } else {
        /* else set to NULL */
        SET_VECTOR_ELT(dimnames, 1, R_NilValue);
      }
      setAttrib(result, R_DimNamesSymbol, dimnames);
    }
    UNPROTECT(2);
  }

  UNPROTECT(1);
  return result;
}
示例#13
0
static SEXP subsetVectorRaw(SEXP x, SEXP idx, int l, int tl)
// Only for use by subsetDT() or subsetVector() below, hence static
// l is the count of non-zero (including NAs) in idx i.e. the length of the result
// tl is the amount to be allocated,  tl>=l
// TO DO: if no 0 or NA detected up front in subsetDT() below, could switch to a faster subsetVectorRawNo0orNA()
{
    int i, this, ansi=0, max=length(x), n=LENGTH(idx), *pidx=INTEGER(idx);
    if (tl<l) error("Internal error: tl<n passed to subsetVectorRaw");
    SEXP ans = PROTECT(allocVector(TYPEOF(x), tl));
    SETLENGTH(ans, l);
    SET_TRUELENGTH(ans, tl);
    // Rprintf("l=%d, tl=%d, LENGTH(idx)=%d\n", l, tl, LENGTH(idx));
#ifdef _OPENMP
    int *ctr = (int *)calloc(omp_get_max_threads()+1, sizeof(int));
#endif

    switch(TYPEOF(x)) {
    case INTSXP :
#ifdef _OPENMP
    #pragma omp parallel
    {
        int tmp=0, ithread = omp_get_thread_num(), nthreads = omp_get_num_threads();    // local
        // computing count indices correctly is tricky when there are 0-indices.
        // 1. count number of non-0 'idx' for each thread
        #pragma omp for
        for (i=0; i<n; i++) tmp += (pidx[i] != 0);  // don't use ctr[ithread+1] here -- false sharing
                            // TODO: use SIMD here?
        ctr[ithread+1] = tmp;                       // ctr[0]=0, rest contains count where iidx!=0,
                            // within each thread's range
        #pragma omp barrier                         // wait for all threads, important
        // 2. using that, set the starting index for each thread appropriately
        #pragma omp single
        for (i=0; i<nthreads; i++)
        ctr[i+1] += ctr[i];                     // for each thread, compute the right starting point, by
                            // taking (non)0-count into account, computed above.
        tmp = ctr[ithread];                         // copy back from shared to thread's local var. All set.
        #pragma omp barrier                         // wait for all threads, important
        // 3. use old code, but with thread's local var with right start index as counter
        #pragma omp for private(this) reduction(+:ansi)
        for (i=0; i<n; i++) {
        this = pidx[i];
        if (this==0) continue;
        // have to use 'tmp' here, and not ctr[ithread++] -- false sharing
        INTEGER(ans)[tmp++] = (this==NA_INTEGER || this>max) ? NA_INTEGER : INTEGER(x)[this-1];
        ansi++;                                 // not required, but just to be sure
        }
    }
#else
    for (i=0; i<n; i++) {
        this = pidx[i];
        if (this==0) continue;
        INTEGER(ans)[ansi++] = (this==NA_INTEGER || this>max) ? NA_INTEGER : INTEGER(x)[this-1];
    }
#endif
    break;
    case REALSXP :
#ifdef _OPENMP
    #pragma omp parallel
    {
        int tmp=0, ithread = omp_get_thread_num(), nthreads = omp_get_num_threads();
        #pragma omp for
        for (i=0; i<n; i++) tmp += (pidx[i] != 0);
        ctr[ithread+1] = tmp;
        #pragma omp barrier
        #pragma omp single
        for (i=0; i<nthreads; i++)
        ctr[i+1] += ctr[i];
        tmp = ctr[ithread];
        #pragma omp barrier
        #pragma omp for private(this) reduction(+:ansi)
        for (i=0; i<n; i++) {
        this = pidx[i];
        if (this==0) continue;
        REAL(ans)[tmp++] = (this==NA_INTEGER || this>max) ? NA_REAL : REAL(x)[this-1];
        ansi++;
        }
    }
#else
    for (i=0; i<n; i++) {
        this = pidx[i];
        if (this==0) continue;
        REAL(ans)[ansi++] = (this==NA_INTEGER || this>max) ? NA_REAL : REAL(x)[this-1];
    }
#endif
    break;
    case LGLSXP :
#ifdef _OPENMP
    #pragma omp parallel
    {
        int tmp=0, ithread = omp_get_thread_num(), nthreads = omp_get_num_threads();
        #pragma omp for
        for (i=0; i<n; i++) tmp += (pidx[i] != 0);
        ctr[ithread+1] = tmp;
        #pragma omp barrier
        #pragma omp single
        for (i=0; i<nthreads; i++)
        ctr[i+1] += ctr[i];
        tmp = ctr[ithread];
        #pragma omp barrier
        #pragma omp for private(this) reduction(+:ansi)
        for (i=0; i<n; i++) {
        this = pidx[i];
        if (this==0) continue;
        LOGICAL(ans)[tmp++] = (this==NA_INTEGER || this>max) ? NA_LOGICAL : LOGICAL(x)[this-1];
        ansi++;
        }
    }
#else
    for (i=0; i<n; i++) {
        this = pidx[i];
        if (this==0) continue;
        LOGICAL(ans)[ansi++] = (this==NA_INTEGER || this>max) ? NA_LOGICAL : LOGICAL(x)[this-1];
    }
#endif
    break;
    case STRSXP :
#ifdef _OPENMP
    #pragma omp parallel
    {
        int tmp=0, ithread = omp_get_thread_num(), nthreads = omp_get_num_threads();
        #pragma omp for
        for (i=0; i<n; i++) tmp += (pidx[i] != 0);
        ctr[ithread+1] = tmp;
        #pragma omp barrier
        #pragma omp single
        for (i=0; i<nthreads; i++)
        ctr[i+1] += ctr[i];
        tmp = ctr[ithread];
        #pragma omp barrier
        #pragma omp for private(this) reduction(+:ansi)
        for (i=0; i<n; i++) {
        this = pidx[i];
        if (this==0) continue;
        SET_STRING_ELT(ans, tmp++, (this==NA_INTEGER || this>max) ? NA_STRING : STRING_ELT(x, this-1));
        ansi++;
        }
    }
#else
    for (i=0; i<n; i++) {
        this = pidx[i];
        if (this==0) continue;
        SET_STRING_ELT(ans, ansi++, (this==NA_INTEGER || this>max) ? NA_STRING : STRING_ELT(x, this-1));
    }
#endif
    break;
    case VECSXP :
#ifdef _OPENMP
    #pragma omp parallel
    {
        int tmp=0, ithread = omp_get_thread_num(), nthreads = omp_get_num_threads();
        #pragma omp for
        for (i=0; i<n; i++) tmp += (pidx[i] != 0);
        ctr[ithread+1] = tmp;
        #pragma omp barrier
        #pragma omp single
        for (i=0; i<nthreads; i++)
        ctr[i+1] += ctr[i];
        tmp = ctr[ithread];
        #pragma omp barrier
        #pragma omp for private(this) reduction(+:ansi)
        for (i=0; i<n; i++) {
        this = pidx[i];
        if (this==0) continue;
        SET_VECTOR_ELT(ans, tmp++, (this==NA_INTEGER || this>max) ? R_NilValue : VECTOR_ELT(x, this-1));
        ansi++;
        }
    }
#else
    for (i=0; i<n; i++) {
        this = pidx[i];
        if (this==0) continue;
        SET_VECTOR_ELT(ans, ansi++, (this==NA_INTEGER || this>max) ? R_NilValue : VECTOR_ELT(x, this-1));
    }
#endif
    break;
    // Fix for #982
    // source: https://github.com/wch/r-source/blob/fbf5cdf29d923395b537a9893f46af1aa75e38f3/src/main/subset.c
    case CPLXSXP :
#ifdef _OPENMP
    #pragma omp parallel
    {
        int tmp=0, ithread = omp_get_thread_num(), nthreads = omp_get_num_threads();
        #pragma omp for
        for (i=0; i<n; i++) tmp += (pidx[i] != 0);
        ctr[ithread+1] = tmp;
        #pragma omp barrier
        #pragma omp single
        for (i=0; i<nthreads; i++)
        ctr[i+1] += ctr[i];
        tmp = ctr[ithread];
        #pragma omp barrier
        #pragma omp for private(this) reduction(+:ansi)
        for (i=0; i<n; i++) {
        this = pidx[i];
        if (this==0) continue;
        if (this == NA_INTEGER || this>max) {
            COMPLEX(ans)[tmp].r = NA_REAL;
            COMPLEX(ans)[tmp++].i = NA_REAL;
        } else COMPLEX(ans)[tmp++] = COMPLEX(x)[this-1];
        ansi++;
        }
    }
#else
    for (i=0; i<n; i++) {
        this = pidx[i];
        if (this == 0) continue;
        if (this == NA_INTEGER || this>max) {
        COMPLEX(ans)[ansi].r = NA_REAL;
        COMPLEX(ans)[ansi].i = NA_REAL;
        } else COMPLEX(ans)[ansi] = COMPLEX(x)[this-1];
        ansi++;
    }
#endif
    break;
    case RAWSXP :
#ifdef _OPENMP
    #pragma omp parallel
    {
        int tmp=0, ithread = omp_get_thread_num(), nthreads = omp_get_num_threads();
        #pragma omp for
        for (i=0; i<n; i++) tmp += (pidx[i] != 0);
        ctr[ithread+1] = tmp;
        #pragma omp barrier
        #pragma omp single
        for (i=0; i<nthreads; i++)
        ctr[i+1] += ctr[i];
        tmp = ctr[ithread];
        #pragma omp barrier
        #pragma omp for private(this) reduction(+:ansi)
        for (i=0; i<n; i++) {
        this = pidx[i];
        if (this==0) continue;
        RAW(ans)[tmp++] = (this == NA_INTEGER || this>max) ? (Rbyte) 0 : RAW(x)[this-1];
        ansi++;
        }
    }
#else
    for (i=0; i<n; i++) {
        this = pidx[i];
        if (this == 0) continue;
        RAW(ans)[ansi++] = (this == NA_INTEGER || this>max) ? (Rbyte) 0 : RAW(x)[this-1];
    }
#endif
    break;
    default :
    error("Unknown column type '%s'", type2char(TYPEOF(x)));
    }
#ifdef _OPENMP
    free(ctr);
#endif
    if (ansi != l) error("Internal error: ansi [%d] != l [%d] at the end of subsetVector", ansi, l);
    copyMostAttrib(x, ans);
    UNPROTECT(1);
    return(ans);
}
示例#14
0
文件: rbind.c 项目: Glanda/xts
SEXP rbind_append (SEXP x, SEXP y) {
/*

  Provide fast row binding of xts objects if the
  left-hand object (binding target) has a last
  index value less than the right-hand object
  (object to bind).  This is an optimization to allow
  for real-time updating of objects without having to
  do much more than a memcpy of the two in coordinated
  fashion

*/
  /*Rprintf("rbind_append called\n");*/
  SEXP result;
  int nrs_x, nrs_y, ncs_x, ncs_y, nr;
  int i;

  ncs_x = ncols(x); ncs_y = ncols(y); nrs_x = nrows(x); nrs_y = nrows(y);

  if(ncs_x != ncs_y)
    error("objects must have the same number of columns"); /* FIXME */

  PROTECT(result = allocVector(TYPEOF(x), (nrs_x + nrs_y) * ncs_x));
  nr = nrs_x + nrs_y;

  switch(TYPEOF(x)) {
    case REALSXP:
      for(i=0; i< ncs_x; i++) {
        memcpy(&(REAL(result)[i*nr]), 
               &(REAL(x)[i*nrs_x]), 
               nrs_x*sizeof(double));
        memcpy(&(REAL(result)[i*nr + nrs_x]), 
               &(REAL(y)[i*nrs_y]), 
               nrs_y*sizeof(double));
      }
      break;
    case INTSXP:
      for(i=0; i< ncs_x; i++) {
        memcpy(&(INTEGER(result)[i*nr]), 
               &(INTEGER(x)[i*nrs_x]), 
               nrs_x*sizeof(int));
        memcpy(&(INTEGER(result)[i*nr + nrs_x]), 
               &(INTEGER(y)[i*nrs_y]), 
               nrs_y*sizeof(int));
      }
      break;
    case LGLSXP:
      for(i=0; i< ncs_x; i++) {
        memcpy(&(LOGICAL(result)[i*nr]), 
               &(LOGICAL(x)[i*nrs_x]), 
               nrs_x*sizeof(int));
        memcpy(&(LOGICAL(result)[i*nr + nrs_x]), 
               &(LOGICAL(y)[i*nrs_y]), 
               nrs_y*sizeof(int));
      }
      break;
    case CPLXSXP:
      for(i=0; i< ncs_x; i++) {
        memcpy(&(COMPLEX(result)[i*nr]), 
               &(COMPLEX(x)[i*nrs_x]), 
               nrs_x*sizeof(Rcomplex));
        memcpy(&(COMPLEX(result)[i*nr + nrs_x]), 
               &(COMPLEX(y)[i*nrs_y]), 
               nrs_y*sizeof(Rcomplex));
      }
      break;
    case RAWSXP:
      for(i=0; i< ncs_x; i++) {
        memcpy(&(RAW(result)[i*nr]), 
               &(RAW(x)[i*nrs_x]), 
               nrs_x*sizeof(Rbyte));
        memcpy(&(RAW(result)[i*nr + nrs_x]), 
               &(RAW(y)[i*nrs_y]), 
               nrs_y*sizeof(Rbyte));
      }
      break;
    case STRSXP:
      /* this requires an explicit loop like rbind.c and
         needs to be left with rbind.c
      */
      break;
    default:
      error("unsupported type");
  }

  copyAttributes(x, result); 

  SEXP index, xindex, yindex;
  xindex = getAttrib(x,install("index"));
  yindex = getAttrib(y,install("index"));
  int INDEXTYPE = TYPEOF(xindex);
  if(INDEXTYPE != NILSXP) {
    PROTECT(index = allocVector(INDEXTYPE, nr));
    if(INDEXTYPE==REALSXP) {
      memcpy(REAL(index), REAL(xindex), nrs_x * sizeof(double));
      memcpy(&(REAL(index)[nrs_x]), REAL(yindex), nrs_y * sizeof(double));
    } else
    if(INDEXTYPE==INTSXP) {
      memcpy(INTEGER(index), INTEGER(xindex), nrs_x * sizeof(int));
      memcpy(&(INTEGER(index)[nrs_x]), INTEGER(yindex), nrs_y * sizeof(int));
    }
    copyMostAttrib(xindex, index);
    setAttrib(result, install("index"), index);
    UNPROTECT(1);
  }

    SEXP dim;
    PROTECT(dim = allocVector(INTSXP, 2));
    INTEGER(dim)[0] = nr;
    INTEGER(dim)[1] = ncs_x; /* should be the same */
    setAttrib(result, R_DimSymbol, dim);
    UNPROTECT(1);

    setAttrib(result, R_DimNamesSymbol, getAttrib(x, R_DimNamesSymbol));
/*
    SEXP dimnames, currentnames, newnames;
    PROTECT(dimnames = allocVector(VECSXP, 2));
    PROTECT(newnames = allocVector(STRSXP, length(j)));
    currentnames = getAttrib(x, R_DimNamesSymbol);

    if(!isNull(currentnames)) {
      SET_VECTOR_ELT(dimnames, 0, R_NilValue);
      for(i=0; i<ncs_x; i++) {
        SET_STRING_ELT(newnames, i, STRING_ELT(VECTOR_ELT(currentnames,1), i));
      }
      SET_VECTOR_ELT(dimnames, 1, newnames);
      setAttrib(result, R_DimNamesSymbol, dimnames);
    }
    UNPROTECT(2);
*/

  UNPROTECT(1);
  return result;
}
示例#15
0
SEXP readfixedsubset(SEXP s_file, SEXP what, SEXP s_vars, SEXP s_cases, SEXP s_start, SEXP s_stop){
  FILE *f = rofile_FILE(s_file);
  PROTECT(s_vars = coerceVector(s_vars,LGLSXP));
  PROTECT(s_cases = coerceVector(s_cases,LGLSXP));
  PROTECT(s_start =  coerceVector(s_start,INTSXP));
  PROTECT(s_stop = coerceVector(s_stop,INTSXP));
  if(LENGTH(s_start) != LENGTH(s_stop)) error("start and stop must have equal length");
  if(LENGTH(s_vars) != LENGTH(s_stop)) error("vars argument has wrong length");
  int m = 0, n = 0;
  int nvar = LENGTH(what);
  int ncases = LENGTH(s_cases);
  int ii,i,j,k;
  for(i = 0; i < LENGTH(s_cases); i++) n += LOGICAL(s_cases)[i];
  for(j = 0; j < LENGTH(s_vars); j++) m += LOGICAL(s_vars)[j];
  int *start = INTEGER(s_start);
  int *stop = INTEGER(s_stop);
  int max_lenline = stop[nvar-1];
  char *buffer = R_alloc(max_lenline+3,1);
  char *item, *currdata;

  SEXP data;
  PROTECT(data = allocVector(VECSXP,m));
  SEXP x, y;
  int *length = (int *) R_alloc(nvar,sizeof(int));
  int maxlen = 0;
  k = 0;
  for(j = 0; j < nvar; j++){
    length[j] = stop[j] - start[j] + 1;
    if(LOGICAL(s_vars)[j]){
      if(maxlen < length[j]) maxlen = length[j];
      x = VECTOR_ELT(what,j);
      SET_VECTOR_ELT(data,k,lengthgets(x,n));
      k++;
    }
  }
  item = R_alloc(maxlen+1,1);
  ii = 0;
  for(i = 0; i < ncases; i++){
    memset(buffer,0,max_lenline+3);
    buffer = fgets(buffer,max_lenline+3,f);
#ifdef DEBUG
    Rprintf("Requested line length: %d\n",max_lenline);
    Rprintf("Actual line length: %d\n",strlen(buffer));
    Rprintf("Buffer: >>%s<<\n",buffer);
#endif
    if(strlen(buffer)< max_lenline) {
      int new_length = i;
      for(j = 0; j < nvar; j++){
        x = VECTOR_ELT(data,j);
        SET_VECTOR_ELT(data,j,lengthgets(x,new_length));
      }
      n = new_length;
      break;
    }
    if(LOGICAL(s_cases)[i]){
      currdata = buffer;
      k = 0;
      for(j = 0; j < nvar; j++){
        currdata = buffer + start[j]-1;
        if(LOGICAL(s_vars)[j]){
          x = VECTOR_ELT(data,k);
          memset(item,0,maxlen+1);
          memcpy(item,currdata,length[j]);
          trim(item,length[j]);
#ifdef DEBUG
          Rprintf("Item: >>%s<<\n",item);
#endif
#undef DEBUG    
          if(TYPEOF(x)==INTSXP)
            INTEGER(x)[ii] = _R_atoi(item);
          else if (TYPEOF(x)==REALSXP)
            REAL(x)[ii] = _R_atof(item);
          else
            SET_STRING_ELT(x,ii,mkChar(item));
          k++;
          }
        }
        ii++;
      }
    }
  k = 0;
  for(j = 0; j < nvar; j++){
    if(LOGICAL(s_vars)[j]){
      x = VECTOR_ELT(what,j);
      y = VECTOR_ELT(data,k);
      copyMostAttrib(x,y);
      k++;
    }
  }

  UNPROTECT(5);
  return data;
}
示例#16
0
SEXP fastmean(SEXP args)
{
  	long double s = 0., t = 0.;
	R_len_t i, l = 0, n = 0;
	SEXP x, ans, tmp;
	Rboolean narm=FALSE;
	x=CADR(args);
	if (length(args)>2) {
	    tmp = CADDR(args);
	    if (!isLogical(tmp) || LENGTH(tmp)!=1 || LOGICAL(tmp)[0]==NA_LOGICAL)
            error("narm should be TRUE or FALSE");
	    narm=LOGICAL(tmp)[0];
	}
	PROTECT(ans = allocNAVector(REALSXP, 1));
	if (!isInteger(x) && !isReal(x) && !isLogical(x)) {
        warning("argument is not numeric or logical: returning NA");
        UNPROTECT(1);
        return(ans);
    }
    l = LENGTH(x);
	if (narm) {
	    switch(TYPEOF(x)) {
	    case LGLSXP:
	    case INTSXP:
	        for (i = 0; i<l; i++) {
		        if(INTEGER(x)[i] == NA_INTEGER) continue;
		        s += INTEGER(x)[i];   // no under/overflow here, s is long double not integer
		        n++;
		    }
		    if (n>0)
		        REAL(ans)[0] = (double) (s/n);
		    else
		        REAL(ans)[0] = R_NaN;  // consistent with base: mean(NA,na.rm=TRUE)==NaN==mean(numeric(),na.rm=TRUE)
	        break;
	    case REALSXP:
	        for (i = 0; i<l; i++) {
	            if(ISNAN(REAL(x)[i])) continue;  // TO DO: could drop this line and let NA propogate?
	            s += REAL(x)[i];
	            n++;
	        }
	        if (n==0) {
	            REAL(ans)[0] = R_NaN;
	            break;
	        }
	        s /= n;
	        if(R_FINITE((double)s)) {
		        for (i = 0; i<l; i++) {
		            if(ISNAN(REAL(x)[i])) continue;
		            t += (REAL(x)[i] - s);
		        }
		        s += t/n;
	        }
	        REAL(ans)[0] = (double) s;
	        break;
	    default:
	        error("Type '%s' not supported in fastmean", type2char(TYPEOF(x)));
	    }
    } else {  // narm==FALSE
	    switch(TYPEOF(x)) {
	    case LGLSXP:
	    case INTSXP:
	        for (i = 0; i<l; i++) {
		        if(INTEGER(x)[i] == NA_INTEGER) {UNPROTECT(1); return(ans);}
		        s += INTEGER(x)[i];
		    }
		    REAL(ans)[0] = (double) (s/l);
	        break;
	    case REALSXP:
	        for (i = 0; i<l; i++) {
	            if(ISNAN(REAL(x)[i])) {UNPROTECT(1); return(ans);}
	            s += REAL(x)[i];
	        }
	        s /= l;
	        if(R_FINITE((double)s)) {
		        for (i = 0; i<l; i++) {
		            // no NA if got this far
		            t += (REAL(x)[i] - s);
		        }
		        s += t/LENGTH(x);
	        }
	        REAL(ans)[0] = (double) s;
	        break;
	    default:
	        error("Type '%s' not supported in fastmean", type2char(TYPEOF(x)));
	    }
    }
    copyMostAttrib(x, ans);
    UNPROTECT(1);
    return(ans);
} 
示例#17
0
SEXP readfixed(SEXP s_file, SEXP what, SEXP s_nlines, SEXP s_start, SEXP s_stop){
  PROTECT(s_start = coerceVector(s_start,INTSXP));
  PROTECT(s_stop = coerceVector(s_stop,INTSXP));
  FILE *f = rofile_FILE(s_file);
  if(LENGTH(s_start) != LENGTH(s_stop)) error("start and stop must have equal length");
  int n = asInteger(s_nlines);
  int nvar = LENGTH(s_start);
  int *start = INTEGER(s_start);
  int *stop = INTEGER(s_stop);
  int max_lenline = stop[nvar-1];
  char *buffer = R_alloc(max_lenline+3,1);
  char *item, *currdata;
  SEXP data;
  PROTECT(data=allocVector(VECSXP,nvar));
  int i,j;
  int *length = (int *) R_alloc(nvar,sizeof(int));
  int maxlen = 0;
  SEXP x,y;
  for(j = 0; j < nvar; j++){
    length[j] = stop[j] - start[j] + 1;
    if(maxlen < length[j]) maxlen = length[j];
    x = VECTOR_ELT(what,j);
    SET_VECTOR_ELT(data,j,lengthgets(x,n));
  }
  item = R_alloc(maxlen+1,1);
#undef DEBUG
#ifdef DEBUG
  Rprintf("Requested number of lines: %d\n",n);
#endif  
  for(i = 0; i < n; i++){
    memset(buffer,0,max_lenline+3);
    buffer = fgets(buffer,max_lenline+3,f);
#ifdef DEBUG
    Rprintf("Requested line length: %d\n",max_lenline);
    Rprintf("Actual line length: %d\n",strlen(buffer));
    if(i == 0)
      Rprintf("Buffer: >>%s<<\n",buffer);
#endif    
    if(strlen(buffer)< max_lenline) {
      int new_length = i;
      for(j = 0; j < nvar; j++){
        x = VECTOR_ELT(data,j);
        SET_VECTOR_ELT(data,j,lengthgets(x,new_length));
      }
      n = new_length;
      break;
    }
    currdata = buffer;
    for(j = 0; j < nvar; j++){
      x = VECTOR_ELT(data,j);
      currdata = buffer + start[j]-1;
      memset(item,0,maxlen+1);
      memcpy(item,currdata,length[j]);
      trim(item,length[j]);
#undef DEBUG
      if(TYPEOF(x)==INTSXP)
        INTEGER(x)[i] = _R_atoi(item);
      else if (TYPEOF(x)==REALSXP)
        REAL(x)[i] = _R_atof(item);
      else
        SET_STRING_ELT(x,i,mkChar(item));
    }
  }
  for(j = 0; j < nvar; j++){
    x = VECTOR_ELT(what,j);
    y = VECTOR_ELT(data,j);
    copyMostAttrib(x,y);
  }  
  UNPROTECT(3);
  return data;
}
示例#18
0
SEXP readDataPorStream(SEXP porStream, SEXP what, SEXP s_n, SEXP s_types){
#ifdef DEBUG
  Rprintf("\n############################");
  Rprintf("\n#readDataPorStream");
  Rprintf("\n############################");
#endif
  porStreamBuf *b = get_porStreamBuf(porStream);
  int n = asInteger(s_n);

#ifdef DEBUG
  Rprintf("\nRequired number of cases: %d",n);
  Rprintf("\nBuffer contents: |%s|",b->buf);
  Rprintf("\nLine: %d",b->line);
  Rprintf("\nPosition: %d",b->pos);
  Rprintf("\nBuffer remainder: %s",b->buf + b->pos);
#endif
  PROTECT(s_types = coerceVector(s_types,INTSXP));
  int nvar = length(s_types);
  int *types = INTEGER(s_types);

  SEXP x, y, data;
  char *charbuf;
  int charbuflen = 0;
  PROTECT(data = allocVector(VECSXP,nvar));
  int i,j;
  for(j = 0; j < nvar; j++){
    if(types[j]==0)
      SET_VECTOR_ELT(data,j,allocVector(REALSXP,n));
    else {
      SET_VECTOR_ELT(data,j,allocVector(STRSXP,n));
      if(types[j] > charbuflen) charbuflen = types[j];
      }
  }
  charbuf = R_alloc(charbuflen+1,sizeof(char));

#ifdef DEBUG
//   PrintValue(data);
#endif

  for(i = 0; i < n; i++){
    if(atEndPorStream(b) || (b->pos < 80 && b->buf[b->pos] == 'Z')){
#ifdef DEBUG
      Rprintf("\nReached end of cases at i=%d",i);
#endif
      int new_length = i;
      for(j = 0; j < nvar; j++){
        x = VECTOR_ELT(data,j);
        SET_VECTOR_ELT(data,j,lengthgets(x,new_length));
      }
      n = new_length;
      break;
    }
#ifdef DEBUG
    Rprintf("\nCase number: %d\n",i);
#endif
    for(j = 0; j < nvar; j++){
      if(atEndPorStream(b)) {
          printPorStreamBuf(b);
          warning("\nPremature end of data");
          break;
      }
#ifdef DEBUG
      PrintValue(VECTOR_ELT(data,j));
#endif
      if(types[j]==0) REAL(VECTOR_ELT(data,j))[i] = readDoublePorStream1(b);
      else SET_STRING_ELT(VECTOR_ELT(data,j), i,
                          mkChar(readCHARPorStream(b,charbuf,types[j])));
#ifdef DEBUG
      if(i<3 && types[j]>0)
      PrintValue(STRING_ELT(VECTOR_ELT(data,j),i));
#endif
      }
    }
  for(j = 0; j < nvar; j++){
    x = VECTOR_ELT(what,j);
    y = VECTOR_ELT(data,j);
    copyMostAttrib(x,y);
  }
  UNPROTECT(2);
  return data;
}
示例#19
0
SEXP attribute_hidden complex_binary(ARITHOP_TYPE code, SEXP s1, SEXP s2)
{
    R_xlen_t i,i1, i2, n, n1, n2;
    SEXP ans;

    /* Note: "s1" and "s2" are protected in the calling code. */
    n1 = XLENGTH(s1);
    n2 = XLENGTH(s2);
     /* S4-compatibility change: if n1 or n2 is 0, result is of length 0 */
    if (n1 == 0 || n2 == 0) return(allocVector(CPLXSXP, 0));

    n = (n1 > n2) ? n1 : n2;
    ans = R_allocOrReuseVector(s1, s2, CPLXSXP, n);
    PROTECT(ans);

    switch (code) {
    case PLUSOP:
	mod_iterate(n1, n2, i1, i2) {
	    if ((i+1) % NINTERRUPT == 0) R_CheckUserInterrupt();
	    Rcomplex x1 = COMPLEX(s1)[i1], x2 = COMPLEX(s2)[i2];
	    COMPLEX(ans)[i].r = x1.r + x2.r;
	    COMPLEX(ans)[i].i = x1.i + x2.i;
	}
	break;
    case MINUSOP:
	mod_iterate(n1, n2, i1, i2) {
	    if ((i+1) % NINTERRUPT == 0) R_CheckUserInterrupt();
	    Rcomplex x1 = COMPLEX(s1)[i1], x2 = COMPLEX(s2)[i2];
	    COMPLEX(ans)[i].r = x1.r - x2.r;
	    COMPLEX(ans)[i].i = x1.i - x2.i;
	}
	break;
    case TIMESOP:
	mod_iterate(n1, n2, i1, i2) {
	    if ((i+1) % NINTERRUPT == 0) R_CheckUserInterrupt();
	    SET_C99_COMPLEX(COMPLEX(ans), i,
			    C99_COMPLEX2(s1, i1) * C99_COMPLEX2(s2, i2));
	}
	break;
    case DIVOP:
	mod_iterate(n1, n2, i1, i2) {
	    if ((i+1) % NINTERRUPT == 0) R_CheckUserInterrupt();
	    SET_C99_COMPLEX(COMPLEX(ans), i,
			    C99_COMPLEX2(s1, i1) / C99_COMPLEX2(s2, i2));
	}
	break;
    case POWOP:
	mod_iterate(n1, n2, i1, i2) {
	    if ((i+1) % NINTERRUPT == 0) R_CheckUserInterrupt();
	    SET_C99_COMPLEX(COMPLEX(ans), i,
			    mycpow(C99_COMPLEX2(s1, i1), C99_COMPLEX2(s2, i2)));
	}
	break;
    default:
	error(_("unimplemented complex operation"));
    }
    UNPROTECT(1);

    /* quick return if there are no attributes */
    if (ATTRIB(s1) == R_NilValue && ATTRIB(s2) == R_NilValue)
	return ans;

    /* Copy attributes from longer argument. */

    if (ans != s2 && n == n2 && ATTRIB(s2) != R_NilValue)
        copyMostAttrib(s2, ans);
    if (ans != s1 && n == n1 && ATTRIB(s1) != R_NilValue)
        copyMostAttrib(s1, ans); /* Done 2nd so s1's attrs overwrite s2's */

    return ans;
}
示例#20
0
SEXP shift(SEXP obj, SEXP k, SEXP fill, SEXP type) {

  size_t size;
  int protecti=0;
  SEXP x, tmp=R_NilValue, elem, ans, thisfill, klass;
  unsigned long long *dthisfill;
  enum {LAG, LEAD/*, SHIFT, CYCLIC*/} stype = LAG; // currently SHIFT maps to LAG and CYCLIC is unimplemented (see comments in #1708)
  if (!xlength(obj)) return(obj); // NULL, list()
  if (isVectorAtomic(obj)) {
    x = PROTECT(allocVector(VECSXP, 1)); protecti++;
    SET_VECTOR_ELT(x, 0, obj);
  } else x = obj;
  if (!isNewList(x))
    error("x must be a list, data.frame or data.table");
  if (length(fill) != 1)
    error("fill must be a vector of length 1");
  // the following two errors should be caught by match.arg() at the R level
  if (!isString(type) || length(type) != 1)
    error("Internal error: invalid type for shift(), should have been caught before. please report to data.table issue tracker"); // # nocov
  if (!strcmp(CHAR(STRING_ELT(type, 0)), "lag")) stype = LAG;
  else if (!strcmp(CHAR(STRING_ELT(type, 0)), "lead")) stype = LEAD;
  else if (!strcmp(CHAR(STRING_ELT(type, 0)), "shift")) stype = LAG; // when we get rid of nested if branches we can use SHIFT, for now it maps to LAG
  else error("Internal error: invalid type for shift(), should have been caught before. please report to data.table issue tracker"); // # nocov

  int nx = length(x), nk = length(k);
  if (!isInteger(k)) error("Internal error: k must be integer"); // # nocov
  const int *kd = INTEGER(k);
  for (int i=0; i<nk; i++) if (kd[i]==NA_INTEGER) error("Item %d of n is NA", i+1);  // NA crashed (#3354); n is called k at C level

  ans = PROTECT(allocVector(VECSXP, nk * nx)); protecti++;
  for (int i=0; i<nx; i++) {
    elem  = VECTOR_ELT(x, i);
    size  = SIZEOF(elem);
    R_xlen_t xrows = xlength(elem);
    switch (TYPEOF(elem)) {
    case INTSXP :
      thisfill = PROTECT(coerceVector(fill, INTSXP)); protecti++;
      int ifill = INTEGER(thisfill)[0];
      for (int j=0; j<nk; j++) {
        R_xlen_t thisk = MIN(abs(kd[j]), xrows);
        SET_VECTOR_ELT(ans, i*nk+j, tmp=allocVector(INTSXP, xrows) );
        int *itmp = INTEGER(tmp);
        size_t tailk = xrows-thisk;
        if ((stype == LAG && kd[j] >= 0) || (stype == LEAD && kd[j] < 0)) {
          // LAG when type = 'lag' and n >= 0 _or_ type = 'lead' and n < 0
          if (tailk > 0) memmove(itmp+thisk, INTEGER(elem), tailk*size);
          for (int m=0; m<thisk; m++) itmp[m] = ifill;
        } else {
          // only two possibilities left: type = 'lead', n>=0 _or_ type = 'lag', n<0
          if (tailk > 0) memmove(itmp, INTEGER(elem)+thisk, tailk*size);
          for (int m=xrows-thisk; m<xrows; m++) itmp[m] = ifill;
        }
        copyMostAttrib(elem, tmp);
        if (isFactor(elem)) setAttrib(tmp, R_LevelsSymbol, getAttrib(elem, R_LevelsSymbol));
      }
      break;

    case REALSXP :
      klass = getAttrib(elem, R_ClassSymbol);
      if (isString(klass) && STRING_ELT(klass, 0) == char_integer64) {
        thisfill = PROTECT(allocVector(REALSXP, 1)); protecti++;
        dthisfill = (unsigned long long *)REAL(thisfill);
        if (INTEGER(fill)[0] == NA_INTEGER)
          dthisfill[0] = NA_INT64_LL;
        else dthisfill[0] = (unsigned long long)INTEGER(fill)[0];
      } else {
        thisfill = PROTECT(coerceVector(fill, REALSXP)); protecti++;
      }
      double dfill = REAL(thisfill)[0];
      for (int j=0; j<nk; j++) {
        R_xlen_t thisk = MIN(abs(kd[j]), xrows);
        SET_VECTOR_ELT(ans, i*nk+j, tmp=allocVector(REALSXP, xrows) );
        double *dtmp = REAL(tmp);
        size_t tailk = xrows-thisk;
        if ((stype == LAG && kd[j] >= 0) || (stype == LEAD && kd[j] < 0)) {
          if (tailk > 0) memmove(dtmp+thisk, REAL(elem), tailk*size);
          for (int m=0; m<thisk; m++) dtmp[m] = dfill;
        } else {
          if (tailk > 0) memmove(dtmp, REAL(elem)+thisk, tailk*size);
          for (int m=tailk; m<xrows; m++) dtmp[m] = dfill;
        }
        copyMostAttrib(elem, tmp);
      }
      break;

    case LGLSXP :
      thisfill = PROTECT(coerceVector(fill, LGLSXP)); protecti++;
      int lfill = LOGICAL(thisfill)[0];
      for (int j=0; j<nk; j++) {
        R_xlen_t thisk = MIN(abs(kd[j]), xrows);
        SET_VECTOR_ELT(ans, i*nk+j, tmp=allocVector(LGLSXP, xrows) );
        int *ltmp = LOGICAL(tmp);
        size_t tailk = xrows-thisk;
        if ((stype == LAG && kd[j] >= 0) || (stype == LEAD && kd[j] < 0)) {
          if (tailk > 0) memmove(ltmp+thisk, LOGICAL(elem), tailk*size);
          for (int m=0; m<thisk; m++) ltmp[m] = lfill;
        } else {
          if (tailk > 0) memmove(ltmp, LOGICAL(elem)+thisk, tailk*size);
          for (int m=tailk; m<xrows; m++) ltmp[m] = lfill;
        }
        copyMostAttrib(elem, tmp);
      }
      break;

    case STRSXP :
      thisfill = PROTECT(coerceVector(fill, STRSXP)); protecti++;
      for (int j=0; j<nk; j++) {
        SET_VECTOR_ELT(ans, i*nk+j, tmp=allocVector(STRSXP, xrows) );
        int thisk = abs(kd[j]);
        if ((stype == LAG && kd[j] >= 0) || (stype == LEAD && kd[j] < 0)) {
          for (int m=0; m<xrows; m++) SET_STRING_ELT(tmp, m, (m < thisk) ? STRING_ELT(thisfill, 0) : STRING_ELT(elem, m - thisk));
        } else {
          for (int m=0; m<xrows; m++) SET_STRING_ELT(tmp, m, (xrows-m <= thisk) ? STRING_ELT(thisfill, 0) : STRING_ELT(elem, m + thisk));
        }
        copyMostAttrib(elem, tmp);
      }
      break;

    case VECSXP :
      thisfill = PROTECT(coerceVector(fill, VECSXP)); protecti++;
      for (int j=0; j<nk; j++) {
        SET_VECTOR_ELT(ans, i*nk+j, tmp=allocVector(VECSXP, xrows) );
        int thisk = abs(kd[j]);
        if ((stype == LAG && kd[j] >= 0) || (stype == LEAD && kd[j] < 0)) {
          for (int m=0; m<xrows; m++) SET_VECTOR_ELT(tmp, m, (m < thisk) ? VECTOR_ELT(thisfill, 0) : VECTOR_ELT(elem, m - thisk));
        } else {
          for (int m=0; m<xrows; m++) SET_VECTOR_ELT(tmp, m, (xrows-m <= thisk) ? VECTOR_ELT(thisfill, 0) : VECTOR_ELT(elem, m + thisk));
        }
        copyMostAttrib(elem, tmp);
      }
      break;

    default :
      error("Unsupported type '%s'", type2char(TYPEOF(elem)));
    }
  }

  UNPROTECT(protecti);
  return isVectorAtomic(obj) && length(ans) == 1 ? VECTOR_ELT(ans, 0) : ans;
}