stumped by eval
Ross Boylan wrote:
In the following example, the inner evaluation pulls in the global value
of subset (a function) rather than the one I thought I was passing in (a
vector). Can anyone help me understand what's going on, and what I need
to do to fix the problem?
f0 <- function(formula, data,
subset, na.action
)
{
f1(formula, data,
subset, na.action
)
}
f1 <- function (formula, data,
subset, na.action
)
{
mf <- match.call()
mf[[1]] <- as.name("model.frame")
mf <- eval(mf, parent.frame())
}
netto <- data.frame(Reading=seq(3), Spec=seq(3), Reader=seq(3))
t3 <- f0(Reading~0+Spec+Reader, netto, c(1))
Error in xj[i] : invalid subscript type 'closure'
traceback()
7: `[.data.frame`(list(Reading = 1:3, Spec = 1:3, Reader = 1:3),
function (x, ...)
UseMethod("subset"), , FALSE)
6: model.frame.default(formula = formula, data = data, subset = subset,
na.action = na.action)
5: model.frame(formula = formula, data = data, subset = subset,
na.action = na.action)
4: eval(expr, envir, enclos)
3: eval(mf, parent.frame())
2: f1(formula, data, subset, na.action)
1: f0(Reading ~ 0 + Spec + Reader, netto, c(1))
I started with a case in which f0 was called with only 2 arguments
(i.e., subset was missing), and that is the case I'm ultimately
interested in. However, even the situation above is failing.
According to resume, the class of subset is numeric in frames 2 and 4,
but a function in frames 3 and 5. That may be correct for frame 3,
since it is the evaluation function without a named argument subset (and
thus it picks up the global value). But it's wrong for 5 (and higher).
eval itself is primitive; I don't understand exactly what is going on
with the 2 entries for it (frames 3 + 4).
Yes, this is elusive, but it is not actually eval() that is doing you in. It is the notion of a model environment, see the last bit of ?formula. The point is that subset (and offset) arguments are subject to the same evaluation rules as the terms inside the formula: First look in "data", then in the environment of the formula, which in this case is the global environment. This behaviour is generally a good thing because it prevents you from accidentally picking up internal variables of f1, but working around it can be a little painful. As far as I recall, you can use an explicit substitute of the subset argument.
R package 2.6.1-1 on Debian GNU/Linux.
______________________________________________ R-help at r-project.org mailing list 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.
O__ ---- Peter Dalgaard ?ster Farimagsgade 5, Entr.B c/ /'_ --- Dept. of Biostatistics PO Box 2099, 1014 Cph. K (*) \(*) -- University of Copenhagen Denmark Ph: (+45) 35327918 ~~~~~~~~~~ - (p.dalgaard at biostat.ku.dk) FAX: (+45) 35327907