为什么 Rcpp 会损坏 xts 对象? [英] Why does Rcpp corrupt xts object?

查看:49
本文介绍了为什么 Rcpp 会损坏 xts 对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个 xts 对象并通过 Rcpp 函数返回索引.以这种方式触摸 xts 对象似乎破坏了 xts 对象.

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.

虽然我有解决方法,但我不明白为什么会出现问题——或者为什么需要我的 hack?

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

使用来自 dirk 的 Rcpp Gallery 的建议代码,xts 对象一旦被触摸就会损坏.

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

怎么回事?

推荐答案

我无法用更简单的属性提取功能重现一切都很好,xx 没有改变:

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    
> 

函数 xtsIndex 将在输入上创建一个副本(因为我们的 xts 对象包含一个整数序列作为数据,NumericMatrix 肯定是一个复制的对象,但它保留了我们可以提取的属性).

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).

但是请注意,来自 xxDate 序列现在如何以 POSIXctDatetime 为单位显示>.这看起来像是 xts(或可能是 Rcpp 但我认为它是 xts 此处)可能在此处执行的强制转换的可能错误.您最好从 POSIXct 时间对象开始,即使它是每日数据.

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.

这样做还可以让我们正确键入 Datetime 的提取器函数:

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        
>   

这篇关于为什么 Rcpp 会损坏 xts 对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆