问题
Is it possible to overwrite R console output with the C/C++ print functions for R?
Rcpp::sourceCpp( code = '
#include <Rcpp.h>
// [[Rcpp::export]]
void print_test() {
for(int i = 0; i < 10; i++) {
std::stringstream strs;
strs << "number: " << i;
std::string temp_str = strs.str();
char const* char_type = temp_str.c_str();
REprintf(char_type);
}
}'
)
print_test()
The output of this function is
number: 0number: 1number: 2number: 3number: 4number: 5number: 6number: 7number: 8number: 9
but I want it to be a dynamic sequence. For example:
number: 0
Wait a few seconds:
number: 1
where number: 0
is completely erased from the console. This procedure repeats until number: 9
is reached.
I've seen this question, but I was not able to get the carriage return solution to work with REprintf().
回答1:
To get the proper updates to the R console, you will need to use the Rinterfaces.h header. This header is only available for unix-alike systems. Thus, your progress update will break on Windows.
In particular, you should use REprintf
(standard error) or Rprintf
(standard output) in combination with R_FlushConsole
to update the console. The key here is to surround output with "\r"
or a carriage return, which forces a return to the beginning of the line. This will cause your value to be printed and then the previous line to be "erased."
During this procedure, it may be advantageous to check for user interrupts (e.g. if user presses escape, exit the process). Thus, I've included a call to R_CheckUserInterrupt()
.
Lastly, to emphasize an update is happening, I've opted to slow the loop by forcing it to sleep every second or so.
#include <Rcpp.h>
// for unix-alike machines only
#if !defined(WIN32) && !defined(__WIN32) && !defined(__WIN32__)
#include <unistd.h>
#include <Rinterface.h>
#endif
// [[Rcpp::export]]
void print_test() {
int n = 10;
for(int i = 0; i < n; i++) {
#if !defined(WIN32) && !defined(__WIN32) && !defined(__WIN32__)
// Sleep for a second
usleep(1000000);
#endif
std::stringstream strs;
strs << "number: " << i;
std::string temp_str = strs.str();
char const* char_type = temp_str.c_str();
REprintf("\r");
REprintf("%s", char_type);
REprintf("\r");
#if !defined(WIN32) && !defined(__WIN32) && !defined(__WIN32__)
R_FlushConsole();
#endif
R_CheckUserInterrupt();
}
}
Example:
来源:https://stackoverflow.com/questions/47623478/creating-a-progress-update-by-replacing-output-in-the-r-console-from-c-c