简体   繁体   中英

Why does Rcpp corrupt xts object?

Say I have an xts object and return the index via an Rcpp function. Touching the xts object in this way seems to corrupt the xts object.

It can be fixed by forcing a deep copy.

While i do have a work-around, i don't understand why the problem exists -- or why my hack is required?

Using the suggested code from dirk's Rcpp Gallery , the xts object is corrupted once touched.

// [[Rcpp::export]]
DatetimeVector xtsIndex(NumericMatrix X) {
    DatetimeVector v(NumericVector(X.attr("index")));
    return v;
}

require(xts)
xx <- xts(1:10, order.by = seq.Date(Sys.Date(), by = "day", length.out = 10))

xtsIndex(xx)

...

> print(xx)
Error in Ops.POSIXt(.index(x), 86400) : 
  '%/%' not defined for "POSIXt" objects

Tweaking the code to force a deep copy prevents the corruption.

// [[Rcpp::export]]
DatetimeVector xtsIndex_deep(NumericMatrix X) {
    DatetimeVector v = clone(NumericVector(X.attr("index")));
    return v;
}

> xtsIndex_deep(xx)
 [1] "2021-05-13 UTC" "2021-05-14 UTC" "2021-05-15 UTC" "2021-05-16 UTC" "2021-05-17 UTC"
 [6] "2021-05-18 UTC" "2021-05-19 UTC" "2021-05-20 UTC" "2021-05-21 UTC" "2021-05-22 UTC"
> xx
           [,1] [,2]
2021-05-13    1   10
2021-05-14    2    9
2021-05-15    3    8
2021-05-16    4    7
2021-05-17    5    6
2021-05-18    6    5
2021-05-19    7    4
2021-05-20    8    3
2021-05-21    9    2
2021-05-22   10    1

what's going on?

I cannot reproduce that with a simpler attribute extraction function all is well and xx is not altered:

> cppFunction("SEXP xtsIndex(NumericMatrix X) { SEXP s = X.attr(\"index\");  return s; } ") 
> xx <- xts(1:10, order.by = seq.Date(Sys.Date(), by = "day", length.out = 10))   
> head(xx)         
           [,1]    
2021-05-13    1    
2021-05-14    2    
2021-05-15    3    
2021-05-16    4    
2021-05-17    5    
2021-05-18    6    
>                  
> xtsIndex(xx)     
 [1] 1620864000 1620950400 1621036800 1621123200 1621209600 1621296000 
 [7] 1621382400 1621468800 1621555200 1621641600         
attr(,"tzone")                                           
[1] "UTC"                                                
attr(,"tclass")                                          
[1] "Date"                                               
>                                                        
> head(xx)                                               
           [,1]                                          
2021-05-13    1                                          
2021-05-14    2                                          
2021-05-15    3    
2021-05-16    4    
2021-05-17    5    
2021-05-18    6    
> 

The function xtsIndex will create a copy on input (as our xts object contains an integer sequence as data the NumericMatrix will surely be a copied object, but it retains the attribute we can extract).

Note, however, how the Date sequence from xx is now displayed in units of a POSIXct or Datetime . This looks like a possible error from a coercion which xts (or possibly Rcpp but I think it is xts here) may do here. You are probably better off starting with a POSIXct time object even if it daily data.

Doing so also allow us to properly type the extractor function for Datetime :

> cppFunction("DatetimeVector xtsIndex(NumericMatrix X) { 
                   return DatetimeVector(wrap(X.attr(\"index\"))); } ")   
> xx <- xts(1:10, order.by = as.POSIXct(seq.Date(Sys.Date(), by = "day", length.out = 10))) 
> head(xx)   
                    [,1]    
2021-05-12 19:00:00    1    
2021-05-13 19:00:00    2    
2021-05-14 19:00:00    3    
2021-05-15 19:00:00    4    
2021-05-16 19:00:00    5    
2021-05-17 19:00:00    6    
> head(xtsIndex(xx))        
[1] "2021-05-12 19:00:00 CDT" "2021-05-13 19:00:00 CDT" "2021-05-14 19:00:00 CDT"  
[6] "2021-05-15 19:00:00 CDT" "2021-05-16 19:00:00 CDT" "2021-05-17 19:00:00 CDT" 
> head(xx)  
                    [,1]        
2021-05-12 19:00:00    1        
2021-05-13 19:00:00    2        
2021-05-14 19:00:00    3        
2021-05-15 19:00:00    4        
2021-05-16 19:00:00    5        
2021-05-17 19:00:00    6        
>   

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM