How do I use a variable to name another variable in R?
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
user2172400
Updated on June 11, 2022Comments
-
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 byreadline
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 about 11 yearsI think you are exposing a new user to language complexities that are not needed and more readily addressed with
get
. -
flodel about 11 years+1 - yes, use a list. Instead of
assign
doaList[[USER.DEFINED.VARIABLE]] <- c(1,2,3,4,5)
and instead ofget
doaList[[USER.DEFINED.VARIABLE]] <- aList[[USER.DEFINED.VARIABLE]] + 1
. -
Ben Bolker about 11 yearsagree 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 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 andsubstitutes
'. 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 about 11 yearsI 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
andassign
are second best: andeval
/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 byparse
/substitute
weirdness, and learned to avoid them unless they are absolutely necessary ... -
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.