All, I have a workspace containing only data frame objects. I would like to loop though each one and clean-up text columns in them. How can I have R loop through the list? I have tried to find an answer in R help but the closest solution I can find is to make a static list of data frames, as illustrated in this recent post: ---------begin post On Tuesday 19 February 2008 (19:51:15), TLowe wrote:> Hey Folks, > > Could somebody show me how to loop through a list of dataframes? I want to > be able to generically access their elements and do something with them. > > For instance, instead of this: > > df1<- data.frame(x=(1:5),y=(1:5)); > df2<- data.frame(x=(1:5),y=(1:5)); > df3<- data.frame(x=(1:5),y=(1:5)); > plot(df1$x,df1$y); > plot(df2$x,df2$y); > plot(df3$x,df3$y); > > I would like to do something like: > (pseudocode) > dfarray[1] = df1 > dfarray[2] = df2 > dfarray[3] = df3 > for (each i in dfarray) { > plot(i$x, i$y); > }It's surprisingly simple: for(df in list(df1,df2,df3)) plot(df$x,df$y) Best, Martin ---------------------end post I would like to avoid having to type-out a very long list over and over again. I have tried every variation I could think of similar to: for(df in list(noquote(ls()))) { do stuff with df } I know this has to be possible. What am I missing? Many Thanks-
On Monday 03 March 2008 (23:28:05), lucy b wrote:> I would like to avoid having to type-out a very long list over and > over again. I have tried every variation I could think of similar to: > > for(df in list(noquote(ls()))) { > > ? ? ?do stuff with df > > ? ? ?} > > I know this has to be possible. What am I missing?I guess something like the following will do what you want, but I am not completely sure ... for(dfname in ls()){ eval(substitute({ <do stuff with df> }, list( df=as.name(dfname) ) ) ) } HTH, Martin
lucy b wrote:> > I have a workspace containing only data frame objects. I would like to > loop though each one and clean-up text columns in them. How can I have > R loop through the list? I have tried to find an answer in R help but > the closest solution I can find is to make a static list of data > frames, as illustrated in this recent post: > ... > I would like to avoid having to type-out a very long list over and > over again. I have tried every variation I could think of similar to: > > for(df in list(noquote(ls()))) { > > do stuff with df > > } >If you name your data frames consistently (e.g. df1, df2, df3 etc.), then you can access them using mget: df1 <- data.frame(a=runif(10), b=letters[1:10]) df2 <- data.frame(c=rnorm(5)) df3 <- data.frame(11:20) dataframes <- mget(paste("df", 1:3, sep=""), envir=.GlobalEnv) Alternatively, if you want every dataframe in your workspace, try: vars <- ls() nvars <- length(vars) dataframes <-list() j <- 1 for(i in 1:nvars) { if(class(get(vars[i]))=="data.frame") { dataframes[[j]] <- get(vars[i]) names(dataframes)[j] <- vars[i] j <- j+1 } } Regards, Richie. Mathematical Sciences Unit HSL -- View this message in context: http://www.nabble.com/looping-through-data-frames-in-a-workspace-tp15815971p15823720.html Sent from the R help mailing list archive at Nabble.com.
Thanks for helpful replies. Unfortunately, I didn't mention that I want to overwrite the existing data frame with the corrected one using the same name. Here's what I have: ## get names of data frames frames <- names(Filter(function(x) x=="data.frame", sapply(objects(),function(x) class(eval(parse(text=x)))))) ## loop through list for( i in seq(along=frames) ) { #don't need next line, but good to remember if need to exclude a df #if (frames[i] != "junk") { df <- eval(parse(text=frames[i])) for (c in 1:ncol(df)){ if (is.factor(df[,c])) { df[,c] <- gsub("\r\n","",as.vector(df[,c])) } } names(df) <- frames[i] }#end first if }#end first for #END Unfortunately, the "names(df)<-frames[i]" line just changes the name of the first column in df. How can I overwrite the existing data frame using the right name?