对R的子顺序C调用不起作用

时间:2016-08-15 23:34:53

标签: c++ r

我正在编写一个c ++函数,它接受一个R调用并对其进行求值。每当我通过一次调用编译时,函数就会按预期返回。 但是当我对我的函数进行子顺序调用时,它会在运行目标文件时卡住。

如何在单个函数调用后重新实例化R实例? 当有两次调用我的函数时,下面的方法会被卡住,但是当我打一个电话时工作正常。

int main(int argc, char* argv[]){

double result1 = calculateScalar(input2);
std::cout << "Result 1 " << result1;


double result2 = calculateScalar(input2);
std::cout << "Result 2 " <<result2;
return 0;
}


double calculateScalar(const char* RCALL){
     SEXP formula, result;
     ParseStatus status;
     R_xlen_t len;
     int errorStatus;

    try {
        Rf_initEmbeddedR(0, NULL);

        Rf_protect(formula = mkString(RCALL));

        Rf_protect(formula = R_ParseVector(formula, 1, &status, R_NilValue));



       result = R_tryEval(VECTOR_ELT(formula,0), R_GlobalEnv, &errorStatus);
       PROTECT(result);

       len = xlength(result);


       UNPROTECT(3);
       Rf_endEmbeddedR(0);
       return (double) getNumericScalar(result);

} catch(std::exception& e){
     std::cout << "Standard exception: " << e.what();
}

//Clean up R
Rf_endEmbeddedR(0);
exit(0);
}

1 个答案:

答案 0 :(得分:2)

而不是重新发明轮子,你可以只是在里面:

edd@brad:~/git/rinside/inst/examples/standard(master)$ make rinside_sample3
ccache g++ -I/usr/share/R/include -I/usr/local/lib/R/site-library/Rcpp/include \
 -I/usr/local/lib/R/site-library/RInside/include -g -O3 -Wall -pipe -Wno-unused \
 -pedantic -Wall    rinside_sample3.cpp  -Wl,--export-dynamic -fopenmp\
 -L/usr/lib/R/lib -lR -lpcre -llzma -lbz2 -lz -lrt -ldl -lm \
 -lblas -llapack  -L/usr/local/lib/R/site-library/RInside/lib -lRInside \
 -Wl,-rpath,/usr/local/lib/R/site-library/RInside/lib -o rinside_sample3
edd@brad:~/git/rinside/inst/examples/standard(master)$ 

this simple source file构建它(自动使用自动化的`GNUmakefile)。

运行它会产生:

edd@brad:~/git/rinside/inst/examples/standard(master)$ ./rinside_sample3 

Call:
lm(formula = Fertility ~ ., data = swiss)

Residuals:
     Min       1Q   Median       3Q      Max 
-15.2743  -5.2617   0.5032   4.1198  15.3213 

Coefficients:
                 Estimate Std. Error t value Pr(>|t|)    
(Intercept)      66.91518   10.70604   6.250 1.91e-07 ***
Agriculture      -0.17211    0.07030  -2.448  0.01873 *  
Examination      -0.25801    0.25388  -1.016  0.31546    
Education        -0.87094    0.18303  -4.758 2.43e-05 ***
Catholic          0.10412    0.03526   2.953  0.00519 ** 
Infant.Mortality  1.07705    0.38172   2.822  0.00734 ** 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 7.165 on 41 degrees of freedom
Multiple R-squared:  0.7067,    Adjusted R-squared:  0.671 
F-statistic: 19.76 on 5 and 41 DF,  p-value: 5.594e-10



And now from C++

                       Estimate      Std. Error         t value        Pr(>|t|)
     (Intercept)        66.9152          10.706         6.25023     1.90605e-07
     Agriculture      -0.172114       0.0703039        -2.44814       0.0187272
     Examination      -0.258008        0.253878        -1.01627        0.315462
       Education       -0.87094        0.183029        -4.75849      2.4306e-05
        Catholic       0.104115       0.0352579         2.95297      0.00519008
Infant.Mortality        1.07705         0.38172         2.82157      0.00733572

edd@brad:~/git/rinside/inst/examples/standard(master)$ 

有几点需要注意:

  • 我选择了这个例子(在包中的其他几十个中),因为它在C ++代码中包含多个eval...()调用。
  • 它也很可爱,因为它为你重做lm()
  • make rinside_sample3之后的实际编译因系统而异;在我看来它反映了我在~/.R/Makevars
  • 中设置的一些参数
  • 我手动将显示屏缩小四个空格以使其适合。