从R中的底层C函数中抑制消息

Yuk*_*kiJ 6 c console printf r output

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

    REprintf("CPLEX environment opened\n");
    REprintf("Closed CPLEX environment\n");
Run Code Online (Sandbox Code Playgroud)

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

duc*_*ayr 9

您在使用时遇到问题sink(),capture.output()通常是因为sink()没有重定向输出REprintf,正如我们在源代码的注释中所看到的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().
Run Code Online (Sandbox Code Playgroud)

但是,我们可以type = "message"用来处理这个问题; 来自help("capture.output"):

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

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

#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;
}
Run Code Online (Sandbox Code Playgroud)

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

example_function(42)

CPLEX environment opened
Closed CPLEX environment
Some more stuff
[1] 42
Run Code Online (Sandbox Code Playgroud)

但是,我可以这样做:

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

[1] 42
Run Code Online (Sandbox Code Playgroud)

虽然输出打印到控制台,但消息却没有.

警告

如果我没有提到上面引用的帮助文件中的警告,我会失职:

请注意,这可能是"不安全的",只应谨慎使用.

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

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

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

invisible(capture.output(log("A"), type = "message", file = "example.txt"))
Run Code Online (Sandbox Code Playgroud)

然后我不必在控制台中看到该消息,但如果我需要在example.txt之后检查,则消息在那里:

Error in log("A") : non-numeric argument to mathematical function
Run Code Online (Sandbox Code Playgroud)

  • @DirkEddelbuettel完成! (2认同)