【发布时间】:2021-08-03 09:23:20
【问题描述】:
假设我有一个 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
发生了什么事?
【问题讨论】:
-
这里发生了很多事情,你玩的有点快和松。
xx是创建时的xts对象,它有一个(int !!)数据向量,但您将其强制转换为xtsIndexNumericMatrix--> 所以“事情发生了”。我同意副作用是不可取的,但你也必须对类型更加小心。 -
Rcpp Gallery 文章中的函数可能是使用旧的 Date(time) 类编写的,我必须检查一下。一个更简单的版本是
cppFunction("SEXP xtsIndex(NumericMatrix X) { SEXP s = X.attr(\"index\"); return s; } "),它应该避免额外的转换并使用日期和日期时间索引对象。 -
@DirkEddelbuettel 我刚刚测试了您建议的修复程序,我得到了相同的
'%/%' not defined for "POSIXt" objects错误。但感谢您的快速关注。 -
我完成了定义该函数的顺序,然后是相同的
xx <- xts(1:10, order.by = seq.Date(Sys.Date(), by = "day", length.out = 10)),然后是xtsIndex(xx),然后xx仍然打印为xts对象。 -
@DirkEddelbuettel 是的,它有效。请张贴作为答案,我会投票。我仍然不明白到底出了什么问题?