在R

时间:2018-04-06 14:00:08

标签: c r console printf output

在脚本中,我经常调用函数Rcplex(),它将“CPLEX环境已打开”和“已关闭的CPLEX环境”打印到控制台。由于该函数被频繁调用,因此它经常打印,这非常烦人。有没有办法压制这个?我尝试了sink()suppressWarnings/Messagesinvisible(catch.output()),但这些都没有成功。我继续检查Rcplex()的代码,找到了打印到控制台的位置。 Rcplex()调用底层C函数(Rcplex.c)。在code of rcplex.c我找到了导致打印的命令:

    REprintf("CPLEX environment opened\n");
    REprintf("Closed CPLEX environment\n");

有没有办法从REprintf()捕获输出,以便它不会被打印到R控制台?显然,一种方法是弄乱Rcplex.c文件并删除相应的行。但是,这不是一个非常干净的解决方案,这就是为什么我要求另一种方法来捕获C函数的输出。

1 个答案:

答案 0 :(得分:9)

您在使用sink()capture.output()时遇到问题,因为sink()不会重定向REprintf的输出,正如source codejson-parse-or的评论中所见{1}}:

REprintf

但是,我们可以使用/* ========= * Printing: * ========= * * All printing in R is done via the functions Rprintf and REprintf * or their (v) versions Rvprintf and REvprintf. * These routines work exactly like (v)printf(3). Rprintf writes to * ``standard output''. It is redirected by the sink() function, * and is suitable for ordinary output. REprintf writes to * ``standard error'' and is useful for error messages and warnings. * It is not redirected by sink(). 来处理这个问题;来自type = "message"

  

发送到stderr()的消息(包括来自消息,警告和消息的消息)   停止)由type =“message”捕获。请注意,这可能是“不安全的”,只应谨慎使用。

首先,我使用您正在处理的相同行为制作C ++函数:

help("capture.output")

如果我通常从R调用它,我会得到:

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
NumericVector example_function(NumericVector x) {
    REprintf("CPLEX environment opened\n");
    REprintf("Closed CPLEX environment\n");
    // As mentioned by Dirk Eddelbuettel in the comments,
    // Rcpp::Rcerr goes into the same REprintf() stream:
    Rcerr << "Some more stuff\n";
    return x;
}

但是,我可以这样做:

example_function(42)

CPLEX environment opened
Closed CPLEX environment
Some more stuff
[1] 42

当输出打印到控制台时,消息不是。

警告

如果我没有提到上面引用的帮助文件中的警告,那将是我的疏忽:

  

请注意,这可能是“不安全的”,只能小心使用。

原因是这将消除实际错误的所有输出。请考虑以下事项:

invisible(capture.output(example_function(42), type = "message"))

[1] 42

您可能希望也可能不希望将捕获的输出发送到文本文件,以防您必须诊断出错的地方。例如:

> log("A")
Error in log("A") : non-numeric argument to mathematical function
> invisible(capture.output(log("A"), type = "message"))
> 

然后我不必在控制台中看到该消息,但如果我之后需要检查invisible(capture.output(log("A"), type = "message", file = "example.txt")) ,那么消息就在那里:

example.txt