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!

5
  • 6
    Instead of generating 10 variables, why don't you create a list of 10 elements? Commented Feb 4, 2016 at 14:28
  • 8
    Yes, normally it is better to create a list: L <- setNames(vector(length = 10, "list"), paste0("var", 1:10)) Commented Feb 4, 2016 at 14:35
  • 5
    hmmm, seems like there is a "Post all the worst practices in R" competition going on. Commented Feb 4, 2016 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 Commented Feb 4, 2016 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. Commented Feb 4, 2016 at 14:55

3 Answers 3

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.

Sign up to request clarification or add additional context in comments.

1 Comment

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."
-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 = ";") ))

4 Comments

@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
fortunes::fortune(106) "If the answer is parse() you should usually rethink the question."
-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).

2 Comments

OP is trying to create 10 variables, not one vector with ten elements.
And no, we don't grow objects in a loop in R.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.