I was hoping that somebody could take a quick look at this example and help me find a better-more efficient way to approach this problem. I want to run a simulation to examine how an animal moves between sites following a set of specific conditions. I have 5 sites and a some initial probabilities,
N<-5 # number of sites sites<-LETTERS[seq(from=1,to=N)] to.r<-rbind(sites) p.move.r<-seq.int(0.05,0.95,by=0.1) # prob of moving to a new site p.leave<-0.01*p.move.r # prob of leaving the system w/out returning p.move.out<-0.01*p.move.r # prob of moving in/out p.stay<-1-(p.move.r+p.leave+p.move.out) # prob of staying in the same site
For this example, I only included 50 simulations, but in reality I would like to have at least 1000 simulations,
set.seed(13973) reps<-50 # number of replicates/simulations steps<-100 # number of time steps (hours, days, weeks, etc) random<-runif(10000,0,1) # generating numbers from a random distribution # Construct empty df to fill with data rep.movements<-matrix(NA,nrow=reps,ncol=steps) colnames(rep.movements)<-c(1:steps);rownames(rep.movements)<-c(1:reps) rep.use<-matrix(NA,nrow=reps,ncol=N) colnames(rep.use)<-c(reefs);rownames(rep.use)<-c(1:reps) # Outer loop to run each of the initial parameters for(w in 1:length(p.stay)){ p.move<-matrix((p.move.r[w]/(N-1)),N,N) diag(p.move)<-0 # Construction of distance matrix move<-matrix(c(0),nrow=(N+2),ncol=(N+2),dimnames=list(c(sites,"NA","left"),c(sites,"NA","left"))) from<-array(0,c((N+2),(N+2)),dimnames=list(c(sites,"NA","left"),c(sites,"NA","left"))) to<-array(0,c((N+2),(N+2)),dimnames=list(c(sites,"NA","left"),c(sites,"NA","left"))) # Filling movement-Matrix construction for(from in 1:N){ for(to in 1:N){ if(from==to){move[from,to]<-p.stay[w]} else {move[from,to]<-p.move[from,to]} move[,(N+1)]<-(1-(p.leave[w]+p.move.out[w]))/N move[,(N+2)]<-(1-(p.leave[w]+p.move.out[w]))/N move[(N+1),]<-p.move.out[w] move[(N+2),]<-p.leave[w] }
}
The idea is to use this cumulative probability matrix to determine the fate of an animal based on random number,
cumsum.move<-cumsum(data.frame(move)) # Cumulative sum of probabilities
In this cumulative matrix, the letters "A","B","C","D" and "E" represent different sites, "NA" represents the probability of leaving and coming back on a future time step and "left" represents the probability of leaving the system and not coming back. Then I use a list of random numbers to compare against the cumulative probability matrix and determine the "fate" of that particular animal.
for(o in 1:reps){
result<-matrix(as.character(""),steps) # Vector for storing sites x<-sample(random,steps,replace=TRUE) # sample array of random number time.step<-data.frame(x) # time steps used in the simulation (i) colnames(time.step)<-c("time.step") time.step$event<-"" j<-sample(1:N,1,replace=T) # first column to be selected k<-sample(1:N,1,replace=T) # selection of column for ind. that move in/out for(i in 1:steps){ for (t in 1:(N+1)){ if(time.step$time.step[i]<cumsum.move[t,j]){ time.step$event[i]<-to.r[t] break } } ifelse(time.step$event[i]=="",break,NA) result[i]<-time.step$event[i] j<-which(to.r==result[i]) if(length(j)==0){j<-k} } result<-time.step$event # calculate frequency/use for each replicate use<-table(result) use.tab<-data.frame(use) use.tab1<-use.tab[-which(use.tab==""),] mergeuse<-merge(use.tab2,use.tab,all.x=TRUE) mergeuse[is.na(mergeuse)]<-0 # insert data into empty matrix rep.movements[o,]<-result rep.use[o,]<-mergeuse$Freq } }
# for the outer loop I have some matrices to store the results for each parameter,
# but for this example this is not important
rep.movements rep.use
Now, the main problem is that it takes to long to run all the simulations for each initial parameter (10 values in this example). I need to find a better/more efficient way to run 1000 simulations / 20 sites across all the initial parameters. I am not too familiar with functions or other ways to speed up this task. Any ideas or recommendations will be appreciated.
Thanks a lot in advance,