Rcppを勉強しようと一念発起してcxxfunction
を使ってみたのに、次のようなエラーでやる気が無くなった人は少なくないはず。
Error in compileCode(f, code, language = language, verbose = verbose) :
Compilation ERROR, function(s)/method(s) not created! Warning message:
running command 'make -f "C:/PROGRA~1/R/R-31~1.3/etc/i386/Makeconf" -f "C:/PROGRA~1/R/R-31~1.3/share/make/winshlib.mk" SHLIB_LDFLAGS='$(SHLIB_CXXLDFLAGS)' SHLIB_LD='$(SHLIB_CXXLD)' SHLIB="file************.dll" OBJECTS="file************.o"' had status 127
In addition: Warning message:
running command 'C:/PROGRA~1/R/R-31~1.3/bin/i386/R CMD SHLIB file************.cpp 2> file************.cpp.err.txt' had status 1
ただし、「********」の部分は毎回変わる一時ファイル名。
これはWindowsで、Rtoolsを導入していない・または導入しているけどパスを通していない場合に起こるようです。
通っているパスをR上で検索するには、Sys.getenv
を使います。
> Sys.getenv()["PATH"]
PATH
"C:\\Program Files\\R\\R-3.1.3\\bin\\i386;...(以下略)"
この中に、c:\Rtools\bin;c:\Rtools\gcc-4.6.3\bin;
が含まれていないなら、パスが通っていないということです(gccのバージョンは自分のフォルダを確認)。
ユーザー環境変数のPathの先頭にc:\Rtools\bin;c:\Rtools\gcc-4.6.3\bin;
を加えて、Rを再起動します(設定方法は、たとえばこちらを参照)。
再度Sys.getenv
を用いて、結果の中にRtools関係が含まれていれば成功です。
> Sys.getenv()["PATH"]
PATH
"C:\\Program Files\\R\\R-3.1.3\\bin\\i386;(中略);c:\\Rtools\\bin;c:\\Rtools\\gcc-4.6.3\\bin;(以下略)"
うまくいきました。
library(inline)
g <- cxxfunction(signature(vs = "numeric"), plugin = "RcppArmadillo",
body = '
arma::vec v = Rcpp::as<arma::vec>(vs);
arma::mat op = v * v.t();
double ip = arma::as_scalar(v.t() * v);
return Rcpp::List::create(Rcpp::Named("outer") = op,
Rcpp::Named("inner") = ip);'
)
g(7:11)
# > g(7:11)
# $outer
# [,1] [,2] [,3] [,4] [,5]
# [1,] 49 56 63 70 77
# [2,] 56 64 72 80 88
# [3,] 63 72 81 90 99
# [4,] 70 80 90 100 110
# [5,] 77 88 99 110 121
#
# $inner
# [1] 415