GregS
GregS

Reputation: 279

How to properly loop without eval, parse, text=paste("... in R

So I had a friend help me with some R code and I feel bad asking because the code works but I have a hard time understanding and changing it and I have this feeling that it's not correct or proper code.

I am loading files into separate R dataframes, labeled x1, x2... xN etc.

I want to combine the dataframes and this is the code we got to work:

assign("x",eval(parse(text=paste("rbind(",paste("x",rep(1:length(toAppend)),sep="",collapse=", "),")",sep=""))))

"toAppend" is a list of the files that were loaded into the x1, x2 etc. dataframes.

Without all the text to code tricks it should be something like:

x <- rbind(##x1 through xN or some loop for 1:length(toAppend)#)

Why can't R take the code without the evaluate text trick? Is this good code? Will I get fired if I use this IRL? Do you know a proper way to write this out as a loop instead? Is there a way to do it without a loop? Once I combine these files/dataframes I have a data set over 30 million lines long which is very slow to work with using loops. It takes more than 24 hours to run my example line of code to get the 30M line data set from ~400 files.

Upvotes: 0

Views: 2625

Answers (1)

IRTFM
IRTFM

Reputation: 263411

If these dataframes all have the same structure, you will save considerable time by using the 'colClasses' argument to the read.table or read.csv steps. The lapply function can pass this to read.* functions and if you used Dason's guess at what you were really doing, it would be:

 x <- do.call(rbind, lapply(file_names, read.csv, 
                                colClasses=c("numeric", "Date", "character")
               ))   # whatever the ordered sequence of classes might be

The reason that rbind cannot take your character vector is that the names of objects are 'language' objects and a character vector is ... just not a language type. Pushing character vectors through the semi-permeable membrane separating 'language' from 'data' in R requires using assign, or do.call eval(parse()) or environments or Reference Classes or perhaps other methods I have forgotten.

Upvotes: 2

Related Questions