I might add that there seems to be a subtle difference between using `...elt()` and `match.call()`, which is that the former causes `a` itself to be evaluated while the latter doesn't: ``` # Some approaches that have been suggested:
# 1. Using `list()` (Bert Gunter) f1 <- function(...) list(...)[["a"]] # 2. Using `...elt()` (Bert Gunter) f2 <- function(...) ...elt(match("a", ...names())) # 3. Using argument matching (Hadley Wickham) f3 <- function(...) (\(a, ...) a)(...) # 4. Using `match.call()` f4 <- function(...) eval(match.call()[["a"]], parent.frame()) ff <- list(f1 = f1, f2 = f2, f3 = f3, f4 = f4) sapply(ff, \(f) { f(b = 2, a = 1, c = 3) }) #> f1 f2 f3 f4 #> 1 1 1 1 # View the (defused) arguments after `a` has been accessed: # returns an expression if the argument has not been evaluated, and a number if it has check_forced_args <- function(f) { body(f) <- call("{", body(f), quote(rlang::enexprs(...))) # pass `f()` some expressions to see which are evaluated f(a = cos(0), b = sqrt(4)) } # make a data frame showing the defused arguments for each function lapply(ff, check_forced_args) |> do.call(rbind, args = _) |> as.data.frame() #> a b #> f1 1 2 # all the arguments are forced #> f2 1 sqrt(4) # only `a` is forced #> f3 1 sqrt(4) # only `a` is forced #> f4 cos(0) sqrt(4) # none of the arguments are forced ``` Also, here's a possible way to adapt Hadley Wickham's approach so that it takes the name of the argument as a string, though it does lose the elegance: ``` pick_arg <- function(nm) { as.function(c( setNames(alist(. = , . = ), c(nm, "...")), as.symbol(nm) )) } z <- "a" f5 <- function(...) { pick_arg(z)(...) } f5(b = 2, a = 1, c = 3) #> [1] 1 ``` Regards, Ian ____ Ian Farm, Laboratory Manager University of Maine Agroecology Lab On Wed, Jan 8, 2025 at 5:58 PM Bert Gunter <bgunter.4...@gmail.com> wrote: > That's very nice, Hadley. Simple and clean. Never would have thought of it > myself. > > As usual, however, in the course of my churnings, I have a further > complication to add. But first ... > > **TO ALL**: Feel free to ignore the following, as I'm just fooling around > here and don't want to waste your time with my stupid stuff. > > Anyway, the complication is motivated by the use of formals() or otherwise > that *programmatically* generates a character representation of the > arguments I want to select. So, for example: > > > z <- "a" > ## Then: > f1 <- function(...){ > ...elt(match(z, ...names())) ## since z gets evaluated in the call > } > ## still works. > > f1(b =2, a=1, c=3) > [1] 1 > > But I haven't figured out how to modify your suggestion -- at least in a > simple way -- to do the same. Likely I've missed something, though. > > > Cheers, > Bert > > > > > > > On Wed, Jan 8, 2025 at 12:51 PM Hadley Wickham <h.wick...@gmail.com> > wrote: > > > I'd propose an alternative that I think is superior: rely on the > semantics > > of ... to do the work for you: > > > > f1 <- function(...){ > > one <- list(...)[['a']] > > two <- ...elt(match('a', ...names())) > > c(one, two, three(...)) > > } > > > > three <- function(a, ...) { > > a > > } > > > > f1(a = 1, b = 2, c = 3) > > #> [1] 1 1 1 > > > > > > On Sun, Jan 5, 2025 at 12:00 PM Bert Gunter <bgunter.4...@gmail.com> > > wrote: > > > >> Consider: > >> > >> f1 <- function(...){ > >> one <- list(...)[['a']] > >> two <- ...elt(match('a', ...names())) > >> c(one, two) > >> } > >> ## Here "..." is an argument list with "a" somewhere in it, but in an > >> unknown position. > >> > >> > f1(b=5, a = 2, c=7) > >> [1] 2 2 > >> > >> Which is better for extracting a specific named argument, one<- or > >> two<- ? Or a third alternative that is better than both? > >> Comments and critiques welcome. > >> > >> Cheers, > >> Bert > >> > >> ______________________________________________ > >> R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see > >> https://stat.ethz.ch/mailman/listinfo/r-help > >> PLEASE do read the posting guide > >> https://www.R-project.org/posting-guide.html > >> and provide commented, minimal, self-contained, reproducible code. > >> > > > > > > -- > > http://hadley.nz > > > > [[alternative HTML version deleted]] > > ______________________________________________ > R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide > https://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. > [[alternative HTML version deleted]] ______________________________________________ R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide https://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.