首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从C中计算R命令不起作用

从C中计算R命令不起作用
EN

Stack Overflow用户
提问于 2015-11-26 13:51:21
回答 2查看 102关注 0票数 0

我试着做一个简单的R命令评估器。

我有以下代码:

Evaluator.h

代码语言:javascript
复制
void evaluate(const std::string &command);

extern "C" SEXP run_eval() {
  evaluate("grDevices:::png(\"snapshot.png\")");

  return R_NilValue;
}

Evaluator.cpp

代码语言:javascript
复制
SEXP createSexp(const std::string &str, ScopeProtector *protector) {
  SEXP result = Rf_allocVector(STRSXP, 1);

  protector->add(result);

  SET_STRING_ELT(result, 0, Rf_mkChar(str.c_str()));

  return result;
}

SEXP createExpressionSexp(SEXP strSexp, ScopeProtector *protector) {
  ParseStatus status;

  SEXP result = R_ParseVector(strSexp, 1, &status, R_NilValue);

  protector->add(result);

  return result;
}

SEXP createExpressionSexp(const std::string &str, ScopeProtector *protector) {
  return createExpressionSexp(createSexp(str, protector), protector);
}

SEXP evaluateExpression(SEXP exprSexp, ScopeProtector *protector) {
  SEXP result = Rf_eval(exprSexp, R_GlobalEnv);

  protector->add(result);

  return result;
}

void evaluate(const std::string &command) {
  ScopeProtector protector;

  evaluateExpression(createExpressionSexp(command, &protector), &protector);
}

ScopeProtector.h

代码语言:javascript
复制
class ScopeProtector: boost::noncopyable {
 public:
  ScopeProtector();

  virtual ~ScopeProtector();

  void add(SEXP sexp);

 private:
  class Impl;

  const std::unique_ptr<Impl> pImpl;
};

ScopeProtector.cpp

代码语言:javascript
复制
class ScopeProtector::Impl {
 public:
  Impl() : count(0) {
  }

  virtual ~Impl() {
    if (count > 0) {
      UNPROTECT(count);
    }
  }

  void add(SEXP sexp) {
    PROTECT(sexp);
    count++;
  }

 private:
  int count;
};

ScopeProtector::ScopeProtector() : pImpl(new Impl) {
}

ScopeProtector::~ScopeProtector() = default;

void ScopeProtector::add(SEXP sexp) {
  pImpl->add(sexp);
}

CMakeLists.txt

代码语言:javascript
复制
cmake_minimum_required(VERSION 3.3)
project(REvaluator)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Werror")

include_directories("/usr/share/R/include")

set(
        SOURCE_FILES
        Evaluator.cpp Evaluator.h
        ScopeProtector.cpp ScopeProtector.h
)

add_library(revaluator SHARED ${SOURCE_FILES})

我试图通过执行以下命令来检查我的评估器:

代码语言:javascript
复制
> dyn.load("librevaluator.so")
> .Call("run_eval")
NULL
> dev.list()
NULL

如您所见,没有任何png设备。你能告诉我问题出在哪里吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-11-27 16:42:25

我找到了解决办法。只需替换

代码语言:javascript
复制
SEXP result = Rf_eval(exprSexp, R_GlobalEnv);

使用

代码语言:javascript
复制
SEXP result = Rf_eval(VECTOR_ELT(exprSexp, 0), R_GlobalEnv);
票数 0
EN

Stack Overflow用户

发布于 2015-11-26 17:52:42

你看过Rcpp和它的Rcpp::Function()吗?

代码语言:javascript
复制
R> library(Rcpp)
R> dev.list()
NULL
R> cppFunction('void newDev(std::string filename) { 
        Rcpp::Function dn = Rcpp::Function("png"); 
        dn(filename); }')
R> newDev("/tmp/foo.png")
R> dev.list()
png 
  2 
R> 

我们通常不建议从“在C++中自下而上”调用大量的R函数,但是对于像创建图形设备这样的八层设置问题来说,这是非常好的。

(注意,我缩进代码以适应这里的显示。cppFunction()是一行;它创建一个具有参数中定义的函数的共享库,并分配它--这样我们刚才创建的新的R调用方newDev就可以用来创建png设备)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33940409

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档