[R] Why does debugging print() change output of function?
William Dunlap
wdunlap at tibco.com
Wed Sep 10 18:06:17 CEST 2014
Another nice thing about using ~formula is that it stores the
environment in which the formula was made along with the formula.
Thus you know which envrionment should be used with evaluating it (and
don't have to guess that parent.frame() may be the right environmnet).
E.g.,
evalRHS <- function(formula) {
RHS <- formula[[length(formula)]]
eval(RHS, envir=environment(formula))
}
p1 <- 1:3
p2 <- 11:13
f1 <- function(formula) {
p1 <- 1000
evalRHS(formula)
}
f1(~p1+p2) # does not use the p1 defined in f1
# [1] 12 14 16
If you do want to override some of the variables in the formula you
can do that by replacing the environment of the formula with a child
of that environment. Do this in a function so it only replaces the
environment in a copy of the formula, not the original one.
f2 <- function(formula) {
environment(formula) <- list2env(list(p1=1000),
new.env(parent=environment(formula)))
evalRHS(formula)
}
f2(~p1+p2)
# [1] 1011 1012 1013
f1(~p1+p2)
# [1] 12 14 16
(These examples are not the best since the global environment is
searched in any case. Put the entire example inside a function to see
the strength of the formula approach.)
Bill Dunlap
TIBCO Software
wdunlap tibco.com
On Tue, Sep 9, 2014 at 10:13 PM, David Winsemius <dwinsemius at comcast.net> wrote:
>
> On Sep 9, 2014, at 4:07 PM, peter dalgaard wrote:
>
>>
>> On 07 Sep 2014, at 00:31 , David Winsemius <dwinsemius at comcast.net> wrote:
>>
>>> The goal:
>>> to create a function modeled after `subset` (notorious for its
>>> non-standard evaluation) that will take a series of logical tests as
>>> unquoted expressions to be evaluated in the framework of a dataframe
>>> environment and return a dataframe of logicals:
>>
>> ...
>>
>> A belated peep from the author of subset(): Don't!
>>
>> I think we learned the hard way by now that it is much easier to pass
>> unevaluated expressions in the shape of formula objects or maybe expression
>> objects. Lots of pain can be avoided by slipping in a simple "~".
>
>
> It's taken me several years to understand why you are probably correct in
> this regard. I needed to learn that `~` is actually a function that creates
> a language object.
>
>> is.function(`~`)
> [1] TRUE
>> is.language( ~ x > 5 & x < 10)
> [1] TRUE
>
> ... and that it's rather easy to extract the object somewhat like but not
> really an expression embedded in such an object:
>
>> is.expression( ~ x > 5 & x < 10)
> [1] FALSE
>
>> is.call( (~ x > 5 & x < 10)[2] )
> [1] TRUE
>
> The task of learning the various types of language objects is not an easy
> one.
>
> --
>
> David Winsemius, MD
> Alameda, CA, USA
>
> ______________________________________________
> 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.
More information about the R-help
mailing list