Okay, so your code only has one small bug, but there are definitely better ways of doing this. Your code doesn't work when the number of rows is an exact multiple of step
. This has to do with the position of your break
. Here is a fix:
create_frame_list<-function(mydata,mystep,elnames){
datalim<-dim(mydata)[1]
mylist<-list()
init<-1
top<-mystep
i<-1
repeat{
if(top < datalim)
# mylist[[i]]<-assign(paste0(elnames,as.character(i)),data.frame(mydata[init:top,]))
mylist[[i]]<-mydata[init:top,]
else
mylist[[i]]<-mydata[init:datalim,]
# if(top > datalim) break
i<-i+1
init<-top+1
top<-top+mystep
if(init > datalim) break
}
return(mylist)
}
The main fix was to move the if
and make it reliant on init
, and not top
.
You'll note that I cleaned up your code, and removed the assign
statments. One good rule of thumb is: if you think you need to use assign
or get
, you're doing it wrong. In your case, the assign was completely redundant, and did not assign the names in the way you wanted.
If you're looking for a better way to do this, here is one option:
n<-nrow(test_data)
step<-300
split.var<-rep(1:ceiling(n/step),each=step,length.out=n)
master_list<-split(test_data,split.var)
names(master_list)<-paste0('bd',seq_along(master_list))
# If you didn't care about the order of the rows you could just do
# split(test_data,seq(ceiling(n/step)))
If you want to get fancy, you could do something like:
special.split<-function(data,step)
split(data,rep(1:ceiling(nrow(data)/step),each=step,length.out=nrow(data)))
lapply(special.split(test_data,300),special.split,step=50)
And that would do everything in one step.