Clarification on generic functions and methods

5 messages Options
Embed this post
Permalink
Doran, Harold

Clarification on generic functions and methods

Reply Threaded More More options
Print post
Permalink
I have constructed the following functions and need a little clarification:

### function to fit the model parameters
jml.fit <- function(dat, con = 1e-3, bias=FALSE, ...){
        do stuff ...
}

### default function which calls jml.fit
jml.default <- function(dat, con = 1e-3, bias=FALSE, ...){
        result <- jml.fit(dat, con = 1e-3, bias)
        result$call <- match.call()
        class(result) <- "jml"
        result
}

### Function to make use of formula
jml.formula <- function(formula, data, na.action, subset, ...){
        mf <- match.call(expand.dots = FALSE)
    m <- match(c("formula", "data", "na.action", "subset"), names(mf), 0L)
    mf <- mf[c(1L, m)]
    mf$drop.unused.levels <- TRUE
    mf[[1L]] <- as.name("model.frame")
    mf <- eval(mf, parent.frame())
        mt <- attr(mf, "terms")
        dat <- mf
        result <- jml.default(dat, ...)
        result$call <- match.call()
        result$formula <- formula
        result
}

### and the generic function
jml <- function(dat, con = 1e-3, bias=FALSE, ...) UseMethod("jml")

Writing R Extensions states, "If the generic specifies defaults, all methods should use the same defaults."

In my example above, the generic function has 2 defaults: one for argument con and another bias. I'm a little confused on exactly how the generic function should be structured for proper package development.

I think the options are:

1) jml <- function(dat, con = 1e-3, bias=FALSE, ...) UseMethod("jml")
2) jml <- function(x, con = 1e-3, bias=FALSE, ...) UseMethod("jml")
3) jml <- function(formula, data, na.action, subset, con = 1e-3, bias = FALSE, ...) UseMethod("jml")

I'm inclined to believe #3 is correct because the .Rd page needs to reflect the args in this function, is that right? Then, this generic function would include the formula, data, na.action, and subset and it includes the proper defaults as the other functions.

Thank you
Harold

> sessionInfo()
R version 2.10.0 (2009-10-26)
i386-pc-mingw32

locale:
[1] LC_COLLATE=English_United States.1252  LC_CTYPE=English_United States.1252  
[3] LC_MONETARY=English_United States.1252 LC_NUMERIC=C                          
[5] LC_TIME=English_United States.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base    

other attached packages:
[1] scoreFoo_1.1   MiscPsycho_1.4 statmod_1.4.1

loaded via a namespace (and not attached):
[1] tools_2.10.0
______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Henrik Bengtsson

Re: Clarification on generic functions and methods

Reply Threaded More More options
Print post
Permalink
Using

jml <- function(...) UseMethod("jml")

will do.

/Henrik


On Wed, Nov 11, 2009 at 4:26 PM, Doran, Harold <[hidden email]> wrote:

> I have constructed the following functions and need a little clarification:
>
> ### function to fit the model parameters
> jml.fit <- function(dat, con = 1e-3, bias=FALSE, ...){
>        do stuff ...
> }
>
> ### default function which calls jml.fit
> jml.default <- function(dat, con = 1e-3, bias=FALSE, ...){
>        result <- jml.fit(dat, con = 1e-3, bias)
>        result$call <- match.call()
>        class(result) <- "jml"
>        result
> }
>
> ### Function to make use of formula
> jml.formula <- function(formula, data, na.action, subset, ...){
>        mf <- match.call(expand.dots = FALSE)
>    m <- match(c("formula", "data", "na.action", "subset"), names(mf), 0L)
>    mf <- mf[c(1L, m)]
>    mf$drop.unused.levels <- TRUE
>    mf[[1L]] <- as.name("model.frame")
>    mf <- eval(mf, parent.frame())
>        mt <- attr(mf, "terms")
>        dat <- mf
>        result <- jml.default(dat, ...)
>        result$call <- match.call()
>        result$formula <- formula
>        result
> }
>
> ### and the generic function
> jml <- function(dat, con = 1e-3, bias=FALSE, ...) UseMethod("jml")
>
> Writing R Extensions states, "If the generic specifies defaults, all methods should use the same defaults."
>
> In my example above, the generic function has 2 defaults: one for argument con and another bias. I'm a little confused on exactly how the generic function should be structured for proper package development.
>
> I think the options are:
>
> 1) jml <- function(dat, con = 1e-3, bias=FALSE, ...) UseMethod("jml")
> 2) jml <- function(x, con = 1e-3, bias=FALSE, ...) UseMethod("jml")
> 3) jml <- function(formula, data, na.action, subset, con = 1e-3, bias = FALSE, ...) UseMethod("jml")
>
> I'm inclined to believe #3 is correct because the .Rd page needs to reflect the args in this function, is that right? Then, this generic function would include the formula, data, na.action, and subset and it includes the proper defaults as the other functions.
>
> Thank you
> Harold
>
>> sessionInfo()
> R version 2.10.0 (2009-10-26)
> i386-pc-mingw32
>
> locale:
> [1] LC_COLLATE=English_United States.1252  LC_CTYPE=English_United States.1252
> [3] LC_MONETARY=English_United States.1252 LC_NUMERIC=C
> [5] LC_TIME=English_United States.1252
>
> attached base packages:
> [1] stats     graphics  grDevices utils     datasets  methods   base
>
> other attached packages:
> [1] scoreFoo_1.1   MiscPsycho_1.4 statmod_1.4.1
>
> loaded via a namespace (and not attached):
> [1] tools_2.10.0
> ______________________________________________
> [hidden email] mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Doran, Harold

Re: Clarification on generic functions and methods

Reply Threaded More More options
Print post
Permalink
Thank you, Henrik. This actually doesn't work when I build the package, which may only require a slight modification to what I'm doing now. First, I create a NAMESPACE as:

### NAMESPACE FILE CONTENTS
export(jml2)
S3method(jml2, fit)
S3method(jml2, default)
S3method(jml2, formula)
S3method(print, jml)
S3method(summary, jml)
S3method(print, summary.jml)

So, only the generic function (jml) is exported.

Now, I do as you suggest below for the generic function, but keep all others as they were previously. That creates a situation where jml.formula, jml.default, and jml have different arguments.

Now, in the .Rd file for the jml function I want the user to see the usage for the jml.formula method, which obviously has more args than "...". So, the .Rd file is structured as (for testing purposes only):

\name{jml2}
\alias{jml2}
\title{JML Estimation}
\description{JML Stuff}
\usage{
jml2(formula, data, na.action, subset, con = 1e-3, bias = FALSE, ...)
}
\arguments{
  \item{formula}{Describe later}
  \item{data}{Describe later}
  \item{na.action}{Describe later}
  \item{subset}{Describe later}
  \item{con}{Describe later}
  \item{bias}{Describe later}
  \item{\dots}{Not implemented}
}
\author{Me}
\examples{
\dontrun{jml(~V1 + V2, data)}
}
\keyword{misc}

But, because the args in the generic functions differ from what I have placed in the .Rd file, the check phase yields the following error, which indicates the .Rd file and code are different.

C:\Program Files\R\R-2.10.0\bin>Rcmd check g:\jmlFoo
* checking for working pdflatex ...pdflatex: not found
 NO
* checking for working latex ...latex: not found
 NO
* using log directory 'C:/Program Files/R/R-2.10.0/bin/jmlFoo.Rcheck'
* using R version 2.10.0 (2009-10-26)
* using session charset: ISO8859-1
* checking for file 'jmlFoo/DESCRIPTION' ... OK
* checking extension type ... Package
* this is package 'jmlFoo' version '1.0'
* checking package name space information ... OK
* checking package dependencies ... OK
* checking if this is a source package ... OK
* checking for executable files ... OK
* checking whether package 'jmlFoo' can be installed ... OK
* checking package directory ... OK
* checking for portable file names ... OK
* checking DESCRIPTION meta-information ... OK
* checking top-level files ... OK
* checking index information ... OK
* checking package subdirectories ... OK
* checking R files for non-ASCII characters ... OK
* checking R files for syntax errors ... OK
* checking whether the package can be loaded ... OK
* checking whether the package can be loaded with stated dependencies ... OK
* checking whether the name space can be loaded with stated dependencies ... OK
* checking for unstated dependencies in R code ... OK
* checking S3 generic/method consistency ... OK
* checking replacement functions ... OK
* checking foreign function calls ... OK
* checking R code for possible problems ... NOTE
jml2.fit: no visible binding for global variable 'theta.max'
jml2.fit: no visible global function definition for 'fit.Stats'
* checking Rd files ... OK
* checking Rd metadata ... OK
* checking Rd cross-references ... OK
* checking for missing documentation entries ... OK
* checking for code/documentation mismatches ... WARNING
Codoc mismatches from documentation object 'jml2':
jml2
  Code: function(...)
  Docs: function(formula, data, na.action, subset, con = 0.001, bias =
                 FALSE, ...)
  Argument names in docs not in code:
    formula data na.action subset con bias
  Mismatches in argument names:
    Position: 1 Code: ... Docs: formula

* checking Rd \usage sections ... OK
* checking examples ... OK

WARNING: There was 1 warning, see
  C:/Program Files/R/R-2.10.0/bin/jmlFoo.Rcheck/00check.log
for details

So, what I'm trying to accomplish is to export the jml generic function and make this the only one visible to the user. All others are in the NAMESPACE as S3 methods. But this obviously creates a conflict between what I want in the .Rd file and what args are in the code for the generic jml function.

Can anyone help me understand how this might be resolved?

Harold


> -----Original Message-----
> From: [hidden email]
> [mailto:[hidden email]] On Behalf Of Henrik Bengtsson
> Sent: Wednesday, November 11, 2009 10:44 AM
> To: Doran, Harold
> Cc: [hidden email]
> Subject: Re: [Rd] Clarification on generic functions and methods
>
> Using
>
> jml <- function(...) UseMethod("jml")
>
> will do.
>
> /Henrik
>
>
> On Wed, Nov 11, 2009 at 4:26 PM, Doran, Harold <[hidden email]> wrote:
> > I have constructed the following functions and need a
> little clarification:
> >
> > ### function to fit the model parameters jml.fit <-
> function(dat, con
> > = 1e-3, bias=FALSE, ...){
> >        do stuff ...
> > }
> >
> > ### default function which calls jml.fit jml.default <-
> function(dat,
> > con = 1e-3, bias=FALSE, ...){
> >        result <- jml.fit(dat, con = 1e-3, bias)
> >        result$call <- match.call()
> >        class(result) <- "jml"
> >        result
> > }
> >
> > ### Function to make use of formula
> > jml.formula <- function(formula, data, na.action, subset, ...){
> >        mf <- match.call(expand.dots = FALSE)
> >    m <- match(c("formula", "data", "na.action", "subset"),
> names(mf),
> > 0L)
> >    mf <- mf[c(1L, m)]
> >    mf$drop.unused.levels <- TRUE
> >    mf[[1L]] <- as.name("model.frame")
> >    mf <- eval(mf, parent.frame())
> >        mt <- attr(mf, "terms")
> >        dat <- mf
> >        result <- jml.default(dat, ...)
> >        result$call <- match.call()
> >        result$formula <- formula
> >        result
> > }
> >
> > ### and the generic function
> > jml <- function(dat, con = 1e-3, bias=FALSE, ...) UseMethod("jml")
> >
> > Writing R Extensions states, "If the generic specifies
> defaults, all methods should use the same defaults."
> >
> > In my example above, the generic function has 2 defaults:
> one for argument con and another bias. I'm a little confused
> on exactly how the generic function should be structured for
> proper package development.
> >
> > I think the options are:
> >
> > 1) jml <- function(dat, con = 1e-3, bias=FALSE, ...)
> UseMethod("jml")
> > 2) jml <- function(x, con = 1e-3, bias=FALSE, ...) UseMethod("jml")
> > 3) jml <- function(formula, data, na.action, subset, con =
> 1e-3, bias
> > = FALSE, ...) UseMethod("jml")
> >
> > I'm inclined to believe #3 is correct because the .Rd page
> needs to reflect the args in this function, is that right?
> Then, this generic function would include the formula, data,
> na.action, and subset and it includes the proper defaults as
> the other functions.
> >
> > Thank you
> > Harold
> >
> >> sessionInfo()
> > R version 2.10.0 (2009-10-26)
> > i386-pc-mingw32
> >
> > locale:
> > [1] LC_COLLATE=English_United States.1252  LC_CTYPE=English_United
> > States.1252 [3] LC_MONETARY=English_United States.1252 LC_NUMERIC=C
> > [5] LC_TIME=English_United States.1252
> >
> > attached base packages:
> > [1] stats     graphics  grDevices utils     datasets  methods   base
> >
> > other attached packages:
> > [1] scoreFoo_1.1   MiscPsycho_1.4 statmod_1.4.1
> >
> > loaded via a namespace (and not attached):
> > [1] tools_2.10.0
> > ______________________________________________
> > [hidden email] mailing list
> > https://stat.ethz.ch/mailman/listinfo/r-devel
> >
>
______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Ken Knoblauch

Re: Clarification on generic functions and methods

Reply Threaded More More options
Print post
Permalink
Doran, Harold <HDoran <at> air.org> writes:
>
> Thank you, Henrik. This actually doesn't work when I build the package,
which may only require a slight

> modification to what I'm doing now. First, I create a NAMESPACE as:
>
> ### NAMESPACE FILE CONTENTS
> export(jml2)
> S3method(jml2, fit)
> S3method(jml2, default)
> S3method(jml2, formula)
> S3method(print, jml)
> S3method(summary, jml)
> S3method(print, summary.jml)
>
> So, only the generic function (jml) is exported.
>
> Now, I do as you suggest below for the generic function, but keep all others
as they were previously. That
> creates a situation where jml.formula, jml.default, and jml have different
 arguments.
>
> Now, in the .Rd file for the jml function I want the user to see the usage for
the jml.formula method, which
> obviously has more args than "...". So, the .Rd file is structured as
 (for testing purposes only):

How about if you document the default method as well as the generic
method in your man page.  See ?lag for an example, and I've come
across several others recently.

HTH,

Ken

--
Ken Knoblauch
Inserm U846
Stem-cell and Brain Research Institute
Department of Integrative Neurosciences
18 avenue du Doyen Lépine
69500 Bron
France
tel: +33 (0)4 72 91 34 77
fax: +33 (0)4 72 91 34 61
portable: +33 (0)6 84 10 64 10
http://www.sbri.fr/members/kenneth-knoblauch.html

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Doran, Harold

Re: Clarification on generic functions and methods

Reply Threaded More More options
Print post
Permalink
Hi Ken:

Well, I'm quite pleased with a solution I found. The t.test method and its .Rd file showed me that I can export only the generic method, use \alias{jml2.default} and \alias{jml2.formula} in the .Rd file for jml2, and then use \method{jml2}{default}{args} and \method{jml2}{formula}{args}.

Using this, I was able to build the package in both windows and Ubuntu without error.

> -----Original Message-----
> From: [hidden email]
> [mailto:[hidden email]] On Behalf Of Ken Knoblauch
> Sent: Wednesday, November 11, 2009 3:58 PM
> To: [hidden email]
> Subject: Re: [Rd] Clarification on generic functions and methods
>
> Doran, Harold <HDoran <at> air.org> writes:
> >
> > Thank you, Henrik. This actually doesn't work when I build the
> > package,
> which may only require a slight
> > modification to what I'm doing now. First, I create a NAMESPACE as:
> >
> > ### NAMESPACE FILE CONTENTS
> > export(jml2)
> > S3method(jml2, fit)
> > S3method(jml2, default)
> > S3method(jml2, formula)
> > S3method(print, jml)
> > S3method(summary, jml)
> > S3method(print, summary.jml)
> >
> > So, only the generic function (jml) is exported.
> >
> > Now, I do as you suggest below for the generic function,
> but keep all
> > others
> as they were previously. That
> > creates a situation where jml.formula, jml.default, and jml have
> > different
>  arguments.
> >
> > Now, in the .Rd file for the jml function I want the user
> to see the
> > usage for
> the jml.formula method, which
> > obviously has more args than "...". So, the .Rd file is
> structured as
>  (for testing purposes only):
>
> How about if you document the default method as well as the
> generic method in your man page.  See ?lag for an example,
> and I've come across several others recently.
>
> HTH,
>
> Ken
>
> --
> Ken Knoblauch
> Inserm U846
> Stem-cell and Brain Research Institute
> Department of Integrative Neurosciences
> 18 avenue du Doyen Lépine
> 69500 Bron
> France
> tel: +33 (0)4 72 91 34 77
> fax: +33 (0)4 72 91 34 61
> portable: +33 (0)6 84 10 64 10
> http://www.sbri.fr/members/kenneth-knoblauch.html
>
> ______________________________________________
> [hidden email] mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>
______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel