[Bioc-devel] problem with documentation of setMethod with different signatures
web working
webwork|ng @end|ng |rom po@teo@de
Mon Feb 18 13:05:56 CET 2019
Hi Martin,
thank you very much for this fast and detailed answer. Your solution
works great for me. I agree with your point that roxygen requires a lot
of manual effort to arrive a satisfactory solution. Especially when you
use it the first time.
Tobias
Am 14.02.19 um 12:07 schrieb Martin Morgan:
> It's important to distinguish between problems in your code and problems in the tools (or use of tools) to process the code. Here the use of setGeneric() / setMethod() is correct. Your use of roxygen2 is getting in the way.
>
> You've used @rdname to document the methods on the same page (reducing the number of man pages probably helps the user, so this is good). But then on the same page you've documented `@param x`, for instance, twice, once for GRanges and once for integer. Here the solution is to document `@param x` in only one place, e.g., in the generic, with sentences that describe appropriate input for each method.
>
> #' @param x A `GRanges` instance or `integer` vector that...
>
> For other tags, e.g., `@details`, `@return`, multiple uses are concatenated into paragraphs in a single element in the Rd file; one might then say
>
> #' @details methodA,GRanges-method does one thing.
> ...
> #' @details methodA,integer-method does another.
>
> Generally, it is much harder to provide clear user-oriented documentation for S4 classes and methods, and roxygen requires a lot of manual effort to arrive at a satisfactory solution. You've already started down that road by using the @rdname tag to group methods documentation on the same page.
>
> While open for discussion and certainly dependent on context, I think it is more helpful to group documentation by class rather than generic, e.g, 'I have a GRanges object, what can I do with it?' rather than 'I wonder what I can find the `start()` of?'. Also the best documentation pages are really very carefully constructed, and these are very difficult to generate automatically from roxygen snippets associated with individual functions / methods; an approach might be to provide a single roxygen chunk at the top of a source file that documents the content of the source file, with individual methods etc restricted to tags `@rdname` and `@export`. The old school approach is to simply edit the man page by hand directly.
>
> Finally, it has proven very helpful to organize code, man pages, and unit tests in a parallel fashion
>
> R/My-class.R
> man/My-class.Rd
> tests/testthat/test_My-class.R
>
> The GenomicRanges package https://github.com/Bioconductor/GenomicRanges might be an advanced example of structure, though based on old-school manual construction of Rd files.
>
> Martin
>
> On 2/14/19, 4:08 AM, "Bioc-devel on behalf of web working" <bioc-devel-bounces using r-project.org on behalf of webworking using posteo.de> wrote:
>
> Hi,
>
> I am struggling a bit with a R generic function. I build a generic and
> set two implementations of the generic with two different signatures as
> input. Both implementations of the generic produce the same output but
> have a different input. During devtools::check() I get the following error:
>
> ❯ checking Rd \usage sections ... WARNING
> Duplicated \argument entries in documentation object 'methodA':
> ‘x’ ‘size’
>
> Functions with \usage entries need to have the appropriate \alias
> entries, and all their arguments documented.
> The \usage entries must correspond to syntactically valid R code.
> See chapter ‘Writing R documentation files’ in the ‘Writing R
> Extensions’ manual.
>
>
> The original functions are complex so here are some dummy methods:
>
>
> #' methodA methods generic
> #' @rdname methodA-methods
> #' @export
> #'
> setGeneric("methodA", function(x, size = 1000)
> standardGeneric("methodA"))
>
>
> #' methodA method for \code{GRanges} input
> #'
> #' @param x a \code{GRanges} object
> #' @param size a \code{numeric} vector
> #'
> #' @import GenomicRanges
> #' @return a \code{list} object
> #' @rdname methodA-methods
> #' @export
> #' @examples
> #' library(GenomicRanges)
> #' dat.GRanges <- GRanges(seqnames=c(rep("chr1", 5), rep("chr2", 5)),
> #' IRanges(start = rep(c(10000, 10000, 55000, 55000, 150000), 2),
> #' end = rep(c(20000, 20000, 70000, 70000, 600000), 2)))
> #' out.list <- methodA(x = dat.GRanges, size = length(dat.GRanges))
> #'
> setMethod(methodA, signature(x="GRanges"),
> function(x, size = 1000){
> s <- start(x)
> return(list(s, size))
> })
>
>
>
> #' methodA method for named \code{integer} input
> #'
> #' @param x a \code{integer} vector
> #' @param size a \code{numeric} vector
> #'
> #' @return a \code{list} object
> #' @export
> #' @rdname methodA-methods
> #' @examples
> #' dat <- 1:20
> #' out.list <- methodA(x = dat, size = length(dat))
> setMethod(methodA, signature(x="integer"),
> function(x, size = 1000){
> return(list(x, size))
> })
>
> The error above sounds absolute understandable for me, but I do not have
> a solution for this. Maybe using a generic is not the way to do this here?
>
> Tobias
>
> _______________________________________________
> Bioc-devel using r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/bioc-devel
>
More information about the Bioc-devel
mailing list