0

I want to apply a certain operation to several (sequentially named) variables using a for loop to shorten the following piece of code:

for(i in 1:ncol(data)) {assign(paste('var', i, sep = '.'), my.fun(data[,i]))}

result.1 <- new.fun(var.1)
result.2 <- new.fun(var.2)
result.3 <- new.fun(var.3)
...

so, how do I call the existing variables var.1, var.2, ....? I tried paste here, too, but that didn't work.

user1353751
  • 1
  • 1
  • 1
  • I think you need to use `get`, although I'm not quite sure what your question is. See e.g. http://stackoverflow.com/questions/10248778/using-do-loops-in-r-to-create-new-variables – Ben Bolker Apr 24 '12 at 13:39

2 Answers2

7

Short answer: don't do that; use a list instead.

Assuming data is a data.frame:

vars <- lapply(data, my.fun)
results <- lapply(vars, new.fun)
Joshua Ulrich
  • 173,410
  • 32
  • 338
  • 418
  • That's a nice piece of code that already solves some of my problems. However, I'd like to do this with lists, too, which I can't combine to data.frames. I'm sorry, my approach might be a bit clumsy, but is there a way to insert the list names into a for loop? – user1353751 Apr 24 '12 at 14:07
  • 2
    @user1353751: you don't have to convert the result to a data.frame; that was my assumption and I've removed it from my answer. As Ben Bolker commented, use `get` on a character string. I still strongly encourage you not to do that. It's not just clumsy, it's also more error-prone, difficult to debug, and difficult for others to understand compared to just using lists. – Joshua Ulrich Apr 24 '12 at 14:26
6

To expand on @Joshua's answer, if your data is already in variables like var.1, var.2, ... then you can combine them into a list using code like:

mydata <- lapply( paste('var.', 1:10, sep=''), get )

or

mydata <- lapply( paste0('var.',1:10), get )

or

mydata <- lapply( sprintf('var.%d',1:10), get )

With the last one you can use "var%03d" if you have varible names like var001, var002, ...

If you then want the terms in the list named (not needed, but can be nice) you can just do:

names(mydata) <- sprintf('var.%d', 1:10)

Now if you want to access a single element of the list you can access it with mydata[[3]] or mydata$var.3. But the big advantage is that you can now use lapply or sapply or vapply or other tools to run the same function on each element of the list, and if you want to save, copy, delete, etc. the data you just have one object to worry about instead of needing another loop.

For future projects it is best to read or create the data directly into a list to begin with rather than creating the individual variables first.

Greg Snow
  • 48,497
  • 6
  • 83
  • 110