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 ________________________________________ From: R-help <r-help-bounces at r-project.org> on behalf of Bert Gunter <bgunter.4567 at gmail.com> Sent: Monday, January 6, 2025 5:22 PM To: Jorgen Harmse Cc: r-help at r-project.org Subject: Re: [R] Extracting specific arguments from "..." 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))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:> f(a = 'red', b = sin(zzz))$bsin(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:> 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: > > > > I would use two because it does not force the evaluation of the other > arguments in the ... list. > > > > > > > > On Sun, Jan 5, 2025, 13:00 Bert Gunter <bgunter.4567 at 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 at 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 at 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.
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:> 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 > > > > > ________________________________________ > From: R-help <r-help-bounces at r-project.org> on behalf of Bert Gunter < > bgunter.4567 at gmail.com> > Sent: Monday, January 6, 2025 5:22 PM > To: Jorgen Harmse > Cc: r-help at r-project.org > Subject: Re: [R] Extracting specific arguments from "..." > > 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)) > 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: > > f(a = 'red', b = sin(zzz))$b > 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: > > > 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: > > > > > > I would use two because it does not force the evaluation of the other > > arguments in the ... list. > > > > > > > > > > > > On Sun, Jan 5, 2025, 13:00 Bert Gunter <bgunter.4567 at 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 at 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 at 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]]
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:>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 > > > > >________________________________________ >From: R-help <r-help-bounces at r-project.org> on behalf of Bert Gunter <bgunter.4567 at gmail.com> >Sent: Monday, January 6, 2025 5:22 PM >To: Jorgen Harmse >Cc: r-help at r-project.org >Subject: Re: [R] Extracting specific arguments from "..." > >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)) >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: >> f(a = 'red', b = sin(zzz))$b >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: > >> 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: >> > >> > I would use two because it does not force the evaluation of the other >> arguments in the ... list. >> > >> > >> > >> > On Sun, Jan 5, 2025, 13:00 Bert Gunter <bgunter.4567 at 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 at 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 at 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. >______________________________________________ >R-help at 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.-- Sent from my phone. Please excuse my brevity.