Creating a progress update by replacing output in the R console from C/C++

六月ゝ 毕业季﹏ 提交于 2021-02-16 21:05:03

问题


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:

Progress Update



来源:https://stackoverflow.com/questions/47623478/creating-a-progress-update-by-replacing-output-in-the-r-console-from-c-c

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!