tags:

views:

53

answers:

3

In a loop, I am trying to get a column vector of class factor into numeric.

If there were not a loop, the code would look like

c1$values <- as.numeric(as.character(c1$values))

But how do I reference c1$values with a loop? I have tried two approaches:

get(paste('c',i,"$values", sep="")) 

just does not work even outside the loop, while

get(paste('c',"1", sep=""))[[1]]

works in itself (returns the column vector), but when trying to perform the operation:

assign(get(paste("c","1", sep=""))[[1]], as.numeric(as.character(get(paste("c","1", sep=""))[[1]])))

returns an error of "invalid first argument".

Any ideas?

Thanks,

Roberto

+1  A: 

Internally the $ operator is a function that can be explicitly called as "$" for getting and "$<-" for setting. assign is the opposite of get. So breaking things up into discrete steps we have:

varname<-paste("c",1,sep="")
obj<-get(varname)
x<-"$"(obj,"values")
x<-as.numeric(as.character(x))
obj<-"$<-"(obj,"values",x)
assign(varname,obj)

But having data (such as an index) encoded into a variable name is not good practice. It might be a better idea to turn the c1,c2 etc. into a list or a data frame and then iterate over them. The conversion can be done by something like this:

lapply(1:2,function(i) get(paste('c',i,sep='')))
Jyotirmoy Bhattacharya
jmoy, thanks. I see the hardcoding option but I don't understand the last suggestion about lapply. c1, c2, etc. are data frames. Can you expand on that thought? Trying to learn good practices.
Roberto
c1,c2,... form a sequence, and get(paste(...)) is our way of getting particular elements of the sequence. But lists are already provided by R to represent sequences with the standard subscripting operation and for loops to get the elements. I was suggesting that you use turn c1,c2,... into a proper list of data frames rather than keeping them as an implicit sequence related by name. The lapply example was to show how that could be done.
Jyotirmoy Bhattacharya
+1  A: 

You can index also columns by integers. This is explained in the R introductory guide on the R website.

zvrba
didn't I do so in the last example? Still it does not work.
Roberto
No, you didn't. Here:`z <- data.frame(x=c(1,2,3),y=c(4,5,6))` and then `z[,2]` is the same as z$y
zvrba
Ah, I just looked at your question without actually looking at your code. The best thing to do is to put all of your data frames into a list, such as `everything <- list(c1=data.frame(..), c2=data.frame(..))` Now, you can access your frames as `everything$c1`, or as `everything[[1]]` or just `c1` if you first do `attach(everything)`.Again, all of this is really explained in the freely available literature on R.
zvrba
that's a valuable suggestion, but the real point here is accessing the specific variables in the data frames, see the answer below.I have no doubt all of this is explained in the literature, but it's hard to consult it when one does not have the mindset to imagine the best approach. That's why SO is great: because humans point you in the right direction.
Roberto
A: 

Rather than converting your factor variables to numeric, you're probably best off figuring out why they were turned into factors in the first place.

However, since no one else has given you a decent solution to your problem, here's a simple approach with sapply and lapply:

factors <- sapply(c1, is.factor)
c1[factors] <- lapply(c1[factors], function(x) as.numeric(as.character(x)))
hadley