我为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)
这很好用:
#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)
目前看来,这个 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)