通过从 C/C++ 替换 R 控制台中的输出来创建进度更新 [英] Creating a progress update by replacing output in the R console from C/C++

查看:41
本文介绍了通过从 C/C++ 替换 R 控制台中的输出来创建进度更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以使用 R 的 C/C++ 打印函数覆盖 R 控制台输出?

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()

这个函数的输出是

number: 0number: 1number: 2number: 3number: 4number: 5number: 6number: 7number: 8number: 9

但我希望它是一个动态序列.例如:

but I want it to be a dynamic sequence. For example:

number: 0

等几秒钟:

number: 1

其中 number: 0 从控制台中完全删除.重复此过程,直到达到 number: 9.

where number: 0 is completely erased from the console. This procedure repeats until number: 9 is reached.

我看过这个问题,但我没有能够让回车解决方案与 REprintf() 一起使用.

I've seen this question, but I was not able to get the carriage return solution to work with REprintf().

推荐答案

要正确更新 R 控制台,您需要使用 Rinterfaces.h 标题.此标头仅适用于类 Unix 系统.因此,您的进度更新将在 Windows 上中断.

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.

特别是,您应该将 REprintf(标准错误)或 Rprintf(标准输出)与 R_FlushConsole 结合使用来更新控制台.这里的关键是用 "\r" 或回车符包围输出,这会强制返回到行的开头.这将导致您的值被打印,然后前一行被擦除".

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."

在此过程中,检查用户中断可能是有利的(例如,如果用户按下退出键,则退出进程).因此,我包含了对 R_CheckUserInterrupt() 的调用.

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();
  }

}

示例:

这篇关于通过从 C/C++ 替换 R 控制台中的输出来创建进度更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆