Rcpp内で日付(Date)を取り扱う

Rcpp内でDate型を取り扱いたいときにはDateVectorクラスを使用する。
ただ、

によると、Rcpp内で日付を扱うためのDateVectorクラスはそのうちdeprecatedになるらしいが、まぁ、まだあるので使う。

このベクトルの各要素はDateクラスのオブジェクトになっているので、そこは適当にこのドキュメントを見てこいつらを使ってやる。

例1

ためしに「引数として渡したDateのベクトルの日付(8月17日なら17)数分だけ日付を進めた日付ベクトル」をlistとして返すコードを書いてやると、

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
List sample1(DateVector x) {
  List result(x.size());
  for(int i = 0; i < x.size(); ++i){
    DateVector date(x[i].getDay());
    for(int j = 0; j < x[i].getDay(); j++){
      date[j] = x[i] + j;
    }
    result[i] = date;
  }
  return result;
}

になる。
実際、動かしてみるとちゃんと動く。

> library("Rcpp")
> sourceCpp("hoge.cpp")
> sample1(x)
[[1]]
[1] "2016-08-28"

[[2]]
[1] "2016-08-29"

[[3]]
[1] "2016-08-30"
> sourceCpp("hoge.cpp")
> x <- Sys.Date() + 1:3
> x
[1] "2016-08-28" "2016-08-29" "2016-08-30"
> sample1(x)
[[1]]
 [1] "2016-08-28" "2016-08-29" "2016-08-30" "2016-08-31" "2016-09-01" "2016-09-02" "2016-09-03" "2016-09-04" "2016-09-05"
[10] "2016-09-06" "2016-09-07" "2016-09-08" "2016-09-09" "2016-09-10" "2016-09-11" "2016-09-12" "2016-09-13" "2016-09-14"
[19] "2016-09-15" "2016-09-16" "2016-09-17" "2016-09-18" "2016-09-19" "2016-09-20" "2016-09-21" "2016-09-22" "2016-09-23"
[28] "2016-09-24"

[[2]]
 [1] "2016-08-29" "2016-08-30" "2016-08-31" "2016-09-01" "2016-09-02" "2016-09-03" "2016-09-04" "2016-09-05" "2016-09-06"
[10] "2016-09-07" "2016-09-08" "2016-09-09" "2016-09-10" "2016-09-11" "2016-09-12" "2016-09-13" "2016-09-14" "2016-09-15"
[19] "2016-09-16" "2016-09-17" "2016-09-18" "2016-09-19" "2016-09-20" "2016-09-21" "2016-09-22" "2016-09-23" "2016-09-24"
[28] "2016-09-25" "2016-09-26"

[[3]]
 [1] "2016-08-30" "2016-08-31" "2016-09-01" "2016-09-02" "2016-09-03" "2016-09-04" "2016-09-05" "2016-09-06" "2016-09-07"
[10] "2016-09-08" "2016-09-09" "2016-09-10" "2016-09-11" "2016-09-12" "2016-09-13" "2016-09-14" "2016-09-15" "2016-09-16"
[19] "2016-09-17" "2016-09-18" "2016-09-19" "2016-09-20" "2016-09-21" "2016-09-22" "2016-09-23" "2016-09-24" "2016-09-25"
[28] "2016-09-26" "2016-09-27" "2016-09-28"

例2

次に、整数値としていったん受け取って、それをDateに直す方法。
これはRcppの中で単にRのas.Dateをimportして呼び出せるようにすればOK。
なんでこんな面倒なことをしないといけないのかというと、Dateクラスのオブジェクトには、数値”ベクトル”に対する加算演算子が定義されていないからだ。

#include <Rcpp.h>
using namespace Rcpp;
Function asDate("as.Date");
// [[Rcpp::export]]
List sample2(IntegerVector x, IntegerVector day) {
  List result(x.size());
  for(int i = 0; i < x.size(); ++i){
    result[i] = asDate(x[i] + seq_len(day[i]), "1970-01-01");
  }
  return result; 
}

これもちゃんと動く。

> sourceCpp("hoge.cpp")
> sample2(x, 1:3)
[[1]]
[1] "2016-08-29"

[[2]]
[1] "2016-08-30" "2016-08-31"

[[3]]
[1] "2016-08-31" "2016-09-01" "2016-09-02"