[R] Fwd: passing a modified argument to an S3 method

Bert Gunter bgunter@4567 @end|ng |rom gm@||@com
Sat Apr 20 22:28:09 CEST 2024


## Neglected to cc to list

---------- Forwarded message ---------
From: Bert Gunter <bgunter.4567 using gmail.com>
Date: Sat, Apr 20, 2024 at 1:26 PM
Subject: Re: [R] passing a modified argument to an S3 method
To: CRAN.r <cran.r using proton.me>


Well, my interpretation of your explanation is as follows:

You have a long list of "control" values, named "control" in my
example below with all fixed default values.  You also have an S3
generic, named e.g. "test", with many methods. Your methods all use
the control list and possibly other arguments that will vary from
method to method. Also, some methods may want to change some of the
fixed values of control but leave most of them unaltered. The altered
list can change from method to method. Also, some of a method's
altered values may have a default value that you do not wish to
specify each time for the method.

In my example below, I have shown how this can be done. I hope it
approximates what you want to do. However, I second Jeff's
recommendation that you do some reading on your own and **NOT** rely
on my (probably flawed) interpretation, which just is meant to suggest
what could be done (e.g. via ?modifyList) rather than point you to an
exact or best solution. There are many good tutorials out there in
addition to Jeff's suggestion that you can search for.
----------------------------------

control <- list (a=2, b=3, c= "hi there")
## list of all control parameters with defaults

## The generic
test <- function(x,...){
   UseMethod("test")
}
## So test will dispatch methods on the 'x' object
##
test.default <- function(x,
                  control = control,
                  ... ## any additional non control arguments
                  )
{
   ## default code here such as:
   cat(control$c, "\n default method result returned\n")
   ..1 ## first argument in ... list
}

## An example:
> test(x =3, control, y = 'abcd')
hi there
 default method result returned
[1] "abcd"

## Now a 'foo' method
test.foo <- function(x, control = control, ## fixed list of defaults again
                     change, ## list of changed default values
                     ## with no defaults for this method
                     special = list(c = "So long"),
                     ## list of changes with defaults for this method
                     ##  If the method does not use its default change it
                     ##  must be given explicitly here.
                     y = 0 ## additional parameter for this method
                     ## with a default
)
   {
   print(control$c)
   cat("Using x = ", x, "\n")
   before <- with(control, sum(a, b, y)) ## before modifying values
   change <- c(change, special) ## get all the changes to the control list
   control <- modifyList(control, val = change)
   after <- with(control, sum(a, b, y))
   cat("Results are: before = ",before, "  after = ", after, "\n\n")
   print(control$c)
   invisible(list(before, after)) ## return but don't print
}

## construct object of class 'foo'
> x <- structure("method foo", class = "foo")

## Now call the foo method on it.
## Note that the 'special' argument can be omitted, since the default
change to the
## 'c' control parameter will be used
## Note also that the 'a' parameter in the control list is used and so does not
## have to be specified in the change list.

> test(x, control, change = list( b = 100), y = 11)
[1] "hi there"
Using x =  method foo
Results are: before =  16   after =  113

[1] "So long"

## Specify a different 'special' value
> test(x, control, special = list( c="Au revoir"),  change = list( b = 100), y = 11)
[1] "hi there"
Using x =  method foo
Results are: before =  16   after =  113

[1] "Au revoir"


Cheers,
Bert


On Sat, Apr 20, 2024 at 9:03 AM CRAN.r <cran.r using proton.me> wrote:
>
> I've got a complicated default value for an argument, basically a "control" argument that's a list with a lot of defaults, and I want to figure out its value before dispatching to a method so I don't need to have the same code repeated at the beginning of every method. None of the default values should be method-dependent, so I don't need or want each method to figure out the value separately. I hope that helps!
>
> Jay
>
>
> On Saturday, April 20th, 2024 at 10:51 AM, Bert Gunter <bgunter.4567 using gmail.com> wrote:
>
> > I do not understand what your goal is here (more context may be helpful, perhaps to others rather than me). So I doubt this is what you want, but here is a guess -- no need to respond if it is unhelpful:
> >
> > ## test.default returns NULL if object "y" not found in **calling environment and enclosures**;
> > ## otherwise y.
> >
> > test <- function(x){
> > UseMethod("test")
> > }
> > test.default <- function(x){
> > tryCatch(y, error = function(e)NULL)
> > }
> >
> > ## y not found
> > test(x=3)
> > NULL
> >
> > ## y found
> > > y <- 'abcd'
> > > test(x = 3)
> > [1] "abcd"
> >
> > Cheers,
> > Bert
> >
> >
> >
> >
> > On Sat, Apr 20, 2024 at 4:23 AM CRAN.r via R-help <r-help using r-project.org> wrote:
> >
> > > Is there a way to pass a modified argument from an S3 generic to a method? Here's a non-working example that I want to return "abcd".
> > >
> > > test <- function(x, y = NULL){
> > > y <- "abcd"
> > > UseMethod("test")
> > > }
> > > test.default <- function(x, y = NULL) y
> > > test(x = 3)
> > >
> > > Is that possible? I've looked around a lot, but can't find any examples or discussion.
> > >
> > > Jay
> > >
> > > ______________________________________________
> > > R-help using r-project.org mailing list -- To UNSUBSCRIBE and more, see
> > > https://stat.ethz.ch/mailman/listinfo/r-help
> > > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> > > and provide commented, minimal, self-contained, reproducible code.



More information about the R-help mailing list