読者です 読者をやめる 読者になる 読者になる

Reference class に roxygen2 用のコメントを入れる方法

先日 Reference class に roxygen 用のコメントを入れる方法 という記事を書いたのですが、実は全然ドキュメントを作れていなかったことに今更気づいたので、せっかくなので roxygen2 用の場合を作ってみました。
基本的には変わっていませんが、@section で fields 等の部分を記述していたり、[http://www.mail-archive.com/roxygen-devel@lists.r-forge.r-project.org/msg00091.html:title=@aliases] の問題 (Roxygen-devel) があったり、個人的には解決しておきたい問題がありました。

Reference class 用サンプルパッケージ (roxygen2 用)

パッケージの Rd ファイル用の roxygen コメント

パッケージの Rd ファイルは以下の様に書くことにしました。

#' testRefclassPkg: A test package for reference class documents using 'roxygen2'
#'
#' A Test Package for Reference Class Documents Using 'roxygen2'
#'
#' This package is an example of how to document reference class methods.
#'
#' @name testRefclassPkg-package
#' @aliases testRefclassPkg
#' @rdname testRefclassPkg-package
#' @docType package
#' @keywords documentation
#'
#' @author
#' Author: Triad sou.
#' Maintainer: Triad sou. \email{triadsou@@gmail.com}
#' @seealso \code{\link[methods:ReferenceClasses]{ReferenceClasses}}
#' @exportPattern '^[^\\.]'
NULL

ポイント

  • roxygen2 では roxygen と違い、上から順に空行で区切って、\title フィールド、\description フィールド、\details フィールドの三つを @ 無しで略記できます。
  • @name testRefclassPkg: \name フィールドを指定します。パッケージの roxygen2 コメントを書く場合、最後に続けて関数定義やクラス定義などを記入できないため、NULL{} などを記入します。この場合、関数名やクラス名が存在しないため、\name フィールドを自動的に作成できずエラーが発生してしまいますが、自分で指定しておけば問題ありません。
  • @aliases testRefclassPkg: help("keyword")?keyword でヘルプを検索するための検索ワードを指定しています。いちいち -package を付けるのが面倒なので、個人的にパッケージ名を検索ワードとして登録しています。
  • @rdname testRefclassPkg-package: Rd ファイル名を指定します、好きな名前を指定して問題ありません。
  • @docType package: \docType フィールドにパッケージ用の Rd ファイルであることを指定します。
  • @keywords documentation: \keyword フィールドを指定します。
  • @author: \author フィールドを指定します。
  • @seealso: \seealso フィールドを指定します。ヘルプ間でリンクを張って、参考情報をたどれるようにするために指定しておきます。
  • @exportPattern '^[^\\.]': NAMESPACE ファイルを自動生成するために、すべてにマッチする directive を書いておきます。
Reference class の定義と Rd ファイル用の roxygen コメント
#' My test class
#'
#' My Test Class (description)
#'
#' \code{test_refclass} class is a test reference class that has three methods (details).
#'
#' @name test_refclass-class
#' @aliases test_refclass
#' @docType class
#'
#' @section Fields:
#' \describe{
#' \item{\code{f1}: }{numeric number of a test field.} 
#' \item{\code{f2}: }{numeric number of a test field.} 
#' }
#' @section Contains:
#' NULL
#' @section Methods:
#' \describe{
#' \item{\code{m1(arg1 = 1)}: }{\code{m1} method set a value to \code{f1}.}
#' \item{\code{m2(arg1)}: }{\code{m2} method return \code{f1 + arg1 * 2}.}
#' \item{\code{m3(arg1)}: }{\code{m3} method return \code{f1 + arg1 * 3}.}
#' }
#' @keywords documentation
#' @family test_refclass
test_refclass <- setRefClass(

  Class = "test_refclass",
  
  fields = c("f1", "f2"),

  methods = list(

    m1 = function(arg1 = 1) {
      f1 <<- arg1
    },

    m1 = function(arg1 = 1, arg2) {
      f1 <<- arg1 + arg2
    },

    m2 = function(arg1) {
      if (class(f1) == "uninitializedField") f1 <<- 2
      f1 + arg1 * 2
    },

    m3 = function(arg1) {
      if (class(f1) == "uninitializedField") f1 <<- 3
      f1 + arg1 * 3
    }

  )
)

ポイント

  • @name test_refclass-class: \name フィールドを指定します。@aliases の問題で、@aliases test_refclass-class と書いてしまうと、Rd ファイルの \alias フィールドがダブルクォートで囲まれてしまい、Rcmd check から警告をいただくことになります。ですので、@name@aliases を逆に書いて、この問題に対処しています。
  • @aliases test_refclass: \alias フィールドを指定します。
  • @docType class: クラス用の Rd ファイルであることを指定します。
  • @section Fields:: Bioconductor にある S4 クラスのドキュメントを参考にすると、\section{Slots} フィールドや \section{Methods} フィールドが用いられていることが分かります。それに合わせて、Reference class では \section{Slots} の代わりに \section{Fields} を作成してみました。ちなみに、@section XXX: で任意のセクションをヘルプファイルに入れておくことができます。
  • @section Contains:: 不要かもしれませんが、個人的には \section{Contains} フィールドを作って、継承に関する情報も併記してあった方が良いと思います。
  • @section Methods:: \section{Contains} フィールドを指定します。
  • @keywords documentation: \keyword フィールドを指定します。
  • @family test_refclass: roxygen2 の特殊キーワードで、@family グループ名 の形式で記入しておくと、同じグループ名を指定した Rd ファイルに対して \seealso フィールドに相互リンクが自動的に生成されます。
メソッドの Rd ファイル用の roxygen コメント
#' The \code{m1} method of \code{test_refclass} class
#'
#' \code{m1} method
#'
#' \code{m1} method set a value to \code{f1}.
#'
#' @name m1,test_refclass-method
#' @aliases m1
#' @rdname test_refclass-m1
#' @docType methods
#'
#' @param arg1 numeric number of a test argument
#' @usage \S4method{m1}{test_refclass}(arg1 = 1)
#' @examples
#' classObj <- test_refclass$new()
#' print(classObj$m1(10))
#' @family test_refclass
NULL

#' The \code{m2} method of \code{test_refclass} class
#'
#' \code{m2} method
#'
#' \code{m2} method return \code{f1 + arg1 * 2}.
#'
#' @name m2,test_refclass-method
#' @aliases m2
#' @rdname test_refclass-m2
#' @docType methods
#' 
#' @param arg1 numeric number of a test argument
#' @usage \S4method{m2}{test_refclass}(arg1)
#' @examples
#' classObj <- test_refclass$new()
#' print(classObj$m2(10))
#' @family test_refclass
NULL

#' The \code{m3} method of \code{test_refclass} class
#'
#' \code{m3} method
#'
#' \code{m3} method return \code{f1 + arg1 * 3}.
#'
#' @name m3,test_refclass-method
#' @aliases m3
#' @rdname test_refclass-m3
#' @docType methods
#'
#' @param arg1 numeric number of a test argument
#' @usage \S4method{m3}{test_refclass}(arg1)
#' @examples
#' classObj <- test_refclass$new()
#' print(classObj$m3(10))
#' @family test_refclass
NULL

ポイント

  • @name m1,test_refclass-method: \name フィールドを指定します。@aliases の問題については同様のため。
  • @aliases m1: \alias フィールドを指定します。
  • @rdname test_refclass-m1: Rd ファイル名を指定します、好きな名前を指定して問題ありません。
  • @docType methods: メソッド用の Rd ファイルであることを指定します。
  • @param: \arguments フィールドを指定します。
  • @usage: \usage フィールドを指定します。\S4method{generic}{signature_list}(argument_list) を流用しています。
  • @examples: \examples フィールドを指定します。@example /パッケージホームからの相対パス で書くと、ファイルを指定して読み込むことも可能です。@example /inst/examples/xxxx.R を用いている例が実際にいくつかありました。
  • @family test_refclass: 相互リンクを指定しておきます。この例ではクラスとメソッド全部に相互リンクを張っています。

表示例

上記のスクリプトを *.R ファイルとして保存し、DESCRIPTION ファイルなど他の必要なファイルと一緒に適切にディレクトリに配置し、

require(roxygen2)
roxygenize(path, copy.package = FALSE)

の様に roxygenize() 関数を適用すると、Rd ファイルが生成されますので、これらをまとめてパッケージ化すると完成です。


以下に、パッケージ化してインストール後に生成されたドキュメントを示しておきます。




roxygen 版の記事について

roxygen 版の記事では @slot 云々の話を書いていたのですが、結局書いても無意味だった事に気づいていなかっただけで、roxygen2 で書いた方が良いということが分かりました!
ちなみに roxygen では @section も利用できません。