Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从C+调用R函数+; 我想在我自己编译的C++代码中检查是否在R中加载了一个库包(如果不是,加载它),从那个库中调用一个函数,并将结果返回到我的C++代码中。_C++_R - Fatal编程技术网

从C+调用R函数+; 我想在我自己编译的C++代码中检查是否在R中加载了一个库包(如果不是,加载它),从那个库中调用一个函数,并将结果返回到我的C++代码中。

从C+调用R函数+; 我想在我自己编译的C++代码中检查是否在R中加载了一个库包(如果不是,加载它),从那个库中调用一个函数,并将结果返回到我的C++代码中。,c++,r,C++,R,有人能给我指出正确的方向吗?似乎有很多关于R的信息和从C++和Vis中调用R的不同方法,但是我没有确切地知道我想做什么。 谢谢。< P> >这是允许你用C++代码轻松扩展R,还有C++代码回调到R.,包中包含了例子。 也许你真正想要的是保持你的C++程序(即你拥有())/>代码>并调用R?这可以很容易地用 它允许你很容易地将R嵌入到C++应用程序中,并且对库的测试、如果需要的加载和函数调用都是非常容易做到的,并且(包括十几个)示例显示了如何使用。并且仍然可以帮助您来回获得结果 编辑:因为马丁非常

有人能给我指出正确的方向吗?似乎有很多关于R的信息和从C++和Vis中调用R的不同方法,但是我没有确切地知道我想做什么。

谢谢。

< P> >这是允许你用C++代码轻松扩展R,还有C++代码回调到R.,包中包含了例子。 也许你真正想要的是保持你的C++程序(即你拥有<代码>())/>代码>并调用R?这可以很容易地用 它允许你很容易地将R嵌入到C++应用程序中,并且对库的测试、如果需要的加载和函数调用都是非常容易做到的,并且(包括十几个)示例显示了如何使用。并且仍然可以帮助您来回获得结果

编辑:因为马丁非常友好,以官方的方式展示了一些东西,我忍不住将其与RInside附带的一个示例进行了对比。这是我曾经快速写过的东西,用来帮助在r-help上询问如何加载(投资组合优化)库并使用它的人。它满足您的要求:加载一个库,通过从C++到R的权重向量访问一些数据,部署R并返回结果。p>
// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4;  tab-width: 8; -*-
//
// Simple example for the repeated r-devel mails by Abhijit Bera
//
// Copyright (C) 2009         Dirk Eddelbuettel 
// Copyright (C) 2010 - 2011  Dirk Eddelbuettel and Romain Francois

#include <RInside.h>                    // for the embedded R via RInside

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

    try {
        RInside R(argc, argv);          // create an embedded R instance 

        std::string txt = "suppressMessages(library(fPortfolio))";
        R.parseEvalQ(txt);              // load library, no return value

        txt = "M <- as.matrix(SWX.RET); print(head(M)); M";
        // assign mat. M to NumericMatrix
        Rcpp::NumericMatrix M = R.parseEval(txt); 

        std::cout << "M has " 
                  << M.nrow() << " rows and " 
                  << M.ncol() << " cols" << std::endl;

        txt = "colnames(M)";        // assign columns names of M to ans and
        // into string vector cnames
        Rcpp::CharacterVector cnames = R.parseEval(txt);   

        for (int i=0; i<M.ncol(); i++) {
            std::cout << "Column " << cnames[i] 
                      << " in row 42 has " << M(42,i) << std::endl;
        }

    } catch(std::exception& ex) {
        std::cerr << "Exception caught: " << ex.what() << std::endl;
    } catch(...) {
        std::cerr << "Unknown exception caught" << std::endl;
    }

    exit(0);
}
<代码> /-*-模式:C++;c级缩进:4级;c-基本偏移量:4;标签宽度:8-*- // //Abhijit Bera重复r-devel邮件的简单示例 // //版权所有(C)2009德克·埃德尔布埃特尔 //版权所有(C)2010-2011德克·埃德尔布埃特尔和罗曼·弗朗索瓦 #包括//用于通过冲洗液的嵌入式R int main(int argc,char*argv[]){ 试一试{ rinsider(argc,argv);//创建一个嵌入式R实例 std::string txt=“抑制消息(库(fPortfolio))”; R.parseEvalQ(txt);//加载库,无返回值
txt=“MDirk关于RInside使生活更轻松的观点可能是正确的。但对于顽固派来说……其本质来自第8.1节和第8.2节,以及与R一起分发的示例。下面的材料涵盖了构建和评估调用;处理返回值是一个不同的(在某种意义上更容易)主题

安装程序 让我们假设一个Linux/Mac平台。首先,必须编译R,以允许链接到共享或静态R库。我使用R源代码的svn副本,在目录
~/src/R-devel
中。我切换到其他目录,称之为
~/bin/R-devel
,然后

~/src/R-devel/configure --enable-R-shlib
make -j
这将生成
~/bin/R-devel/lib/libR。因此
;也许您正在使用的任何发行版都已经有了这个功能?
-j
标志并行运行,这大大加快了构建速度

嵌入示例在
~/src/R-devel/tests/embedding
中,可以使用
cd~/bin/R-devel/tests/embedding&&make
制作。显然,这些示例的源代码非常有指导意义

代码 为了举例说明,创建一个文件
embed.cpp
。首先包括定义R数据结构的头文件和R嵌入接口;它们位于
bin/R-devel/include
,并作为主要文档。我们还有一个用于完成所有工作的函数原型

#include <Rembedded.h>
#include <Rdefines.h>

static void doSplinesExample();
Embedding
下的示例包括调用
库(样条线)
,设置命名选项,然后运行函数
example(“ns”)
。下面是执行此操作的例程

static void
doSplinesExample()
{
    SEXP e, result;
    int errorOccurred;

    // create and evaluate 'library(splines)'
    PROTECT(e = lang2(install("library"), mkString("splines")));
    R_tryEval(e, R_GlobalEnv, &errorOccurred);
    if (errorOccurred) {
        // handle error
    }
    UNPROTECT(1);

    // 'options(FALSE)' ...
    PROTECT(e = lang2(install("options"), ScalarLogical(0)));
    // ... modified to 'options(example.ask=FALSE)' (this is obscure)
    SET_TAG(CDR(e), install("example.ask"));
    R_tryEval(e, R_GlobalEnv, NULL);
    UNPROTECT(1);

    // 'example("ns")'
    PROTECT(e = lang2(install("example"), mkString("ns")));
    R_tryEval(e, R_GlobalEnv, &errorOccurred);
    UNPROTECT(1);
}
编译并运行 我们现在已经准备好把所有的东西放在一起了。编译器需要知道头和库在哪里

g++ -I/home/user/bin/R-devel/include -L/home/user/bin/R-devel/lib -lR embed.cpp
编译后的应用程序需要在正确的环境中运行,例如,正确设置R_HOME;这可以通过

根据您的雄心壮志,编写R扩展的第8节中的某些部分并不相关,例如,需要回调来实现R之上的GUI,而不是评估简单的代码块

一些细节 详细介绍一下……SEXP(S表达式)是R表示基本类型(整数、逻辑、语言调用等)的基本数据结构

    PROTECT(e = lang2(install("library"), mkString("splines")));
    R_tryEval(e, R_GlobalEnv, &errorOccurred);
生成一个符号
和一个字符串
“样条线”
,并将它们放入由两个元素组成的语言构造中。这构造了一个未计算的语言对象,大约相当于
引号(库(“样条线”))
在R中。
lang2
返回一个从R的内存池分配的SEXP,需要
PROTECT
防止垃圾收集。
PROTECT
e
指向的地址添加到保护堆栈中,当不再需要保护内存时,从堆栈中弹出该地址(使用
取消保护(1)
,向下几行)。行

    PROTECT(e = lang2(install("library"), mkString("splines")));
    R_tryEval(e, R_GlobalEnv, &errorOccurred);
尝试在R的全局环境中计算
e
erroroccurrent
如果发生错误,则设置为非0。
R\u tryEval
返回表示函数结果的SEXP,但我们在此处忽略它。因为我们不再需要分配用于存储
库(“样条线”)的内存
,我们告诉R,它不再受到保护

下一段代码类似,评估
options(example.ask=FALSE)
,但调用的构造更复杂。
lang2
创建的S表达式是一个配对列表,概念上有一个节点、一个左指针(CAR)和一个右指针(CDR)。
e
的左指针指向符号
options
e
的右指针指向配对列表中的另一个节点,其左指针为
FALSE
(右指针)
    SET_TAG(CDR(e), install("example.ask"));
PROTECT(tmp = mkString("options(example.ask=FALSE)"));
PROTECT(e = R_ParseVector(tmp, 1, &status, R_NilValue));
R_tryEval(VECTOR_ELT(e, 0), R_GlobalEnv, NULL);
UNPROTECT(2);
SEXP result;
PROTECT(result = Rf_tryEval(e, R_GlobalEnv, &errorOccurred));
// ...
UNPROTECT(1);