为什么 Rcpp 会损坏 xts 对象? [英] Why does Rcpp corrupt xts object?
问题描述
假设我有一个 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).
但是请注意,来自 xx
的 Date
序列现在如何以 POSIXct
或 Datetime
为单位显示>.这看起来像是 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屋!