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-boun...@r-project.org on behalf of webwork...@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@r-project.org mailing list
     https://stat.ethz.ch/mailman/listinfo/bioc-devel


_______________________________________________
Bioc-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/bioc-devel

Reply via email to