如何在 64 位向量中将 NA 值从 Rcpp 传递给 R?
我的第一种方法是:
// [[Rcpp::export]]
Rcpp::NumericVector foo() {
Rcpp::NumericVector res(2);
int64_t val = 1234567890123456789;
std::memcpy(&(res[0]), &(val), sizeof(double));
res[1] = NA_REAL;
res.attr("class") = "integer64";
return res;
}
但它产生
#> foo()
integer64
[1] 1234567890123456789 9218868437227407266
我需要得到
#> foo()
integer64
[1] 1234567890123456789 <NA>
最佳答案
好吧,我想我找到了答案......(不漂亮,但有效)。
简答:
// [[Rcpp::export]]
Rcpp::NumericVector foo() {
Rcpp::NumericVector res(2);
int64_t val = 1234567890123456789;
std::memcpy(&(res[0]), &(val), sizeof(double));
# This is the magic:
int64_t v = 1ULL << 63;
std::memcpy(&(res[1]), &(v), sizeof(double));
res.attr("class") = "integer64";
return res;
}
这导致
#> foo()
integer64
[1] 1234567890123456789 <NA>
更长的答案
检查
bit64
如何存储 NA
# the last value is the max value of a 64 bit number
a <- bit64::as.integer64(c(1, 2, NA, 9223372036854775807))
a
#> integer64
#> [1] 1 2 <NA> <NA>
bit64::as.bitstring(a[3])
#> [1] "1000000000000000000000000000000000000000000000000000000000000000"
bit64::as.bitstring(a[4])
#> [1] "1000000000000000000000000000000000000000000000000000000000000000"
由 reprex package (v0.3.0) 于 2020-04-23 创建
我们看到它是一个
10000...
。这可以在 Rcpp
中使用 int64_t val = 1ULL << 63;
重新创建。使用 memcpy()
而不是带有 =
的简单赋值可确保不会更改任何位!
关于Rcpp 和 int64 NA 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61386279/