2012-06-21 19 views
2

我想创建某种结构来减少我在R文件中调用的参数数量。在R中使用结构减少参数数目C使用C

在我的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文件中的参数。由于所需的参数数量可能会增加,因此代码的人工可读性将大大降低。

+0

列表会做你想要什么。和data.frame一样。 –

+0

以及如何从C中的列表中读取? – Manolete

+0

这是我没有做的事情,但它是可能的。德克Eddelbuettel Rcpp似乎流行。 –

回答

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 
} 
+0

我正在开发一个包,如果我使用你的库,还需要安装你的包才能执行我的包?它会成为依赖吗? – Manolete

+0

是的,Rcpp是一个依赖项。超过60个其他CRAN软件包依赖于它 - 而RcppExamples也是一个例子,因为它取决于Rcpp。 –