21

Hi I'm trying to name variables using a for loop so I get dynamic names for my variables.

for (i in 1:nX) {
    paste("X",i, sep="")=datos[,i+1]
    next
}
6
  • 3
    Why are you trying to do that? Use the array instead. Commented Dec 29, 2012 at 13:11
  • Hi, I have a data frame with long headers but would like to automatically set my own variables as X1, X2, etc so I can operate with them individually Commented Dec 29, 2012 at 13:27
  • 7
    Why don't you just do colNames(datos) <- paste("X", i, sep="") then? Then you can access them with datos$X1, datos$X2 etc Commented Dec 29, 2012 at 13:29
  • Thanks nico that is a nice solution! Commented Dec 29, 2012 at 13:38
  • 10
    This is faq 7.21, the most important part of that answer is the last part that says not to do this, use a list or environment. Commented Dec 29, 2012 at 14:34

2 Answers 2

34

use assign as in:

x <- 1:10

for(i in seq_along(x)){
  assign(paste('X', i, sep=''), x[i])
}
Sign up to request clarification or add additional context in comments.

3 Comments

Hi David, why do you think is a bad idea?
@user1228124 Experienced R programmers generally advise against using assign unless you are absolutely forced to. In this case, nico's suggestion of using colnames<- is safer, simpler, and easier to understand.
plus one, this saved me time
12

It can be a good idea to use assign when there are many variables and they are looked up frequently. Lookup in an environment is faster than in vector or list. A separate environment for the data objects is a good idea.

Another idea is to use the hash package. It performs lookup as fast as environments, but is more comfortable to use.

datos <- rnorm(1:10)
library(hash)
h <- hash(paste("x", 1:10, sep=""), datos)
h[["x1"]]

Here is a timing comparision for 10000 vars that are looked up 10^5 times:

datos <- rnorm(1:10000)
lookup <- paste("x", sample.int(length(datos), 100000, replace=TRUE), sep="")

# method 1, takes 16s on my machine
names(datos) <- paste("x", seq_along(datos), sep="")
system.time(for(key in lookup) datos[[key]])

# method 2, takes 1.6s on my machine
library(hash)
h <- hash(paste("x", seq_along(datos), sep=""), datos)
system.time(for(key in lookup) h[[key]])

# method 3, takes 0.2s on my machine
e <- new.env()
for(i in seq_along(datos)){
  assign(paste('x', i, sep=''), datos[i], envir=e)
}
system.time(for(key in lookup) e[[key]])

However, the vectorized version of method 1 is the fastest, but is not always applicable

# method 4, takes 0.02s
names(datos) <- paste("x", seq_along(datos), sep="")
system.time(datos[lookup])

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.