使用Roxygen2记录R6类方法

时间:2018-04-06 13:41:21

标签: r documentation roxygen2 roxygen r6

我正在编写一个包含R6类的包,它有几种方法。我希望能够为类,类和方法生成文档。对于以下示例,我希望能够为该方法访问包含?Person的文档和?set_hair的文档。这是我的示例类:

#' 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
  },
  )
)

运行roxygenise()时,方法体上方的注释根本不会呈现,因此我在@section Methods中指定的唯一信息就在文档中。

由于我有超过50个类方法,如果我可以单独使用?methodname访问方法文档会更好。我发现了一些帖子(Documenting R6 classes and methods within R package in RStudiohttps://github.com/klutometis/roxygen/issues/306),但在我看来,R6类不支持。

分别记录我的课程方法的最佳方法是什么?

2 个答案:

答案 0 :(得分:0)

上面关于user2554330评论中链接的github-raised issue的讨论表明,分离出来的文档不是roxygen的待办事项列表中的内容,因为它与传统的方法风格不匹配文档。也就是说,我仍然发现它很有用,并且一直在使用解决方法。

一个部分解决方案是创建功能包装器。这是一个半手动的过程,在许多方法(如您的情况下)中可能很麻烦,但它确实在单独的文档中为R6方法启用了清晰和半自动的文档。使用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()
}

结果将是两个单独的.Rd个文件,一个用于person类,另一个用于set_hair方法,均可通过?访问。

结果具有额外的优点,因为大多数R用户可能更喜欢接近函数形式的调用,因为这更接近于设置大多数R语法的方式。 person$set_hair(val)set_hair(person, val)都可以产生相同的结果而无需显式分配,从而在增加最小开销的同时保持R6的优势。

编辑:

在与一些人讨论之后,我发现更多的人喜欢使用实际的功能形式包装 - 牺牲参考组件以支持功能性方法,因为它更接近R&#39 ; s&#34;规范。&#34;在这种情况下,该方法仍然提供相同的文档优势,而参考方法调用仍然可以通过$获得。但是,在编写包装器文档时,应该进一步强调引用方法方法的存在。

#` 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
}

当然,使用这些包装器的路线取决于您的具体应用程序的速度和内存要求。功能性方法可能会产生足够的障碍,使其不可行。

答案 1 :(得分:0)

这是一篇旧帖子,您可能很久以前就已经解决了您的问题。但是这里没有添加,以防万一有人需要解决方案,它将是:

#' 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
  },
  )
)