Skip to content

Extracting specific arguments from "..."

7 messages · Jorgen Harmse, Sorkin, John, Bert Gunter +1 more

#
I think Bert Gunter is right, but do you want partial matches (not found by match), and how robust do you want the code to be?

f <- function(?)
{ pos <- match('a', ...names())
  if (is.na(pos))
    stop("a is required.")
  ?elt(pos)
}

Incidentally, what is the best way to extract the expression without evaluating it?



g <- function(...)

{ pos <- match('a',...names())

  if (is.na(pos))

    stop("a is missing.")

  (function(a,...) substitute(a)) (...)

}

Regards,
Jorgen Harmse.

Message: 8
Date: Sun, 5 Jan 2025 11:17:02 -0800
From: Bert Gunter <bgunter.4567 at gmail.com>
To: Iris Simmons <ikwsimmo at gmail.com>
Cc: R-help <R-help at r-project.org>
Subject: Re: [R] Extracting specific arguments from "..."
Message-ID:
        <CAGxFJbROnopt-boDF6sRPP79bWUcPPOO3+ycDGN3y-YTDU5b6Q at mail.gmail.com>
Content-Type: text/plain; charset="utf-8"

Thanks, Iris.
That is what I suspected, but it wasn't clear to me from the docs.

Best,
Bert
On Sun, Jan 5, 2025 at 10:16?AM Iris Simmons <ikwsimmo at gmail.com> wrote:

  
  
#
Thanks Jorgen.

I thought your approach to getting the argument expressions was clever, but
somewhat convoluted. I think the usual simple way is to use match.call()
(or sys.call() )to get the unevaluated argument expressions;  e.g. ...

f <- function(...){
   match.call()
}
f(a = "red", b = sin(zzz))

The return value is an object of class call that can be subscripted as (or
converted by as.list() to) a list to extract the argument expressions:
sin(zzz)

You'll note that the $b component is again of class "call". So you may wish
to convert it to character or expression or whatever for further
processing, depending on context. Obviously, I haven't thought about this
carefully.

You raise an important point about robustness. I believe this approach to
extracting the call expressions should be fairly robust, but I do get
confused about the lay of the land when you add promises with default
arguments that may not yet have been forced before match.call() is called.
You may have to wrestle with sys.call() and it's "wh" argument to make
things work the way you want in that situation. I leave such delights to
wiser heads, as well as any corrections or refinements to anything that
I've said here.

Cheers,
Bert
On Mon, Jan 6, 2025 at 9:55?AM Jorgen Harmse <JHarmse at roku.com> wrote:

            

  
  
#
Bert and other on this Chain,

The original question asked by Bert Gunter, highlights one of my long standing wishes. Perhaps my wish has already been fulfilled (if it has, please let me know where I can look of fulfill my wish), if it hasn't perhaps someone can grant me my wish.

I have tried to understand how to write a function (beyond a basic function), get values of the parameters, and process the parameters. I have looked for a source that clearly describes how his may be done (with examples), but I have yet to find one. Yes, one can look at a function (e.g. lm) look at the statements that are used and use the help system to research each of the statements (I have done this), but doing this is not the most efficient way to learn the topic. It would be very helpful if someone Knowledgeable would put together a primer on writing functions and processing function arguments. If such a document exist, I would be happy to have someone send me its URL.

Thank you,
John

John David Sorkin M.D., Ph.D.
Professor of Medicine, University of Maryland School of Medicine;
Associate Director for Biostatistics and Informatics, Baltimore VA Medical Center Geriatrics Research, Education, and Clinical Center;
PI Biostatistics and Informatics Core, University of Maryland School of Medicine Claude D. Pepper Older Americans Independence Center;
Senior Statistician University of Maryland Center for Vascular Research;

Division of Gerontology and Paliative Care,
10 North Greene Street
GRECC (BT/18/GR)
Baltimore, MD 21201-1524
Cell phone 443-418-5382
#
I am frankly at a loss.

Have you read "An Introduction to R," which is shipped with R, especially
Ch. 10. Or any of Hadley's (free, online) books. Or looked at Posit's or
the web's tutorials? There is so much out there...

I would say that the Help docs are meant to be concise references on how to
use particular functions, *not* tutorials on how to write functions in R.
(That said, I have found some of R's Help resources sufficient to learn
techniques that I was ignorant of, regular expressions for example.
However, that is not their purpose, as I said).

Or have I entirely misunderstood you?!

NB. Terminology: Function "arguments" not "parameters". "Parameters"
actually means something different in R.

Cheers,
Bert

On Mon, Jan 6, 2025 at 3:26?PM Sorkin, John <jsorkin at som.umaryland.edu>
wrote:

  
  
#
It is a pretty tricky topic, but IMO Advanced R [1] steps you through it systematically... you just have to be prepared to follow along in R with the examples as you read it. In particular, the chapter on Functions goes through this.

The subtleties of how base R gives you control over these topics is what lead to the tidyverse creating new packages to build such function interfaces. Manipulating object evaluation from arbitrary environments is still complex, and the more you learn about it the more you learn to avoid it for certain types of tasks. String literals are surprisingly simple alternatives that don't bite you in the butt nearly so often as NSE does.

[1] https://adv-r.hadley.nz/
On January 6, 2025 3:26:25 PM PST, "Sorkin, John" <jsorkin at som.umaryland.edu> wrote:

  
    
#
Jeff:
Would you care to offer an example of:

"String literals are surprisingly simple alternatives that don't bite you
in the butt nearly so often as NSE does."

"No" is a perfectly acceptable answer.

I would generally agree with you about NSE, but my original query was
motivated by something simple. I like to use lattice graphics when I fool
around with graphing data, as I'm retired and don't have to worry about
adhering to organizational or journal standards built around the ggplot
graphics grammar or require it's very extensive and sophisticated
capabilities. But I do often create custom panel displays, which typically
requires that I have to pass around long default lists of graphics
arguments via "..." that I modify to suit my aesthetic and analytical
preferences. Ergo my query about how to check what's in the "..." list
without requiring evaluation, which Iris helped me with.

I would also suggest that as a personal user of R for "data science stuff",
one can avoid a lot of the complexities to which you allude; while as a
developer of "tools" (chiefly packages) for others, one has to wade into a
lot of those complexities. This is just a software clich? I think.
Unfortunately, S and therefore R, were originally designed for a pretty
sophisticated audience (ATT labs researchers) and intentionally, and to me
rather seductively, blurred the line between "user" and "developer."  All
IMO, of course. YMMV.

Cheers,
Bert


On Mon, Jan 6, 2025 at 4:04?PM Jeff Newmiller <jdnewmil at dcn.davis.ca.us>
wrote:

  
  
#
I have no particular example in mind, though if your data are in lists (e.g. data frames) or better yet you want to add new data to a list then a particular trap for inexperienced analysts is trying to capture the name of the not-yet-created item from a symbol instead of simply giving the function a string to label the new item with.

I must say playing around with ... seems tediously unpleasant to me... to each their own though. I prefer to let R handle that... if I want to tweak a variable being passed I just declare the parameter explicitly and pass it along explicitly. As long as it has a default value the calling function shouldn't care... unless it is also abusing ....
On January 6, 2025 5:15:59 PM PST, Bert Gunter <bgunter.4567 at gmail.com> wrote: