1

I've written an apply where I want to 'loop' over a subset of the columns in a dataframe and print some output. For the sake of an example I'm just transforming based on dividing one column by another (I know there are other ways to do this) so we have:

apply(df[c("a","b","c")],2,function(x){
z <- a/df[c("divisor")]
    }
)

I'd like to print the column name currently being operated on, but colnames(x) (for example) doesn't work.

Then I want to save a new column, based on each colname (a.exp,b.exp or whatever) into the same df.

mck
  • 40,932
  • 13
  • 35
  • 50
sjgknight
  • 393
  • 1
  • 5
  • 19

2 Answers2

2

For example, take

df <- data.frame(a = 1:3, b = 11:13, c = 21:23)

I'd like to print the column name currently being operated on, but colnames(x) (for example) doesn't work.

Use sapply with column indices:

sapply(seq_len(ncol(df)), function(x) names(df)[x])
# [1] "a" "b" "c"

I want to save a new column, based on each colname (a.exp,b.exp or whatever) into the same df.

Here is one way to do it:

(df <- cbind(df, setNames(as.data.frame(apply(df, 2, "^", 2)), paste(names(df), "sqr", sep = "."))))
#   a  b  c a.sqr b.sqr c.sqr
# 1 1 11 21     1   121   441
# 2 2 12 22     4   144   484
# 3 3 13 23     9   169   529
lukeA
  • 53,097
  • 5
  • 97
  • 100
0

I think a lot of people will look for this same issue, so I'm answering my own question (having eventually found the answers). As below, there are other answers to both parts (thanks!) but non-combining these issues (and some of the examples are more complex).

First, it seems the "colnames" element really isn't something you can get around (seems weird to me!), so you 'loop' over the column names, and within the function call the actual vectors by name [c(x)].

Then the key thing is that to assign, so create your new columns, within an apply, you use '<<'

apply(colnames(df[c("a","b","c")]),function(x) {
z <- (ChISEQCIS[c(paste0(x))]/ChISEQCIS[c("V1")])
ChISEQCIS[c(paste0(x,"ind"))] <<- z
}
)

The << is discussed e.g. https://stackoverflow.com/questions/2628621/how-do-you-use-scoping-assignment-in-r

I got confused because I only vaguely thought about wanting to save the outputs initially and I figured I needed both the column (I incorrectly assumed apply worked like a loop so I could use a counter as an index or something) and that there should be same way to get the name separately (e.g. colname(x)).

There are a couple of related stack questions:

Community
  • 1
  • 1
sjgknight
  • 393
  • 1
  • 5
  • 19
  • Note the use of z <- ... and then the <<- underneath Originally I had both as << but this isn't necessary, the z only needs to be stored 'within' the apply loop (I don't then use it anywhere else). So now if you run this you'll see that the 'z' doesn't appear in your workspace, while the new columns obviously are added to the df. – sjgknight Jan 22 '15 at 19:58