Как перейти от использования C++ со встроенными функциями к созданию собственного пакета R?

Здесь происходит две вещи:(1 )Я только изучаю, как использовать Rcpp и друзей, чтобы сделать мой код R быстрее, и (2 )Я никогда раньше не создавал R-пакет.

У меня есть использование inline. Отличный пакет. Любить это. Однако я не могу использовать какой-либо код, разработанный с помощью inlineс package.skeleton, для создания пакета R.

Вот минимальный пример:

Шаг 1 :Создайте сценарий R

#############################
# File : build-R-pacakge.R  #
#############################
require(inline)
require(Rcpp)
require(RcppArmadillo)

# Define a simple cxxfunction
plus.two.cpp.src <- '
    arma::mat U = Rcpp::as(UmatrixR);
    return(Rcpp::wrap(U+2));
'
plus.two.cpp <- cxxfunction(
             signature(UmatrixR="numeric"),
             body=plus.two.cpp.src,
             plugin="RcppArmadillo")

# Define the analogous R function
plus.two.r <- function( x ) {
  return( x + 2 )
}

Шаг 2 :Создайте его как пакет R

В новом сеансе R запустите:

source('build-R-package.R')
RcppArmadillo.package.skeleton(name='inlineExample',
                 list=c('plus.two.cpp', 'plus.two.r'),
                 code_files='build-R-package.R')

Затем удалите файлы man/*.Rd, поскольку R не устанавливает значения по умолчанию, которые «просто работают».

$ rm inlineExample/man/*.Rd

И беги:

$ R CMD build inlineExample/
<< snip >> 
$ R CMD check inlineExample_1.0.tar.gz 
<< snip >>
$ R CMD INSTALL inlineExample_1.0.tar.gz 
<< snip >>

Которые все завершаются успешно, за исключением некоторых жалоб на недостающую документацию.

Шаг 3 :Попробуйте

А затем попробуйте в новом сеансе R :

> require(inlineExample)
Loading required package: inlineExample
Loading required package: Rcpp
Loading required package: RcppArmadillo
Loading required package: inline
>
> plus.two.cpp( matrix(1:12, ncol=3))
Error in.Primitive(".Call")(, UmatrixR) : 
  NULL value passed as symbol address
>
> plus.two.cpp
An object of class "CFunc"
function (UmatrixR) 
.Primitive(".Call")(, UmatrixR)

Slot "code":
[1] "\n// includes from the plugin\n#include \n#include \n\n\n#ifndef BEGIN_RCPP\n#define BEGIN_RCPP\n#endif\n\n#ifndef END_RCPP\n#define END_RCPP\n#endif\n\nusing namespace Rcpp;\n\n\n// user includes\n\n\n// declarations\nextern \"C\" {\nSEXP file2f8c4cc10657( SEXP UmatrixR) ;\n}\n\n// definition\n\nSEXP file2f8c4cc10657( SEXP UmatrixR ){\nBEGIN_RCPP\n\n  arma::mat U = Rcpp::as(UmatrixR);\n  return(Rcpp::wrap(U+2));\n\nEND_RCPP\n}\n\n\n"

. Это терпит неудачу. На мой неопытный взгляд кажется, что:

  1. код, который inlineскомпилировал, никогда не копировался *.package.skeleton в «правую» часть скелета каталога для последующей компиляции в процессе сборки R, и
  2. если аргумент 'code _files' не приводит к тому, что R будет использовать эти файлы *.R при загрузке пакета.

Размышляя об этом дальше, кажется, что (2 )было бы очень плохой идеей, потому что это заставит пользователя компилировать код каждый раз, когда он загружает свой пакет. Это исключит всех пользователей, которым требуются только бинарные пакеты, и просто будет очень неэффективно.

И (1 )кажется технически возможным, но, как обсуждалось в списке рассылки Rcpp , не стоит реализовывать набор функций автоматического -магического конвертера.

Так,вопрос:

Может ли кто-нибудь рассказать -о том, как правильно взять предоставленный пример кода и превратить его в пакет R?

Для меня слишком много новизны, чтобы разобраться в существующей документации. FWIW, я уверен, что это будет полезно для людей в будущем!

9
задан Benjamin 29 July 2014 в 16:56
поделиться