Sorkin, John
2023-Mar-16 12:11 UTC
[R] Trying to learn how to write an "advanced" function
I am trying to understand how to write an "advanced" function. To do so, I am examining the lm fucnction, a portion of which is pasted below. I am unable to understand what match.call or match does, and several other parts of lm, even when I read the help page for match.call or match. (1) can someone point me to an explanation of match.call or match that can be understood by the uninitiated? (2) can someone point me to a document that will help me learn how to write an "advanced" function? Thank you, John> lmfunction (formula, data, subset, weights, na.action, method = "qr", model = TRUE, x = FALSE, y = FALSE, qr = TRUE, singular.ok = TRUE, contrasts = NULL, offset, ...) { ret.x <- x ret.y <- y cl <- match.call() mf <- match.call(expand.dots = FALSE) m <- match(c("formula", "data", "subset", "weights", "na.action", "offset"), names(mf), 0L)
? Thu, 16 Mar 2023 12:11:35 +0000 "Sorkin, John" <jsorkin at som.umaryland.edu> ?????:> (1) can someone point me to an explanation of match.call or match > that can be understood by the uninitiated? (2) can someone point me > to a document that will help me learn how to write an "advanced" > function?By "advanced" functions, you seem to mean non-standard evaluation. See this chapter in the first edition of Advanced R: http://adv-r.had.co.nz/Computing-on-the-language.html Additionally, a search for "R non-standard evaluation" should give you other useful results. Note that non-standard evaluation is hard to get right for all cases, and such bugs surface even in R itself from time to time: https://bugs.r-project.org/show_bug.cgi?id=18368 -- Best regards, Ivan
Rasmus Liland
2023-Mar-16 12:42 UTC
[R] Trying to learn how to write an "advanced" function
On 2023-03-16 12:11 +0000, Sorkin, John wrote:> (1) can someone point me to an > explanation of match.call or match > that can be understood by the > uninitiated?Dear John, the man page ?match tells us that match matches the first vector against the second, and returns a vector of indecies the same length as the first, e.g. > match(c("formula", "data", "subset", "weights", "na.action", "offset"), c("Maryland", "formula", "data", "subset", "weights", "na.action", "offset", "Sorkin", "subset"), 0L) [1] 2 3 4 5 6 7 perhaps a bad answer ...> (2) can someone point me to a document > that will help me learn how to write > an "advanced" function?Perhaps the background here is looking at the lm function as a basis for writing something more advanced, then the exercise becomes looking at dput(lm), understanding every line by looking up all the functions you do not understand in the man pages e.g. ?match. Remember, you can search for things inside R by using double questionmark, ??match, finding versions of match existing inside other installed packages, e.g. raster::match and posterior::match, perhaps this exercise becomes writing ones own version of lm inside ones own package? Best, Rasmus
The first thing to understand is that despite similarity in names, `match` and `match.call` are doing very different things, which should not be confused with each other. For understanding what a function is doing, it is helpful to watch what it does at each step. With functions like `lm` that are built in, we cannot easily modify the source code with print statements and the like, then rerun, but the `trace` and `browser` functions are nice for allowing us to debug these functions. If you run the following line: trace(lm, browser, at=7) Then this will insert a call to `browser` into the `lm` function which when you next run `lm` will pause at about line 7 (just after the code that you show) and allow you to examine the values of `mf` and `m` and any other variables. Unfortunately just printing `mf` is not super helpful for this, since it prettys the call, but printing as.list(mf) is more useful. Basically mf will hold information on how `lm` was called, the first element is that `lm` is the function that was called, then further elements are the arguments that were passed in. The line with `match` then identifies which elements of mf correspond to the list of arguments that we want to keep for the next part (essentially the next few lines create a call object to the `model.frame` funcion with the same arguments that you passed to `lm` but without any arguments not in the short list. When in `browser` mode you can step through the evaluation of the function with "s" or "n" and quit everything with "Q" (see ?browser for details) Don't forget to call `untrace(lm)` when you are through. On Thu, Mar 16, 2023 at 6:16?AM Sorkin, John <jsorkin at som.umaryland.edu> wrote:> > I am trying to understand how to write an "advanced" function. To do so, I am examining the lm fucnction, a portion of which is pasted below. I am unable to understand what match.call or match does, and several other parts of lm, even when I read the help page for match.call or match. > (1) can someone point me to an explanation of match.call or match that can be understood by the uninitiated? > (2) can someone point me to a document that will help me learn how to write an "advanced" function? > > Thank you, > John > > > lm > function (formula, data, subset, weights, na.action, method = "qr", > model = TRUE, x = FALSE, y = FALSE, qr = TRUE, singular.ok = TRUE, > contrasts = NULL, offset, ...) > { > ret.x <- x > ret.y <- y > cl <- match.call() > mf <- match.call(expand.dots = FALSE) > m <- match(c("formula", "data", "subset", "weights", "na.action", > "offset"), names(mf), 0L) > ______________________________________________ > 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 http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code.-- Gregory (Greg) L. Snow Ph.D. 538280 at gmail.com
In addition to what has already been suggested, you can use debug (and subsequently undebug) to browse a function step by step to see what each step of the function is doing. For your specific query about match.call(), I suspect that your 'puzzlement' is that you don't know what a function call is exactly. The references you were given or even an internet search would help with that.Perhaps this also might be useful: f <- function(x,yikes,wt=3,...) match.call() z <- f(y = 0, x = 2, more = 'a') z str(z) as.list(z) Cheers, Bert On Thu, Mar 16, 2023 at 5:16?AM Sorkin, John <jsorkin at som.umaryland.edu> wrote:> I am trying to understand how to write an "advanced" function. To do so, I > am examining the lm fucnction, a portion of which is pasted below. I am > unable to understand what match.call or match does, and several other > parts of lm, even when I read the help page for match.call or match. > (1) can someone point me to an explanation of match.call or match that can > be understood by the uninitiated? > (2) can someone point me to a document that will help me learn how to > write an "advanced" function? > > Thank you, > John > > > lm > function (formula, data, subset, weights, na.action, method = "qr", > model = TRUE, x = FALSE, y = FALSE, qr = TRUE, singular.ok = TRUE, > contrasts = NULL, offset, ...) > { > ret.x <- x > ret.y <- y > cl <- match.call() > mf <- match.call(expand.dots = FALSE) > m <- match(c("formula", "data", "subset", "weights", "na.action", > "offset"), names(mf), 0L) > ______________________________________________ > 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 > http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >[[alternative HTML version deleted]]
Maybe Matching Threads
- Trying to learn how to write an "advanced" function
- R Processing dataframe by group - equivalent to SAS by group processing with a first. and retain statments
- Syntax for fit.contrast (from package gmodels)
- Mean of a row of a data frame
- Syntax for fit.contrast (from package gmodels)