ggg
ggg

Reputation: 1979

"with" function behaviour

Can anyone explain what causes the error in the last line of the code? Is it a bug?

> ll <- list(a=1, b=2)
> ee <- as.environment(ll)
> ee
<environment: 0x0000000004d35810>
> ls(ee)
[1] "a" "b"
> with(ee, a)
[1] 1
> with(ee, a - b)
Error in eval(expr, envir, enclos) : could not find function "-"
> 

Upvotes: 6

Views: 6619

Answers (2)

Gavin Simpson
Gavin Simpson

Reputation: 174813

This is due to R's scoping. It needs to find the function "-"(). You told R to evaluate your expression in the environment ee. There is no function "-"() there, so proceeded to the parent environment of ee, which is:

> parent.env(ee)
<environment: R_EmptyEnv>

where there is no function "-"() either. As there is no parent environment to the empty environment

> parent.env(parent.env(ee))
Error in parent.env(parent.env(ee)) : the empty environment has no parent

R gave up the search and threw an error.

We can solve the problem by attaching a parent environment to ee where R can find the function:

> parent.env(ee) <- .BaseNamespaceEnv
> with(ee, a - b)
[1] -1

But I think this would be more natural, to set the parent of ee to be the global environment:

> parent.env(ee) <- globalenv()
> with(ee, a - b)
[1] -1

a and b will always be found in ee as that is the first scoping environment encountered, but the functions can be looked up in the usual place, as if running this at the command line. If you are doing this in a function call, then you'll need to assign the correct environment.

Upvotes: 15

Richie Cotton
Richie Cotton

Reputation: 121077

The - function isn't visible from the environment that you created.

If you assign it there,

ee$`-` <- `-`

then your example will work.

Upvotes: 5

Related Questions