为什么 Rcpp 会损坏 xts 对象?

时间:2021-05-13 03:02:32

标签: r rcpp xts

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

可以通过强制深度复制来修复。

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

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

// [[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

调整代码以强制进行深度复制可防止损坏。

// [[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

怎么回事?

1 个答案:

答案 0 :(得分:4)

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

> 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 肯定是一个复制对象,但它保留了 {{ 1}} 我们可以提取)。

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

这样做还允许我们正确键入 POSIXct 的提取器函数:

Datetime
相关问题