1

Context

I have a named vector q1 = 2. The object name is stored in a = 'q1'.

I can change q1's name by names(q1) = 'this_is_name'.

Then I trid to use non standard evaluation to change q1's name.

I thought names(q1) = 'new_name' and names(sym(a)) = 'new_name' will do the same, but it is not.

Question

How can I rename the object that get access by a in R?

In other word, How can I make names(sym(a)) = 'new_name' do the same as names(q1) = 'new_name'.

Reproducible code

q1 = 2
names(q1) = 'this_is_name'
a = 'q1'


names(q1) = 'new_name' 

names(sym(a)) = 'new_name' # I expect the code should do the same as names(q1) = 'new_name' 

zhiwei li
  • 1,635
  • 8
  • 26

2 Answers2

3

To actually change the object q1 you can use get and assign, both in base R

assign(a, setNames(get(a), 'new_name'))

q1
#> new_name 
#>        2

Created on 2022-10-09 with reprex v2.0.2

Allan Cameron
  • 147,086
  • 7
  • 49
  • 87
  • This does not literally change the object. It creates a new object of the same name overwriting the old object. This is transparent to the user who may not care what is happening internally but just wanted to clarify what "change the object" means. – G. Grothendieck Oct 09 '22 at 12:51
  • @G.Grothendieck yes, fair point. I guess that could potentially be an issue with very large objects where read/write time is a concern. Still, fairly succinct and transparent code for most use cases. Using your method (or even avoiding creating a new environment by using `attr(as.environment(find(a))[[a]], 'name') <- 'new_name'` ) might be better if performance was a worry. – Allan Cameron Oct 09 '22 at 13:05
  • My answer also makes a copy so I don't think there is a material performance difference. Note that `attr(as.environment(find(a))[[a]], 'name') <- 'new_name'` results in an Error. – G. Grothendieck Oct 09 '22 at 13:48
3

Assuming that we have run the code in the Note at the end (copied from the question) this changes the name of q1. This does change the address of q1 internally but it is transparent to the user who is not affected. It uses only base R and does not use eval -- the use of which is generally frowned upon.

e <- environment()
names(e[[a]]) <- "new name"

q1
## new name 
##        2 

or as a one-liner

with(list(e = environment()), names(e[[a]]) <- "new name")

q1
## new name 
##        2 

Note

q1 = 2
names(q1) = 'this_is_name'
a = 'q1'
G. Grothendieck
  • 254,981
  • 17
  • 203
  • 341