Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Suppress messages from underlying C-function in R

In a script I often call the function Rcplex(), which prints "CPLEX environment opened" and "Closed CPLEX environment" to the console. Since the function is called rather frequently, it prints this very often, which is quite annoying. Is there a way to suppress this? I tried sink(), suppressWarnings/Messages or invisible(catch.output()) but none of these did the trick. I proceeded to check the code of Rcplex() and found where the printing to the console happens. Rcplex() calls an underlying C-function (Rcplex.c). In the code of rcplex.c I located the commands which cause the printing:

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

Is there a way to capture the output from REprintf() so that it does not get printed to the R-console? One way would obviously be to mess around with the Rcplex.c file and delete the corresponding lines. However, this would not be a very clean solution, which is why I'm asking for another way to capture the output from C-functions.

like image 655
YukiJ Avatar asked Apr 06 '18 14:04

YukiJ


1 Answers

You had problems using sink() and capture.output() normally because sink() does not redirect output from REprintf, as we see in comments from the source code for 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().

However, we can use type = "message" to deal with this; from help("capture.output"):

Messages sent to stderr() (including those from message, warning and stop) are captured by type = "message". Note that this can be "unsafe" and should only be used with care.

First I make a C++ function with the same behavior you're dealing with:

#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;
}

If I call it from R normally, I get:

example_function(42)

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

However, I could instead do this:

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

[1] 42

And while the output is is printed to the console, the message is not.

Warning

I would be remiss if I didn't mention the warning from the help file I quoted above:

Note that this can be "unsafe" and should only be used with care.

The reason is that this will eliminate all output from actual errors as well. Consider the following:

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

You may or may not want to therefore send the captured output to a text file in case you have to diagnose something that went wrong. For example:

invisible(capture.output(log("A"), type = "message", file = "example.txt"))

Then I don't have to see the message in the console, but if I need to check example.txt afterward, the message is there:

Error in log("A") : non-numeric argument to mathematical function
like image 148
duckmayr Avatar answered Oct 20 '22 18:10

duckmayr