Skip to content

use variable in for loop to name output files

4 messages · john-usace, Rui Barradas, David Winsemius +1 more

#
Hi,

This question should be simple to answer. I am a new R user. 

I have a data.frame called appended. I would like to break it into 7 smaller
datasets based on the value of a categorical variable dp (which has values
1:7). I would like to name the smaller datasets set1, set2, set3,....,set7.
I don't know how to refer to the variable in the for loop, when naming the
output datasets. In STATA (which I am much more familiar with) each i in the
foreach loop would be refered to as `i'. This is the code I've included
below. I've also tried set[[i]] and set[i] neither works.

for (i in 1:7) {
	set`i' = appended[which(appended$dp==i & appended$sampled==0), ]
	write.table(set`i', file = "output\\set`i'.csv", sep = ",", row.name=F)
	}

I'm assuming I just need to replace `' with something else but I can figure
out what that something else is.



--
View this message in context: http://r.789695.n4.nabble.com/use-variable-in-for-loop-to-name-output-files-tp4652711.html
Sent from the R help mailing list archive at Nabble.com.
#
Hello,

Try the following.


set <- list()
for (i in 1:7) {
     set[[i]] <- appended[which(appended$dp == i & appended$sampled == 0), ]
     fl <- paste0("output/set", i, ".csv")
     write.table(set[[i]], file = fl, sep = ",", row.name=F)
}



Hope this helps,

Rui Barradas
Em 10-12-2012 21:03, john-usace escreveu:
#
On Dec 10, 2012, at 1:03 PM, john-usace wrote:

            
I am not aware of any set function, nor can one append back-ticked  
characters to unquoted characters and expect anything useful to happen.
In R the easy way would be to create a list that holds all of the  
split dataframes:

newlist <- split( appended, catvar)
names(newlist) <- paste0("set", 1:7)

If you goal were just to have these in your workspace, you are done.  
If you goal is to write them out to a file then you can either save it  
as one object to be later pulled back into a session with the load(.)  
command using this:

save(newlist, "newlist.Rdata")

Or you can write each individually with

lapply(names(newlist) , function(dfrm) {
                       write.table(newlist[[dfrm]],
                             file=paste0( dfrm, ".csv", sep=",",  
rowname=FALSE) }

(Untested. You should read the help pages of the various functions  
mentioned.)
1 day later
#
If your final goal is to write the csv files, and only the csv files, then
then this (not tested) should do it.

for (i in unique(appended$dp) ) {
  tmp <- subset(appended, dp==i & sampled==0)
  write.table(tmp,
    file= file.path('output', paste0('set',i,'.csv')),
    sep=',',
    row.names=FALSE)
}

I threw in the use of file.path(); not necessary, but will make your
scripts more cross-platform.

And you don't actually have to create the 'tmp' data frame. You could
do this inside the loop:

write.table(
  subset(appended, dp==i & sampled==0),

  file= file.path('output', paste0('set',i,'.csv')),
  sep=',',
  row.names=FALSE)


But I often find nested function calls harder to read.
 
David and Rui both suggested storing the subsets in a list, and I agree.

But if you really want objects named "set1", "set2", and so on in your
workspace, so that you can reference them by those names, then you need
the assign function. Experience will eventually give you some ideas
of which way is better and when. The general recommendation is to avoid
using assign(), and that's good advice. But I do occasionally find it
useful.

-Don