[R] How to modify object's code living in some environment?
Duncan Murdoch
murdoch@dunc@n @end|ng |rom gm@||@com
Mon Dec 27 14:27:28 CET 2021
On 27/12/2021 8:25 a.m., Duncan Murdoch wrote:
> On 27/12/2021 8:06 a.m., Grzegorz Smoliński wrote:
>> Hi,
>>
>> I know it is possible to find the environment in which some object
>> lives using the 'environment()' function and the name of this object,
>> but how to modify code of this object after this? Below is MRE:
>
> You are misunderstanding the relation between environments and
> functions. However, your understanding is also being messed up by a bug
> in R, so it's not entirely your fault.
>
> More details below:
>>
>> test <- function() 1
>>
>> test() # 1
>>
>> environment(test)$test <- eval(parse(text = "function() 2"))
>
> First: while it's usually true that function f will be found in
> environment(f), these are really separate concepts.
>
> The environment of a function is where it will start looking for
> non-local variables. It is initially the environment in which the
> function definition is evaluated.
>
> The environment holding a function can be completely different. This
> most commonly shows up when you have functions that create other
> functions. For example,
>
> factory <- function(x) {
> force(x)
> function() print(x)
> }
>
> f <- factory(3)
> f()
>
> which will print 3. Here environment(f) is the evaluation frame of the
> call to factory(3), while f is not stored there, it is stored in the
> global environment. (If you run ls(environment(f)) you won't see "f"
> listed, only "x".)
>
> In your first line "test <- function() 1" you create a function named
> test in the global environment whose environment is also the global
> environment.
>
> The third line should do what you want, i.e. put the new definition into
> the environment of the test function, using the name test, but it
> doesn't: I think that's a bug in R. It should be equivalent to
>
> .GlobalEnv$test <- eval(parse(text = "function() 2"))
>
> or
>
> test <- eval(parse(text = "function() 2"))
>
> but as you saw, it's not. They do what you were expecting your third
> line to do.
>
>>
>> test() # still 1
>>
>> .GlobalEnv$test <- eval(parse(text = "function() 3"))
>>
>> test() # 3
>>
>> The context is I have shiny app which code I would like to modify (add
>> something) and the only way to refer to this environment I know is to
>> use 'environment()' (as I see, those functions do not live in
>> .GlobalEnv), but as you can see above, I can't use it to modify the
>> code.
>
> You can, as long as you work around the bug in R. Just change that
> third line into two statements:
>
> e <- environment(test)
> e$test <- eval(parse(text = "function() 2"))
>
And I forgot to mention, as Ivan did, that this might not do what you
want, because of the difference in the concepts of "environment(f)" and
"environment where f is found".
Duncan Murdoch
More information about the R-help
mailing list