Rcppおよびint64 NA値


8

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>

ビットパターンはその時点での1つであるため、NA_REALその後は使用できません。memcpyint64
Dirk Eddelbuettel

タイトルも編集します。デフォルトの64ビットNAはちょうどであるNA_realあなたの質問が何であるかされていません。
Dirk Eddelbuettel

しかし、memcpyは64ビット(sizeof(double))のみをコピーしますか?だから、res[0]64ビットから取得 valして、設定res[1] = ...の用途に次の64ビットは。結果に同意しますが、最初のコメントにはあまり従わないでください。
デビッド

1
全体のポイントは、ということであるコンテンツベクトルは、その後で少しずつint64_t単に内部「駐車」であるdoubleベクトル(別名NumericVector)。魔法の論理のコピーはありません。ジェムズはすべてのハードワークを手作業で行っています。マッピングNAを含みます。
Dirk Eddelbuettel

1
それ。です。何。私が持っています。された。やってみます。に。説明してください。たとえば、既存のNA定義のRソースを見てください。を使用していくつかのパッケージをint64見て、それらが何をするかを見てください。
Dirk Eddelbuettel

回答:


6

さて、私は答えを見つけたと思う...

簡潔な答え:

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

2020-04-23にreprexパッケージ(v0.3.0)によって作成されました

であることがわかり10000...ます。これはで再現することが可能Rcppint64_t val = 1ULL << 63;memcpy()単純な代入の代わりにを使用=すると、ビットが変更されないことが保証されます。


1
はい。いくつかのソースパッケージを見ると、#define1つのビットパターン(多くの場合、minまたはmax)をNA値として宣言するための対応するステートメントが表示されます。
Dirk Eddelbuettel

6

それは本当に、はるかに簡単です。私たちは行動の持っているint64Rでは、(複数の)アドオンされる最高のそのパッケージが提供するbit64私たちに与えinteger64S3クラスと関連付けられた動作を。

そして、NAを次のように内部的に定義します。

#define NA_INTEGER64 LLONG_MIN

そして、それだけです。Rとそのパッケージは最も重要なCコードであり、LLONG_MINそこに存在し、(ほぼ)創設者の父親にまでさかのぼります。

ここには2つのレッスンがあります。1つ目は、浮動小数点値の NaNおよびInfを定義するIEEEの拡張です。Rは、実際に道を超えて、追加NAのためにそのタイプの各。上記のほとんどの方法では、1つの特定のビットパターンを予約します。(どちらの場合も、2人のオリジナルRクリエイターのうちの1人の誕生日です。)

もう1つは、Jensがbit64パッケージと必要なすべての変換および演算子関数で行った大量の作業を賞賛することです。 NA、NaN、Infなどを含む可能性のあるすべての値をシームレスに変換することは簡単な作業ではありません。

そしてそれはあまり多くの人が知らないきちんとした話題です。私たちは今ここに記録を持っているので、あなたが質問をしてくれてうれしいです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.