0

I keep running into situations where I want to dynamically create variables using a for loop (or similar / more efficient construct using dplyr perhaps). However, it's unclear to me how to do it right now.

For example, the below shows a construct that I would intuitively expect to generate 10 variables assigned numbers 1:10, but it doesn't work.

for (i in 1:10) {paste("variable",i,sep = "") = i}

The error

Error in paste("variable", i, sep = "") = i : 
target of assignment expands to non-language object

Any thoughts on what method I should use to do this? I assume there are multiple approaches (including a more efficient dplyr method). Full disclosure: I'm relatively new to R and really appreciate the help. Thanks!

AME
  • 339
  • 5
  • 13
  • 6
    Instead of generating 10 variables, why don't you create a list of 10 elements? – dikesh Feb 04 '16 at 14:28
  • 8
    Yes, normally it is better to create a list: `L <- setNames(vector(length = 10, "list"), paste0("var", 1:10))` – G. Grothendieck Feb 04 '16 at 14:35
  • 5
    hmmm, seems like there is a "*Post all the worst practices in R*" competition going on. – David Arenburg Feb 04 '16 at 14:38
  • 6
    It would help to provide some context surrounding the question. There may be a better way [What is the XY Problem](http://meta.stackexchange.com/a/66378) – Pierre L Feb 04 '16 at 14:44
  • 2
    This was brought up by @G.Grothendieck, though I wanted to emphasize it since it's a cool trick. You should use `paste0("variable", i)` instead of paste("variable", i, sep = "") to avoid having to specify the `sep=""` argument everytime. – Berk U. Feb 04 '16 at 14:55

3 Answers3

0

I've run into this problem myself many times. The solution is the assign command.

for(i in 1:10){
    assign(paste("variable", i, sep = ""), i)
}

If you wanted to get everything into one vector, you could use sapply. The following code would give you a vector from 1 to 10, and the names of each item would be "variable i," where i is the value of each item. This may not be the prettiest or most elegant way to use the apply family for this, but I think it ought to work well enough.

var.names <- function(x){
    a <- x
    names(a) <- paste0("variable", x)
    return(a)
}

variables <- sapply(X = 1:10, FUN = var.names)

This sort of approach seems to be favored because it keeps all of those variables tucked away in one object, rather than scattered all over the global environment. This could make calling them easier in the future, preventing the need to use get to scrounge up variables you'd saved.

spf614
  • 52
  • 6
  • 6
    `fortunes::fortune(236)` "The only people who should use the assign function are those who fully understand why you should never use the assign function." – zx8754 Feb 04 '16 at 14:45
-2

No need to use a loop, you can create character expression with paste0 and then transform it as uneveluated expression with parse, and finally evaluate it with eval.

eval(parse(text = paste0("variable", 1:10, "=",1:10, collapse = ";") ))
Mamoun Benghezal
  • 5,264
  • 7
  • 28
  • 33
  • 3
    I didn't downvote, but http://stackoverflow.com/questions/13649979/what-specifically-are-the-dangers-of-evalparse – Pierre L Feb 04 '16 at 14:42
  • 2
    @Mamoun because eval(parse is a bad practice and can lead to problems, because there's no explanation on how it works and how it solves the problem. I did not downvote, but it's a very low quality answer anyway. [See here](http://stackoverflow.com/questions/13649979/what-specifically-are-the-dangers-of-evalparse) – Tensibai Feb 04 '16 at 14:43
  • 2
    Please read this http://meta.stackoverflow.com/questions/316112/can-we-care-a-little-more-about-quality-instead-of-quantity-please – David Arenburg Feb 04 '16 at 14:47
  • 3
    `fortunes::fortune(106)` "If the answer is parse() you should usually rethink the question." – zx8754 Feb 04 '16 at 14:50
-4

The code you have is really no more useful than a vector of elements:

x<-1
for(i in 2:10){
    x<-c(x,i)
}

(Obviously, this example is trivial, could just use x<-1:10 and be done. I assume there's a reason you need to do non-vectored calculations on each variable).

Matthew
  • 4,149
  • 2
  • 26
  • 53