109

Is it possible to create new variable names on the fly?

I'd like to read data frames from a list into new variables with numbers at the end. Something like orca1, orca2, orca3...

If I try something like

paste("orca",i,sep="")=list_name[[i]]

I get this error

target of assignment expands to non-language object

Is there another way around this?

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
Maiasaura
  • 32,226
  • 27
  • 104
  • 108
  • 11
    As long as we're giving out r-faq tags let's give the link (FAQ 7.21: http://cran.r-project.org/doc/FAQ/R-FAQ.html#How-can-I-turn-a-string-into-a-variable_003f ) – Ben Bolker May 19 '11 at 14:33

6 Answers6

135

Use assign:

assign(paste("orca", i, sep = ""), list_name[[i]])
BroVic
  • 979
  • 9
  • 26
Shane
  • 98,550
  • 35
  • 224
  • 217
  • 31
    This is how to do this. There's a meta-question here which is, "Should I do this?" The answer is almost always "no". Named elements in a list are almost always preferred. – Ari B. Friedman Jul 20 '12 at 16:18
  • 29
    The answer is almost always "no" except when it isn't. – Shane Aug 02 '12 at 12:33
  • 11
    Well of course. But most people seeking this answer aren't doing so from a position of having rejected a list for their application. – Ari B. Friedman Aug 02 '12 at 13:15
  • @Ari B. Friedman I generate variable names for datasets I save in mypackage/data. Each one in its file with same name for the file and the data in it (given R recommendations for data in package). Each dataset is about 10M and the total is ~ 17Go I hardly see an other way. – cmbarbu Feb 16 '16 at 11:19
  • What if my new variable is a column name and I want to name it on the fly like XYZ$assign... I guess I can not use it like this? – Abhishek Singh Jul 04 '17 at 07:57
  • 4
    Is there any reason why you didn't use `paste0`? – BroVic Jul 05 '18 at 15:11
  • This is a bad solution. – Konrad Rudolph Sep 01 '21 at 14:31
36

It seems to me that you might be better off with a list rather than using orca1, orca2, etc, ... then it would be orca[1], orca[2], ...

Usually you're making a list of variables differentiated by nothing but a number because that number would be a convenient way to access them later.

orca <- list()
orca[1] <- "Hi"
orca[2] <- 59

Otherwise, assign is just what you want.

John
  • 23,360
  • 7
  • 57
  • 83
  • 11
    I agree. Usually when people think they want to name variables on the fly, what they really want is a different data structure. – Michael Dunn Apr 21 '10 at 05:55
  • 9
    +1 (FAQ 7.21: http://cran.r-project.org/doc/FAQ/R-FAQ.html#How-can-I-turn-a-string-into-a-variable_003f ) discusses this nicely – Ben Bolker May 19 '11 at 14:35
11

Don't make data frames. Keep the list, name its elements but do not attach it.

The biggest reason for this is that if you make variables on the go, almost always you will later on have to iterate through each one of them to perform something useful. There you will again be forced to iterate through each one of the names that you have created on the fly.

It is far easier to name the elements of the list and iterate through the names.

As far as attach is concerned, its really bad programming practice in R and can lead to a lot of trouble if you are not careful.

zx8754
  • 52,746
  • 12
  • 114
  • 209
sidquanto
  • 315
  • 3
  • 6
5

FAQ says:

If you have

varname <- c("a", "b", "d")

you can do

get(varname[1]) + 2

for

a + 2

or

assign(varname[1], 2 + 2)

for

a <- 2 + 2

So it looks like you use GET when you want to evaluate a formula that uses a variable (such as a concatenate), and ASSIGN when you want to assign a value to a pre-declared variable.

Syntax for assign: assign(x, value)

x: a variable name, given as a character string. No coercion is done, and the first element of a character vector of length greater than one will be used, with a warning.

value: value to be assigned to x.

Mox
  • 511
  • 5
  • 15
0

Another tricky solution is to name elements of list and attach it:

list_name = list(
    head(iris),
    head(swiss),
    head(airquality)
    )

names(list_name) <- paste("orca", seq_along(list_name), sep="")
attach(list_name)

orca1
#   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# 1          5.1         3.5          1.4         0.2  setosa
# 2          4.9         3.0          1.4         0.2  setosa
# 3          4.7         3.2          1.3         0.2  setosa
# 4          4.6         3.1          1.5         0.2  setosa
# 5          5.0         3.6          1.4         0.2  setosa
# 6          5.4         3.9          1.7         0.4  setosa
Marek
  • 49,472
  • 15
  • 99
  • 121
0

And this option?

list_name<-list()
for(i in 1:100){
    paste("orca",i,sep="")->list_name[[i]]
}

It works perfectly. In the example you put, first line is missing, and then gives you the error message.

Vincent Bonhomme
  • 7,235
  • 2
  • 27
  • 38
gla
  • 43
  • 3
  • 3
    This doesn't address OP's question. We have a list with dataframes, and we want to assign it to dataframes, named as orca1, orca2, etc. – zx8754 Oct 27 '16 at 19:57
  • "List with dataframes" = "list OF dataframes"? – Mox Apr 04 '18 at 21:54