2

Rファイルからの呼び出しに含まれるパラメーターの数を減らすために、ある種の構造を作成したいと思います。

私のRファイル(example.R)には次のようなものがあります:

  ret <- .Call("example", 

        ## data
    as.double  (t(x)),
    as.integer (nr), 
    as.integer(ncol(x)),
    as.double  (y),
    as.integer (nclass),
    as.integer (cross),
        .....
)

そして、私のインターフェイス C ファイルは次のようになります。

SEXP example(SEXP x, SEXP rows, SEXP cols, 
      SEXP y, SEXP nclass, SEXP cross, SEXP sp_rows)
{
  PROTECT( x      = AS_NUMERIC( x      ) );
  PROTECT( y      = AS_NUMERIC( y      ) );

  PROTECT( cross  = AS_INTEGER( cross  ) );
  PROTECT( rows   = AS_INTEGER( rows   ) );
  PROTECT( cols   = AS_INTEGER( cols   ) );
  PROTECT( nclass = AS_INTEGER( nclass ) );
  PROTECT( sp_rows  = AS_INTEGER( sp_rows  ) );

  x_matrix = NUMERIC_POINTER(x);
  y_vector = NUMERIC_POINTER(y);

  int num_rows = INTEGER_VALUE(rows);
  .....

アイデアは、.R ファイルにある種の構造を作成して、.C ファイルのパラメーターを読み取ることができるようにすることです。必要なパラメーターの数が増える可能性があるため、コードの可読性が大幅に低下します。

4

1 に答える 1

3

RcppExamplesパッケージの例を次に示します。

RcppExport SEXP newRcppParamsExample(SEXP params) {

    try {                                       // or use BEGIN_RCPP macro

        Rcpp::List rparam(params);              // Get parameters in params.
        std::string method   = Rcpp::as<std::string>(rparam["method"]);
        double tolerance     = Rcpp::as<double>(rparam["tolerance"]);
        int    maxIter       = Rcpp::as<int>(rparam["maxIter"]);
        Rcpp::Date startDate = Rcpp::Date(Rcpp::as<int>(rparam["startDate"])); 

        Rprintf("\nIn C++, seeing the following value\n");
        Rprintf("Method argument    : %s\n", method.c_str());
        Rprintf("Tolerance argument : %f\n", tolerance);
        Rprintf("MaxIter argument   : %d\n", maxIter);
        Rprintf("Start date argument: %04d-%02d-%02d\n",
                startDate.getYear(), startDate.getMonth(), startDate.getDay());

        return Rcpp::List::create(Rcpp::Named("method", method),
                                  Rcpp::Named("tolerance", tolerance),
                                  Rcpp::Named("maxIter", maxIter),
                                  Rcpp::Named("startDate", startDate),
                                  Rcpp::Named("params", params));  

    } catch( std::exception &ex ) {             // or use END_RCPP macro
        forward_exception_to_r( ex );
    } catch(...) {
        ::Rf_error( "c++ exception (unknown reason)" );
    }
    return R_NilValue; // -Wall
}

Rからの一致する呼び出しは次のとおりです。

RcppParamsExample <- function(params,
                              api=c("classic", "new")) {

    api <- match.arg(api)               # match to classic or new
    fun <- paste(api, "RcppParamsExample", sep="")

    ## Check that params is properly set.
    if (missing(params)) {
        cat("\nIn R, setting default argument for params\n")
        params <- list(method='BFGS',
                       tolerance=1.0e-8,
                       maxIter=1000,
                       startDate=as.Date('2006-7-15'))
    }

    ## Make the call...
    val <- .Call(fun,
                 params,
                 PACKAGE="RcppExamples")

    val
}
于 2012-06-21T14:09:55.297 に答える