简体   繁体   English

使用 Roxygen2 记录 R6 类方法

[英]Documenting R6 class methods with Roxygen2

I'm writing a package with an R6 class that has several methods.我正在编写一个带有多个方法的 R6 类的包。 I would like to be able to generate documentation for both, class and methods.我希望能够为类和方法生成文档。 For the below example, I would like to be able to access the docs with ?Person for the class and ?set_hair , for the method.对于下面的示例,我希望能够使用?Person访问该类的文档,并使用?set_hair访问该方法的文档。 Here my example class:这是我的示例类:

#' This is my Person class
#' @title Person Class
#' @docType class
#' @description Person class description
#' @field name Name of the person
#' @field hair Hair colour
#'
#' @section Methods:
#' \describe{
#' \item{set_hair Set the hair color}
#' }
#' 
#' @examples
#' Person$new(name="Bill", hair="Blond")
#' @export
Person <- R6::R6Class("Person",
  public = list(
    name = NULL,
    hair = NULL,
    initialize = function(name = NA, hair = NA) {
      self$name <- name
      self$hair <- hair
  },    

    # '@name set_hair
    # '@param val: hair colour
    set_hair = function(val) {
      self$hair <- val
  },
  )
)

Running roxygenise() , the annotations above the method bodies are not rendered at all, so the only information I specify in @section Methods is in the docs.运行roxygenise() ,方法主体上方的注释根本没有呈现,所以我在@section Methods中指定的唯一信息是在文档中。

Since I have over 50 class methods, it would be much nicer if I can access the method docs with ?methodname sepeartly.由于我有 50 多个类方法,如果我可以使用?methodname methodname 单独访问方法文档会更好。 I found some some posts on this ( Documenting R6 classes and methods within R package in RStudio , https://github.com/klutometis/roxygen/issues/306 ), but it seems to me that this is not supported for R6 classes.我发现了一些关于此的帖子( 在 RStudio 中记录 R 包中的 R6 类和方法https://github.com/klutometis/roxygen/issues/306 ),但在我看来,这不适用于 R6 类。

What would be the best way to document my class methods separately?分别记录我的类方法的最佳方法是什么?

The discussion on the github-raised issue linked in user2554330's comment above indicates that separated out documentation is not something on the to-do list for roxygen, as it does not match traditional style for method documentation.上面 user2554330 的评论中链接的关于 github 引发的问题的讨论表明,分离出的文档不是 roxygen 的待办事项列表中的内容,因为它与方法文档的传统风格不匹配。 That said, I've still found it useful, and have been using a workaround.也就是说,我仍然发现它很有用,并且一直在使用解决方法。

One partial solution is to create functional wrappers.一种部分解决方案是创建功能性包装器。 This is a semi-manual process that can be cumbersome given lots of methods (as in your case), but it does enable clear and semi-automated documentation for R6 methods in separate docs.这是一个半手动过程,在有很多方法的情况下可能很麻烦(如您的情况),但它确实在单独的文档中为 R6 方法提供了清晰的半自动文档。 Using the person example, here is the would-be implementation of a document-able wrapper in roxygen2:使用person示例,这里是 roxygen2 中可文档包装器的可能实现:

#` Method for setting hair
#` 
#` @param person a person class object
#` @param val hair color
#` 
#` @return nothing; modifies \code{person}
#` @export
#` 
#` @examples
#` bill <- Person$new(name="Bill", hair="Blond")
#` bill$set_hair("InspiredRed")
#` bill$hair
#` set_hair(bill, "MetalBlack")
#` bill$hair
set_hair <- function(person, val){
  person$set_hair(val)
  invisible()
}

The result would be two separate .Rd files, one for the person class, and one for the set_hair method, both accessible with ?结果将是两个单独的.Rd文件,一个用于person类,另一个用于set_hair方法,都可以通过? . .

The result has an added advantage in that a call closer to functional form may be preferred by most R users, since this is closer to how most R syntax is set up.结果有一个额外的优势,因为大多数 R 用户可能更喜欢更接近函数形式的调用,因为这更接近于大多数 R 语法的设置方式。 Both person$set_hair(val) and set_hair(person, val) will produce the same result without any need for explicit assignment, maintaining R6's advantages while adding minimal overhead. person$set_hair(val)set_hair(person, val)将产生相同的结果,无需任何显式赋值,保持 R6 的优势,同时增加最少的开销。


EDIT:编辑:

After bringing this up with a few people, I've anecdotally found more preference for having actual functional form wrappers--ones which sacrifice the reference component in favor of a functional approach, as it is nearer to R's "norm."在向几个人提出这个问题后,我发现更喜欢使用实际的函数形式包装器——那些牺牲参考组件而支持函数方法的包装器,因为它更接近 R 的“规范”。 In this case, the approach still provides the same documentation advantages, while referential method calls are still available via $ .在这种情况下,该方法仍然提供相同的文档优势,而引用方法调用仍然可以通过$ However, additional emphasis should be made on the existence of the referential method approach when writing the wrapper documentation.但是,在编写包装器文档时,应额外强调引用方法方法的存在。

#` Clones person and changes hair
#` 
#` @param person a person class object
#` @param val hair color
#` 
#` @return nothing; modifies \code{person}
#` @export
#` 
#` @details This creates a new person with the same characteristics as the \code{person}
#' provided, except with new hair. To update the original person's hair by reference,
#' use \code{person$set_hair()}.
#` 
#` @examples
#` bill <- Person$new(name="Bill", hair="Blond")
#` bill$set_hair("InspiredRed")
#` bill$hair
#` set_hair(bill, "MetalBlack")
#` bill$hair
set_hair <- function(person, val){
  personNew <- person.clone()
  personNew$set_hair(val)
  invisible(personNew) # invisible assuming no print method, but you probably want one
}

Of course, which route to take with these wrappers depends on your specific application's speed and memory requirements.当然,这些包装器采用哪种方式取决于您的特定应用程序的速度和内存要求。 The functional approach may create enough of a hindrance to not be viable.函数式方法可能会造成足够的障碍,使其不可行。

This is an old post and you might have solved your question long ago.这是一篇旧帖子,您可能很久以前就已经解决了您的问题。 But it's not added here so in case someone need the solution, it will be:但是这里没有添加,所以如果有人需要解决方案,它将是:

#' This is my Person class
#' @description Person class description
#' @field name Name of the person
#' @field hair Hair colour
#' 
#' @examples
#' Person$new(name="Bill", hair="Blond")
#' @export
Person <- R6::R6Class("Person",
  public = list(
    name = NULL,
    hair = NULL,

    #' @description
    #' Create a person
    #' @param name Name of the person
    #' @param hair Hair colour
    initialize = function(name = NA, hair = NA) {
      self$name <- name
      self$hair <- hair
  },    

    #' @description Set hair
    #' @param val Hair colour
    set_hair = function(val) {
      self$hair <- val
  },
  )
)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM