wwl
wwl

Reputation: 2065

Error with paste within for loop

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

Answers (2)

Gin_Salmon
Gin_Salmon

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

Tonio Liebrand
Tonio Liebrand

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

Related Questions