Reputation: 2065
I'm trying to get a for loop to generate multiple smaller dataframes from a large dataframe:
Year <- rep(1995:2012,4)
Name <- rep(LETTERS[1:4],18)
abc <- data.frame(Year,Name)
for (year in 1995:2012) {
assign(paste("dff",year,sep=""), abc[abc$Year == year,])
#paste("dff",year,sep="") <- paste("dff",year,sep="")[with(paste("dff",year,sep=""), order(Name)), ]
}
Problem is the last (commented) line which when uncommented throws an error:
invalid 'envir' argument of type 'character'
.
What can I do to fix this? I'm basically trying to order the dataframe by the column Name
.
Upvotes: 1
Views: 678
Reputation: 847
Just in the interest of providing a couple of extra options, or If you were interested in using lists, and or avoiding using assign
we could do the following:
library(data.table)
Year <- rep(1995:2012,4)
Name <- rep(LETTERS[1:4],18)
abc <- data.frame(Year,Name)
abc <- data.table(abc)
my_list <- split(abc, Year)
my_list <- lapply(my_list, function(x){x[order(Name)]})
Pretty simple, avoids using get
and assign
. split
gets rid of the need to loop things to split the data table up as well. Might be easier to read/understand too.
If you wanted to stick to something using a for loop, i.e. what you had initially, you could do:
empty_list <- list()
for(i in unique(abc[,Year])){
empty_list[[paste0(i)]] <- abc[Year == i,]
empty_list[[paste0(i)]] <- empty_list[[paste0(i)]][order(Name)]
}
Someone might be able to write a cleaner loop than above, but it works!
Upvotes: 2
Reputation: 17689
Either you use list()
or adapt your code the following way:
Year <- rep(1995:2012,4)
Name <- rep(LETTERS[1:4],18)
abc <- data.frame(Year,Name)
for (year in 1995:2012) {
assign(paste("dff",year,sep=""), abc[abc$Year == year,])
assign((paste("dff",year,sep="")), get(paste("dff",year,sep=""))[with(get(paste("dff",year,sep="")), order(Name)), ])
}
Upvotes: 2