打印Rcpp类的通用

问题描述 投票:1回答:1

我有一些问题为Rcpp类编写R通用打印机。想想http://dirk.eddelbuettel.com/code/rcpp/Rcpp-modules.pdf第8页的Uniform示例。我试图定义这样的通用:

# Create new Uniform object:
uniform = Uniform$new(1, 2)
class(uniform)

## [1] "Rcpp_Uniform"
## attr(,"package")
## [1] "uniform"


# Printer for the object:
print.Rcpp_Uniform = function (x, ...) { message("Hi, I am an uniform object") }

现在,如果我输入uniform,我得到:

C++ object <000000000d825c80> of class 'Uniform' <000000000287b090>

但这是我试图避免的。直接调用打印机可以提供我喜欢的内容:

print(uniform)
## Hi, I am an uniform object

有没有办法直接使用自定义打印机而不调用打印功能?

r printing rcpp
1个回答
2
投票

感谢德克斯提示我有一个解决方案。这是cpp文件uniform.cpp,它包含统一类(复制了Dirks Rcpp Modules文档)和Rcpp模块定义:

// BEGIN uniform.cpp

#include <Rcpp.h>

using namespace Rcpp;

class Uniform {
public:
  Uniform(double min_, double max_) : min(min_), max(max_) {}
  NumericVector draw(int n) const {
    RNGScope scope;
    return runif( n, min, max );
  }
  double min, max;
};
double uniformRange( Uniform* w) {
  return w->max - w->min;
}
RCPP_MODULE(unif_module) {
  class_<Uniform>( "Uniform" )
  .constructor<double,double>()
  .field( "min", &Uniform::min )
  .field( "max", &Uniform::max )
  .method( "draw", &Uniform::draw )
  .method( "range", &uniformRange )
  ;
}

// END uniform.cpp

现在可以获取并使用它:

library(Rcpp)
## Warning: package 'Rcpp' was built under R version 3.4.3

sourceCpp(file = "uniform.cpp")

uniform = Uniform$new(0, 10)

# Default printer:
uniform
## C++ object <00000000137a2e90> of class 'Uniform' <0000000015256dc0>

class(uniform)
## [1] "Rcpp_Uniform"
## attr(,"package")
## [1] ".GlobalEnv"

现在的线索是将方法show定义为S4类Rcpp_Uniform的自定义打印机。之后打印机完成所需的操作:

setMethod("show", class(uniform), function (object) {
  cat("\n Hi, I am an uniform object!\n")
  cat("\n I was initialized with a minimum value of", object$min)
  cat("\n and a maximum value of ", object$max, ".\n", sep = "")
  cat("\n Therefore my range is ", object$range(), ".", sep = "")
  cat("\n\n")
})
## [1] "show"

uniform
## 
##  Hi, I am an uniform object!
## 
##  I was initialized with a minimum value of 0
##  and a maximum value of 10.
## 
##  Therefore my range is 10.

Use in Package

要在将C++类暴露到包中的R之后将该打印机作为默认打印机,只需创建一个R文件(例如R/uniform_printer.R)并将以下代码放入其中:

setMethod("show", "Rcpp_Uniform", function (object) {
  cat("\n Hi, I am an uniform object!\n")
  cat("\n I was initialized with a minimum value of", object$min)
  cat("\n and a maximum value of ", object$max, ".\n", sep = "")
  cat("\n Therefore my range is ", object$range(), ".", sep = "")
  cat("\n\n")
})

请注意,有必要通过字符串(此处为qazxsw poi)显式引用该类。

这里的一个缺点是,这将在构建包时抛出警告,因为在构建包时没有该类的定义。如果在获取cpp文件之前从上面运行Rcpp_Uniform函数,则会发生相同的警告。

要避免这种警告的一点是在setMethod前设置一个类。这看起来像这样:

setMethod

老实说,我不知道这是多么合适。但它在一个包中工作正常。

© www.soinside.com 2019 - 2024. All rights reserved.