1

I would like to add a column to every data frame in my R environment which all have the same format. I can create the column I want with a simple assignment like this:

x[,8] <- x[,4]/(x[,4]+x[,5])

When I try to put this in a for loop that will iterate over every object in the environment, I get an error.

control_data <- ls()

for (i in control_data) {(i[,8] <- i[,4]/(i[,4]+i[,5]))}

Error: unexpected '[' in "for (i in control_data) {["

Here is what the input files look like:

ENSMUSG00000030088  Aldh1l1 chr6:90436420-90550197  1.5082200   3.130860    0.671814    0.0000000
ENSMUSG00000020932  Gfap    chr11:102748649-102762226   7.0861500   44.182700   20.901700   0.2320750
ENSMUSG00000024411  Aqp4    chr18:15547902-15562193 3.4920400   3.474880    2.463230    0.0331238
ENSMUSG00000023913  Pla2g7  chr17:43705046-43749150 1.5105400   24.275600   11.422400   1.5111100
ENSMUSG00000035805  Mlc1    chr15:88786313-88809437 1.9010200   7.147400    5.313190    0.6358940
ENSMUSG00000007682  Dio2    chr12:91962993-91976878 1.7322900   12.094200   6.738320    1.0736900
ENSMUSG00000017390  Aldoc   chr11:78136469-78141283 55.4562000  199.958000  91.328300   22.9541000
ENSMUSG00000005089  Slc1a2  chr2:102498815-102630941    63.7394000  130.729000  103.710000  10.0406000
ENSMUSG00000070880  Gad1    chr2:70391128-70440071  2.6501400   14.907500   13.730200   1.3992200
ENSMUSG00000026787  Gad2    chr2:22477724-22549394  3.9908200   11.308600   28.221500   1.4530500

Thank you for any help you could provide. Is there a better way to do this using an apply function?

Community
  • 1
  • 1
JoshuaA
  • 279
  • 4
  • 11
  • Note that your loop is actually looping over a character vector and you can't use [] notation on a character vector. – Dason Jun 19 '12 at 20:16
  • `eapply` is used to apply a function to every object in an environment, but doing this on your `.GlobalEnv` is probably a bad idea. – GSee Jun 19 '12 at 20:20
  • I think you would get better answers if you provide a [reproducible example](http://stackoverflow.com/q/5963269/289572) as there may be multiple ways of solving this, e.g.: `(e)apply` and `eval(parse(...))` (as already suggested), but also possibly other ways with the results of `ls()` via `assign` or `get`. – Henrik Jun 19 '12 at 20:24

1 Answers1

2

As mentioned in the comment, your error happens because the results of calling ls are not the objects themselves but rather their names as strings.

To use the for-loop, you'll be headed down the eval(parse(...)) path. You can also do this with apply and a function.

myfun <- function(x) {
  df <- get(x)
  df[,8] <- df[,4] / (df[,4] + df[,5])
  return(df)
}

control_data <- ls()

lapply(control_data, myfun)

As per the comment:

for(i in control_data) {
  df <- get(i)
  df[,8] <- df[,4] / (df[,4] + df[,5])
  assign(i, df)
}
Justin
  • 42,475
  • 9
  • 93
  • 111
  • you can use `get` and `assign` in a for loop and not use `eval(parse(...))` – GSee Jun 19 '12 at 20:22
  • Wonderful. Thank you for the help. I am just getting into the apply functions in R and I can see their usefulness. The myfun you defined prints the correct output, but does not actually update the objects. How would I change it to do this? – JoshuaA Jun 19 '12 at 21:18