使用roxygen2记录S4方法:明确区分帮助文件中的方法

时间:2012-09-18 11:39:39

标签: r methods package s4 roxygen2

在瞄准和射击之前

我知道这个问题与post密切相关。事实上,我遵循了各种答案中给出的建议,但仍然认为生成的帮助文件有点“尴尬”或至少看起来有点“混在一起”,因此我的问题

实际问题

  1. 当记录S4泛型及其各自的方法时,我如何最终得到一个Rd文件结构,让用户可以清楚地区分各种方法,从而清楚地说明文档的哪一部分特别属于哪种方法?
  2. 鉴于我提供了@alias个标签,在尝试获取特定方法的帮助时,如何实际使用它们?像?foo-character-method这样的东西,而不只是输入?foo
  3. 在一般方法中更好地记录a)签名参数是一个好习惯,因为每个方法肯定都包含相应的文档,b)返回值,因为这也是各自的方法?
  4. 现在,我觉得我最终得到了一个帮助文件,它似乎无法正确区分通用和各种方法 - 至少在视觉上是这样。

    但也许我还没完全得到这个;-)。在这种情况下,任何指针都将非常感谢!


    这是一个可重现的示例,它生成包含S4泛型和两种方法的包mypkg。我试图遵循此postWriting R Extensions

    中给出的建议

    确保目录

    sapply(c("src", "package"), dir.create, showWarnings=FALSE)
    

    通用方法定义

    gnrc.roxy <- c(
        "#' Doing Something Useful",
        "#'", 
        "#' Description here.",
        "#'", 
        "#' @param x A signature argument for method dispatch.",
        "#' @param y A signature argument for method dispatch.",
        "#' @param arg.1 A \\code{logical} scalar. If \\code{TRUE} (default)", 
        "#'      something happens; else not.",
        "#' @param arg.2 A \\code{numeric} vector containing some useful numbers.", 
        "#' @param ... Further arguments.",
        "#' @return Depends on the actual method.", 
        "#' @references \\url{http://www.rappster.de/}",
        "#' @author Janko Thyson \\email{janko.thyson@@rappster.de}",
        "#' @examples", 
        "#'   foo(x=\"a\", y=letters[1:5])",
        "#'   foo(x=\"a\", y=1:5)",
        "#' @docType methods",
        "#' @rdname foo-methods",
        "#' @export"
    )    
    gnrc.def <- c(
        "setGeneric(",
        "    name=\"foo\",",
        "    signature=c(\"x\", \"y\"),",
        "    def=function(",
                "x,",
                "y,",
                "arg.1=TRUE,",
                "arg.2,",
                "...",
        ") {",
        "standardGeneric(\"foo\")",       
        "})"
    )
    path <- "src/gnrc_foo.R"
    write(gnrc.roxy, file=path)
    write(gnrc.def, file=path, append=TRUE)
    

    相关方法的定义

    mthd1.roxy <- c(
        "#' @param x A \\code{character} scalar.",
        "#' @param y A \\code{character} vector.",
        "#' @return A \\code{character} vector.", 
        "#' @docType methods",
        "#' @rdname foo-methods",
        "#' @rdname foo-methods",
        "#' @aliases foo,character,character-method",
        "#' @export"
    )    
    mthd1.def <- c(
        "setMethod(",
            "f=\"foo\",",
            "signature=signature(x=\"character\", y=\"character\"),", 
            "definition=function(",
                "x,",
                "y,", 
                "...",
            ") {",
            "print(x);print(y);return(y)",
            "})"
    )    
    path <- "src/mthds_foo.R"
    write(mthd1.roxy, file=path)
    write(mthd1.def, file=path, append=TRUE)
    
    mthd2.roxy <- c(
        "#' @param x A \\code{character} scalar.",
        "#' @param y A \\code{numeric} vector.",
        "#' @return A \\code{numeric} vector.", 
        "#' @docType methods",
        "#' @rdname foo-methods",
        "#' @rdname foo-methods",
        "#' @aliases foo,character,numeric-method",
        "#' @export"
    )    
    mthd2.def <- c(
        "setMethod(",
            "f=\"foo\",",
            "signature=signature(x=\"character\", y=\"numeric\"),", 
            "definition=function(",
                "x,",
                "y,", 
                "...",
            ") {",
            "print(x);print(y);return(y)",
            "})"
    )    
    write(mthd2.roxy, file=path, append=TRUE)
    write(mthd2.def, file=path, append=TRUE)
    
    # Test source to see if methods were defined correctly
    #sapply(list.files("src", full.names=TRUE), source)
    

    创建包骨架

    # Ensure empty package directory
    subdirs <- list.files("package", full.names=TRUE)
    if (length(subdirs)) {
        sapply(subdirs, unlink, recursive=TRUE)
    }
    
    pkg.name    <- "mypkg"
    path        <- file.path("package", pkg.name)
    
    package.skeleton(
        name=pkg.name, 
        path="package", 
        code_files=list.files("src", full.names=TRUE, recursive=TRUE)
    )
    

    Roxygenize

    require("roxygen2")
    roxygenize(package.dir=path)
    

    修补Rd文件

    有些事情需要修补,以便允许自动检查和构建过程,不需要任何手动干预,如手动编辑Rd文件等。

    rdfiles <- list.files(file.path(path, "man"), full.names=TRUE)
    
    # 1) Removing unnecessary file './package/mypgk/man/foo.Rd'
    file <- grep("foo.Rd", rdfiles, value=TRUE)
    if (length(file)) {
        unlink(file)
    }
    
    # 2) Patching './mypkg/man/mypkg-package.Rd' to pass R CMD CHECK
    file <- grep(paste(pkg.name, "-package.Rd", sep=""), rdfiles, value=TRUE)
    if (length(file)) {
        cnt <- readLines(file, warn=FALSE)
        idx.0 <- grep("\\\\examples\\{", cnt)
        if (length(idx.0)) {
            idx.1 <- grep("\\}", cnt)
            idx.1 <- max(idx.1[which(idx.1 > idx.0)])
            exnew <- c(
                "\\examples{",
                "# TODO: add examples",
                "}"
            )
            cnt <- cnt[-(idx.0:idx.1)]
            cnt <- append(cnt, exnew, after=idx.0-1)
            write(cnt, file=file)
        }
    }
    

    检查包

    shell(paste("R CMD check", path), intern=FALSE)
    

    构建并安装软件包

    shell(paste("R CMD INSTALL",  path), intern=FALSE)
    

    调查帮助文件

    require("mypkg")
    
    foo(x="a", y=letters)
    foo(x="a", y=1:10)
    
    ?foo
    

    替代方式:分离构建和安装

    shell(paste("R CMD INSTALL --build --data-compress=gzip ",  path), intern=FALSE)
    
    install.packages(paste0(pkg.name, "_1.0.zip"), type="win.binary")
    
    require("mypkg")
    
    ?foo
    

0 个答案:

没有答案