32
$\begingroup$

I wonder if there is a simple way to produce a list of variables using a for loop, and give its value.

for(i in 1:3)
{
  noquote(paste("a",i,sep=""))=i
}

In the above code, I try to create a1, a2, a3, which assign to the values of 1, 2, 3. However, R gives an error message. Thanks for your help.

$\endgroup$
7
  • 3
    $\begingroup$ I doubt you you have to do this -- it seems you're making something in a very wrong way. $\endgroup$
    – user88
    Commented May 16, 2011 at 9:36
  • $\begingroup$ @mbq, in Eviews for example this is pretty normal coding practice. Not that I am advocating it, Eviews rates only a bit lower than Excel in my top evil software list :) $\endgroup$
    – mpiktas
    Commented May 16, 2011 at 10:24
  • 7
    $\begingroup$ @mpiktas In R, it is more natural to make a list, set its names parameter and later either just use it, attach it or convert it into an environment with list2env and eval inside it. With no loops, parse or other ugly stuff. $\endgroup$
    – user88
    Commented May 16, 2011 at 10:38
  • $\begingroup$ @mbq, hm, list2env is a relatively new function. And still it will produce the variables in the some environment, when the OP wants to get the variables in the top environment. So the ugliness still remains :) $\endgroup$
    – mpiktas
    Commented May 16, 2011 at 10:49
  • 4
    $\begingroup$ For future questions of a similar nature, I'd suggest that this kind of question actually belongs on StackOverflow. The question has nothing to do with statistics per se. $\endgroup$
    – Mars
    Commented Apr 16, 2015 at 19:21

2 Answers 2

46
$\begingroup$

Your are looking for assign().

for(i in 1:3){
  assign(paste("a", i, sep = ""), i)    
}

gives

> ls()
[1] "a1"          "a2"          "a3" 

and

> a1
[1] 1
> a2
[1] 2
> a3
[1] 3

Update

I agree that using loops is (very often) bad R coding style (see discussion above). Using list2env() (thanks to @mbq for mentioning it), this is another solution to @Han Lin Shang's question:

x <- as.list(rnorm(10000))
names(x) <- paste("a", 1:length(x), sep = "")
list2env(x , envir = .GlobalEnv)
$\endgroup$
23
$\begingroup$

If the values are in vector, the loop is not necessary:

vals <- rnorm(3)
n    <- length(vals)
lhs  <- paste("a",    1:n,     sep="")
rhs  <- paste("vals[",1:n,"]", sep="")
eq   <- paste(paste(lhs, rhs, sep="<-"), collapse=";")
eval(parse(text=eq))

As a side note, this is the reason why I love R.

$\endgroup$
14
  • 4
    $\begingroup$ library(fortunes) fortune(106) $\endgroup$ Commented May 16, 2011 at 12:18
  • $\begingroup$ @Roman, strange, I've started using parse after reading R help pages. I agree that sometimes it is an overkill, for example in formula management, but I found it very useful. Note that I cannot rethink the question as suggested in the fortune, since I did not ask it. $\endgroup$
    – mpiktas
    Commented May 16, 2011 at 12:28
  • 1
    $\begingroup$ @mpiktas : it has to do with the fact that the underlying scoping rules can result in inpredictable results when used within a function. Also (as mentioned in the help files), R and S can give a different result due to the difference in scoping rules. It is also slower than other solutions. This will matter when you have to do this many times. And last but not least, in most cases there is a more elegant and easier solution than using eval(parse()). In this case that's working with lists or using assign. $\endgroup$
    – Joris Meys
    Commented May 16, 2011 at 12:40
  • 1
    $\begingroup$ @mpiktas : I never said it's deficient. I just gave you the reason why in general a eval(parse()) construct is advised against by eg Thomas Lumley, member of the R core development team. (cfr the refernce of @Roman Lustrik) $\endgroup$
    – Joris Meys
    Commented May 16, 2011 at 13:06
  • 1
    $\begingroup$ exactly, bad practice like using assign to create multiple single element variables should be discouraged $\endgroup$
    – mdsumner
    Commented May 19, 2011 at 23:27

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.