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 回答