0

I'd like to subset an xts object in an Rcpp function and return the subset.

If the xts object has an index of class Date extracting the index via Rcpp corrupts the xts object -- see dirk's answer to this question, where he demonstrates that getting a pointer to the Date indices from the xts (what i call the SEXP approach) doesn't lead to corruption.

Say that i have a pointer s to the SEXP in Rcpp -- how do i iterate over the underlying object using that SEXP? Can it be done?

I'd like to iterate over the underlying object, and return a subset of that object.

The below R code does what I require:

set.seed(1)
require(xts)
xx_date <- xts(round(runif(100, min = 0, max = 20), 0), 
  order.by = seq.Date(Sys.Date(), by = "day", length.out = 100))

subXts_r <- function(Xts) {
  i = 2
  while( as.numeric(Xts[i, ]) != as.numeric(Xts[i-1, ])) {
    if (i == nrow(Xts)) break else i = i+1
  }
  Xts[1:i,]
}

subXts_r(xx_date)

This Rcpp code also does what I want, but it uses a clone of the index (second line) to prevent corruption. My idea is to replace the second line with SEXP s = X.attr(\"index\") -- but I don't know how to iterate over s once I have it.

cppFunction("NumericVector subXts_cpp(NumericMatrix X) {
            DatetimeVector v = clone(NumericVector(X.attr(\"index\"))); // need to clone else xx_date is corrupted
            double * p_dt = v.begin() +1;
            double * p_value = X.begin() +1;
            while( (*p_value != *(p_value -1)) & (p_value < X.end())) {
              p_value++;
              p_dt++;
            }

            Rcpp::NumericVector toDoubleValue(X.begin(), p_value);
            Rcpp::NumericVector toDoubleDate(v.begin(), p_dt);

            int rows = toDoubleValue.size(); // find length of xts object

            toDoubleDate.attr(\"tzone\")    = \"UTC\";         // the index has attributes
  CharacterVector t_class  = CharacterVector::create(\"POSIXct\", \"POSIXt\");
            toDoubleDate.attr(\"tclass\")   = t_class;

  // now modify dataVec to make into an xts
  toDoubleValue.attr(\"dim\")         = IntegerVector::create(rows,1);
  toDoubleValue.attr(\"index\")       = toDoubleDate;
  CharacterVector d_class  = CharacterVector::create(\"xts\", \"zoo\");
  toDoubleValue.attr(\"class\")       = d_class;
  toDoubleValue.attr(\".indexCLASS\") = t_class;
  toDoubleValue.attr(\"tclass\")      = t_class;
  toDoubleValue.attr(\".indexTZ\")    = \"UTC\";
  toDoubleValue.attr(\"tzone\")       = \"UTC\";
            return toDoubleValue;}")
ricardo
  • 8,195
  • 7
  • 47
  • 69
  • 1
    SEXP objects already _are_ pointers as the letters expand to "Pointer to SEX object". And this question seems a little confused. Did you look at my answer to your other question? – Dirk Eddelbuettel May 13 '21 at 13:52
  • 2
    I confess I have no idea what you actually want to do, and little of what you wrote makes sense. You don't need iterators (we have vectorized commands in Rcpp Sugar), I showed you in the other question that you do not need deep copies (unless I misunderstand something). Maybe best to delete this question, think things over and maybe show with a simple _working_ R example what you want to do, and then whatever C++ code you have that tries to replicate it. (Also note that xts operations are efficient, you will bit be faster just because you force them to be done in C++.) – Dirk Eddelbuettel May 13 '21 at 20:37
  • 6
    I am always happy to help people -- I have answered apprently more than 3700 times on this site -- but you have to help me help you. If the question is unclear, convoluted, too long, ... or otherwise off-putting I may just move on, as to other help. Make it _easy_ and _obvious_ what you want, did, and are struggling with and people may spend their spare time helping you for free. – Dirk Eddelbuettel May 13 '21 at 23:24

0 Answers0