如何在Rcpp中将R对象打印到stderr?

Mic*_*uhn 5 r rcpp

为R实现了一个Python风格的字典,但是当给定的键在字典中没有值时,没有找到引发错误的好方法.调用stop很简单,但我想通过打印R对象告诉用户找不到哪个键.现在我有:

Rcpp::Rcout << "Key not found: ";
Rcpp::print(key); # <-- how can I get this on stderr?
Rcpp::stop("Key error!");
Run Code Online (Sandbox Code Playgroud)

这会将消息打印到stdout,但我宁愿在stderr上使用它.可能我只是缺少Rcpp提供的功能?

这是一个MWE:

library(Rcpp)

sourceCpp(code='

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
void test(SEXP key) {
  Rcpp::print(key);
  Rcpp::Rcerr << "This does not work: " << key << std::endl;
}

/*** R
test("x")
test(c(1,2,3))
*/

')
Run Code Online (Sandbox Code Playgroud)

Rol*_*and 5

这很好用:

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
std::string test(std::string key) {
  Rcpp::Rcerr << "Key not found: "<< key << std::endl;
  Rcpp::stop("Key error!");
  return key;
}

/*** R
test("x")
*/
Run Code Online (Sandbox Code Playgroud)

输出:

Key not found: x
Error in eval(expr, envir, enclos) : Key error!
Run Code Online (Sandbox Code Playgroud)

编辑:

好的,所以你传递一个可以是单个值或向量的SEXP.我建议将其转换为字符向量:

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
void test(SEXP key) {
  CharacterVector key1 = as<CharacterVector>(key);
  Rcpp::Rcerr << "This does not work: " << key1 << std::endl;
}

/*** R
test(c("x", "y"))
test(1:3)
  */
Run Code Online (Sandbox Code Playgroud)

输出:

> Rcpp::sourceCpp('E:/temp/ttt.cpp')

> test(c("x", "y"))
This does not work: "x" "y"

> test(1:3)
This does not work: "1" "2" "3"
Run Code Online (Sandbox Code Playgroud)

  • @Roland也许只是将`switch`语句与上述逻辑混合在一起,例如[this](https://gist.github.com/nathan-russell/bb15db458ca9727ba76d#file-printerror-cpp). (2认同)

Mic*_*uhn 1

目前看来,这个 hack 是唯一的出路。这不是很高效,因为我们从 C++ 返回到 R 来获取作为漂亮字符串的值。

library(Rcpp)

sourceCpp(code='

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
void test(SEXP key, Function generate_error) {
  std::string s = as<std::string>(generate_error(key));
  stop(s);
}

/*** R

generate_error <- function(key) {
  paste("Key not found:", capture.output(print(key)))
}

try( test("x", generate_error) )
try( test(c(1,2,3), generate_error) )
*/

')
Run Code Online (Sandbox Code Playgroud)