Roxygen2: documenting S3 class used as S4 when overloading R base function (cor)

房东的猫 提交于 2020-01-11 11:15:09

问题


I have the following context:

I do overload cor base function so that I have in my package .R file following statement:

#'export
setGeneric("cor")

Now I want to create a specific function for my objects (class named stranger) -- here for simplicity I just consider my object is a data.table with an additional column named .id.

#' Correlation for stranger objects
#' describeIn cor Correlation method for stranger objects.
setMethod("cor",signature(x="stranger"),function(x, method = c("pearson", "kendall", "spearman")){
  selectMethod("cor","ANY")(x[,-'.id',with=FALSE],y=NULL, use="everything",method=method)
})

If I understant setGeneric, it relies on S4 classes -- hence the signature parameter.

However, I don't use S4 classes but build my stranger object with simple old way:

buildClass <- function(x,...){
  #... prepare out object as data.table with .ìd column 
  class(out) <- c("stranger", class(out))
  return(out)
}

That is, I don't have S4 classes for my object. Dispacthing still works: calling cor on my objects correctly apply the dedicated method.

My question is about properly documenting that with ROxygen2. Currently, when loading my functions, I encounter following message:

Updating stranger documentation
Loading stranger
Creating a generic function for 'cor' from package 'stats' in package 'stranger'
in method for 'cor' with signature 'x="stranger"': no definition for class "stranger"

I have already carefully read Hadley vignette on roxygen2 plus some questions that seem related on stackoverflow but they only deal either with classical S3 mechanism or pure S4 whereas I don't have a S4 constructor with setClass and setGeneric relies on S4.


回答1:


Rather than set an S4 generic method for cor(), you can redefine it as an S3 generic and define methods for it. To illustrate, I created an R package with only two R files, "buildClass.R", and "cor.R", reproduced below:

buildClass.R:

#' Stranger Class Constructor
#'
#' Put some details about it
#'
#' @param x an object
#'
#' @export
buildClass <- function(x){
    class(x) <- c("stranger", class(x))
    return(x)
}

cor.R

#' Cor
#'
#' Put some details about it
#'
#' @param x an object
#' @param ... other arguments
#'
#' @rdname cor
#' @export
cor <- function(x, ...) {
    UseMethod('cor', x)
}

#' @rdname cor
#' @export
cor.stranger <- function(x, ...) {
    return(1)
}

#' @rdname cor
#' @export
cor.default <- function(x, ...) {
    return(stats::cor(x, ...))
}

Then, if you load your package (named in my case "anRpackage"), the user will be warned that the package masks stats::cor, but the way cor.default() is defined, stats::cor() is called for objects that are not of class stranger:

library(anRpackage)

Attaching package: ‘anRpackage’

The following object is masked from ‘package:stats’:

    cor

set.seed(1234)
regular_mat <- matrix(rnorm(100), nrow = 25)
stranger_mat <- buildClass(regular_mat)
cor(regular_mat)

            [,1]       [,2]        [,3]       [,4]
[1,]  1.00000000  0.1531414 -0.01948986 -0.3737424
[2,]  0.15314141  1.0000000  0.17531423 -0.1752925
[3,] -0.01948986  0.1753142  1.00000000  0.4371213
[4,] -0.37374237 -0.1752925  0.43712127  1.0000000

cor(stranger_mat)
[1] 1

When checking the package with devtools::check() using the default cran = TRUE (which checks "using the same settings as CRAN uses"), no errors, warnings, or notes were raised:

> check(current.code)
Updating anRpackage documentation
Loading anRpackage
Setting env vars ----------------------------------------------------------------
CFLAGS  : -Wall -pedantic
CXXFLAGS: -Wall -pedantic
Building anRpackage -------------------------------------------------------------
'/usr/lib/R/bin/R' --no-site-file --no-environ --no-save --no-restore --quiet  \
  CMD build '/home/duckmayr/anRpackage' --no-resave-data --no-manual 

* checking for file ‘/home/duckmayr/anRpackage/DESCRIPTION’ ... OK
* preparing ‘anRpackage’:
* checking DESCRIPTION meta-information ... OK
* checking for LF line-endings in source and make files and shell scripts
* checking for empty or unneeded directories
* building ‘anRpackage_1.0.tar.gz’

Setting env vars ----------------------------------------------------------------
_R_CHECK_CRAN_INCOMING_USE_ASPELL_: TRUE
_R_CHECK_CRAN_INCOMING_           : FALSE
_R_CHECK_FORCE_SUGGESTS_          : FALSE
Checking anRpackage -------------------------------------------------------------
'/usr/lib/R/bin/R' --no-site-file --no-environ --no-save --no-restore --quiet  \
  CMD check '/tmp/RtmpTcdHJ5/anRpackage_1.0.tar.gz' --as-cran --timings  \
  --no-manual 

* using log directory ‘/tmp/RtmpTcdHJ5/anRpackage.Rcheck’
* using R version 3.4.3 (2017-11-30)
* using platform: x86_64-pc-linux-gnu (64-bit)
* using session charset: UTF-8
* using options ‘--no-manual --as-cran’
* checking for file ‘anRpackage/DESCRIPTION’ ... OK
* checking extension type ... Package
* this is package ‘anRpackage’ version ‘1.0’
* checking package namespace information ... OK
* checking package dependencies ... OK
* checking if this is a source package ... OK
* checking if there is a namespace ... OK
* checking for executable files ... OK
* checking for hidden files and directories ... OK
* checking for portable file names ... OK
* checking for sufficient/correct file permissions ... OK
* checking whether package ‘anRpackage’ can be installed ... OK
* checking installed package size ... OK
* checking package directory ... OK
* checking DESCRIPTION meta-information ... OK
* checking top-level files ... OK
* checking for left-over files ... OK
* checking index information ... OK
* checking package subdirectories ... OK
* checking R files for non-ASCII characters ... OK
* checking R files for syntax errors ... OK
* checking whether the package can be loaded ... OK
* checking whether the package can be loaded with stated dependencies ... OK
* checking whether the package can be unloaded cleanly ... OK
* checking whether the namespace can be loaded with stated dependencies ... OK
* checking whether the namespace can be unloaded cleanly ... OK
* checking loading without being on the library search path ... OK
* checking dependencies in R code ... OK
* checking S3 generic/method consistency ... OK
* checking replacement functions ... OK
* checking foreign function calls ... OK
* checking R code for possible problems ... OK
* checking Rd files ... OK
* checking Rd metadata ... OK
* checking Rd line widths ... OK
* checking Rd cross-references ... OK
* checking for missing documentation entries ... OK
* checking for code/documentation mismatches ... OK
* checking Rd \usage sections ... OK
* checking Rd contents ... OK
* checking for unstated dependencies in examples ... OK
* checking examples ... NONE
* DONE

Status: OK

R CMD check results
0 errors | 0 warnings | 0 notes


来源:https://stackoverflow.com/questions/45917501/roxygen2-documenting-s3-class-used-as-s4-when-overloading-r-base-function-cor

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