How do I use a variable to name another variable in R?

14,228

Solution 1

It depends bit on what you want to do, but here's an example of using get function:

x = 1
get("x") + 1

2

assign("name", get("x") + 1)
name

2

Solution 2

Why not just do all the manipulation of the variable (adding 1 or other changes) to a local copy of the variable with your own name, then at the end of the function/script/whatever do the assigning or other saving? That would be much simpler than creating the variable then having to use get to get a copy, change it, and assign it again.

Even better is to use your own variable name inside of a function, then just return the result and let the user decide what to name it at that point. This is the much more Rish way of doing things, it is best to not use the assign function at all. Most things that can be done using assign can be done much simpler by using a list and subscripting.

Functions should not change anything in the global environment, just return any values that the user might need and let the user make the assignment.

Solution 3

You can use eval and parse. The later interprets text as if it was an input in the console. The first evaluates the expression (generated by parse, for instance). Example:

> varname <- "user.defined.variable"
> varvalue <- 42
> eval(parse(text=paste(varname, varvalue, sep=" <- ")), envir=.GlobalEnv)
> ls()
[1] "user.defined.variable" "varname"               "varvalue"             
> user.defined.variable
[1] 42

Note that I've choosen the global environment as the destination for the new variable. You can make the appropriate changes if that is not the case.

To refer to the new variable later, you can use as.symbol. Just evaluate it under the environment where you assigned the new variable:

> eval(as.symbol(varname), envir=.GlobalEnv)
[1] 42

You can also use substitute to create expressions that eval can understand:

> eval(substitute(x+1, list(x=as.symbol(varname))), envir=.GlobalEnv)
[1] 43

To make changes to the new variable, just creat assignments expressions and evaluate them:

> eval(substitute(x <- x*10, list(x=as.symbol(varname))), envir=.GlobalEnv)
> eval(as.symbol(varname), envir=.GlobalEnv)
[1] 420
Share:
14,228
user2172400
Author by

user2172400

Updated on June 11, 2022

Comments

  • user2172400
    user2172400 almost 2 years

    I have a function that uses readline to allow the user to enter the name they want to give for a variable I will be creating for them. Let's call this "USER.DEFINED.VARIABLE". It contains the name I want to use for another variable. Let's say that "USER.DEFINED.VARIABLE" gets set by readline to be "jimsfilename".

    I know I can assign value to a variable named "jimsfilename" using:

    assign(USER.DEFINED.VARIABLE,c(1,2,3,4,5))
    

    "jimsfilename" will now have 1,2,3,4,5 in it. However, how do I now fuss with "jimsfilename", given that I don't (before readline assigns it to USER.DEFINED.VARIABLE) know what its name is?

    In other words, lets say I now want to add 1 to every value in jimsfilename. I can't do:

    USER.DEFINED.VARIABLE <- USER.DEFINED.VARIABLE + 1 # can't do this
    

    because "USER.DEFINED.VARIABLE" is actually a text string name. I want instead to refer to jimsfilename, but all I have is USER.DEFINED.VARIABLE to indicate it. I'm sure this is something easy...

  • IRTFM
    IRTFM about 11 years
    I think you are exposing a new user to language complexities that are not needed and more readily addressed with get.
  • flodel
    flodel about 11 years
    +1 - yes, use a list. Instead of assign do aList[[USER.DEFINED.VARIABLE]] <- c(1,2,3,4,5) and instead of get do aList[[USER.DEFINED.VARIABLE]] <- aList[[USER.DEFINED.VARIABLE]] + 1.
  • Ben Bolker
    Ben Bolker about 11 years
    agree very much with @DWin. I'm tempted to downvote this answer because I think it's really bad advice even though I can see it is offered in good faith.
  • Ferdinand.kraft
    Ferdinand.kraft about 11 years
    @BenBolker, @DWin. Folks, let's not underestimate our new users... When I was a complete newbie to R, I was puzzled with all those deparse's and substitutes'. But being exposed to it didn't caused me any effect other than stimulating me to actually understand what was going on. And if I figured it out (at least to some degree, infinitesimally greater than zero), then others can work it out too.
  • Ben Bolker
    Ben Bolker about 11 years
    I don't think they won't necessarily understand it (although that's part of it); I think it's the wrong way to tackle this problem. The best, most idiomatic way is to use lists; get and assign are second best: and eval/parse are third best. library(fortunes); fortune(106) says "If the answer is parse() you should usually rethink the question. (Thomas Lumley)". Experienced users have been bitten by parse/substitute weirdness, and learned to avoid them unless they are absolutely necessary ...
  • Ferdinand.kraft
    Ferdinand.kraft about 11 years
    @BenBolker, I just installed the fortunes package. LOL. Thanks for the link. Well, I must confess. I didn't aim only at solving his immediate problem but also at introducing him some nice features of the language.