I am trying to update a call for a new function I developed with a new class. The developing is pretty similar to linmod
found in Leish's article "Creating R packages".
Inside the function, the call is stored with match.call()
.
When I try to update the call, as follows:
library(MASS)
fit <- linmod(Hwt~Bwt*Sex, data=cats)
update(fit, subset = -1)
I got the following error message:
Error in eval(expr, envir, enclos) : could not find function "linmod.formula"
The problem seems to be that match.call()
saves the full S3 method name (linmod.formula
), instead of just the generic function name (linmod
), which would work perfectly.
Anyone could help me how to solve this problem?
Since this hasn't been mentioned here yet, and it is the approach explicitly recommended in ?update
: write a method for getCall
. From ?update
:
“Extracting the call” in
update()
and similar functions usesgetCall()
which itself is a (S3) generic function with a default method that simply gets x$call. Because of this,update()
will often work (via its default method) on new model classes, either automatically, or by providing a simplegetCall()
method for that class.
So, in your package, if you have:
#' @export
f <- function(x) {
UseMethod("f")
}
#' @export
f.bar <- function(x) {
structure(list(x = x, call = match.call()), class = "fbar")
}
#' @export
#' @importFrom stats getCall
getCall.fbar <- function(x) {
x$call[[1L]] <- quote(f) # replacing `f.bar`
x$call
}
Then, in your script, you could do:
x1 <- structure(1, class = "bar")
x2 <- structure(2, class = "bar")
fx1 <- f(x = x1)
fx2 <- update(fx1, x = x2)
fx1
# $x
# [1] 1
# attr(,"class")
# [1] "bar"
#
# $call
# f.bar(x = x1)
#
# attr(,"class")
# [1] "fbar"
fx2
# $x
# [1] 2
# attr(,"class")
# [1] "bar"
#
# $call
# f.bar(x = x2)
#
# attr(,"class")
# [1] "fbar"