2

In my R function, I am dealing with a character string containing the name of an object that is sitting somewhere in the workspace. I would like to overwrite the object (e.g., convert the object to a matrix).

However, I only know the name of the object as a character string, and I don't have the object reference. I know I can convert the character string to an object reference either by using the get(x) function (where x is the string referring to the object), or by something like eval(as.name(x)). However, this works only for accessing the object, not for overwriting the object.

How can I achieve this? Here is some code:

myvector <- 1:5              # my object
x <- "myvector"              # text representation of the object
get(x) <- as.matrix(get(x))  # my first attempt
eval(as.name(x)) <- as.matrix(eval(as.name(x)))  # second attempt

Note that the first line is not part of the function from which I want to overwrite this object in the workspace, so I cannot just write myvector <- as.matrix(myvector).

Philip Leifeld
  • 2,253
  • 15
  • 24

1 Answers1

3

You try to assign by name a global variable within a function. Why? Should avoid to manipulate global variable and as said in the comment should exist better manner to deal with your problem and avoid global variable side effect.
You should use assign to change value by name. By default, it changes value in the current environment(local), So you should also set in which environment your variable is defined. Something like this :

 assign( x , as.matrix(get(x)),envir=.GlobalEnv)

Or , tell assign to search until it encounters the variable :

 assign( x , as.matrix(get(x)),inherits=TRUE)

EDIT better solution

  1. Return the new value and assign it later in the global environment

    assign( x , function(x){....})
    
  2. If the variable is kind of global setting you can define an environment where your define myvector.

    myoptions <- new.env()
    myoptions$myvalue <- 1:5
    function(x){ assign(x,newvalue,myoptions )}
    
agstudy
  • 119,832
  • 17
  • 199
  • 261
  • Thanks for the hint. I am not very familiar with environments. It would be OK if the object was copied from the global environment to the function and overwritten only inside the function. Or if a new object with the same name was created locally within the function (instead of overwriting it). – Philip Leifeld Jul 08 '13 at 09:57
  • @SpammerSlammer Better is to return the new value and assign it later in the global environment. – agstudy Jul 08 '13 at 10:05
  • @SpammerSlammer you can see my edit. I suggest a couple of solutions. – agstudy Jul 08 '13 at 10:11
  • I don't really understand your edits, but your original solution seems to work for me. I need a new object in the local environment (that is, inside the function only) which has the same name as the object in the global environment but to which I can assign a new value. The local object is only used for estimations within the function, but it is crucial that it has the same name as the global object. So I think this can be achieved using `assign(x, as.matrix(get(x)))` inside my function without any additional option. (At least it seemed to work when I tried it.) – Philip Leifeld Jul 08 '13 at 10:55
  • 1
    You said: "it is crucial that it has the same name as the global object" ? why? poor design here! – agstudy Jul 08 '13 at 11:03
  • Because: There is a function contained in a package which has a formula syntax where elements can be functions that need to be evaluated. Example: `y ~ object1 + doSomething(object2, arg = someArgument)`. I don't have access to the functions contained in that package, but my task is to write a function that creates a formula like the one shown here. So in my function, the user should hand over a formula, then I should transform the objects from this formula locally (thus I need the object references), then I should reassemble the formula and hand it over to the estimation in the other package. – Philip Leifeld Jul 08 '13 at 14:30
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/33087/discussion-between-agstudy-and-spammerslammer) – agstudy Jul 08 '13 at 14:39