###Mixing Polygon Simulation (2 isotopes); v1.1, 22.7.2013, R version 3.0.1 ###J.A.Smith et. al. 2013 (The University of NSW)### ###For updates and instructions, visit http://www.famer.unsw.edu.au/downloads.html ###New in v1.1: added black and white plot of mixing region ##Housekeeping rm(list=ls(all=TRUE)) graphics.off() setwd("C:/R_scripts/MixPolySim") install.packages("sp") #for point-in-polygon (P-I-P) calculations install.packages("splancs") #to calculate polygon area library(sp) library(splancs) ##USER INPUT sources <- read.table("Sources_example.csv",header=T,sep=",") #always put 13C(x) before 15N(y) mixture <- read.table("Mixture_example.csv",header=T,sep=",") #some error is required for every value TEF <- read.table("TEF_example.csv", header=T,sep=",") its <- 1500 #specify the number of iterations ("its") min_C <- -50 #specifiy the dimensions and resolution for the mixing region figure max_C <- -20 #choose values outside the 95% mixing region min_N <- -2 max_N <- 10 res <- 250 #resolution of the mixing region figure; reducing this improves performance ##Now RUN the simulation step_C <- (max_C - min_C)/(res - 1) step_N <- (max_N - min_N)/(res - 1) C_g <- seq(min_C,max_C,by=step_C) #values must be in ascending order N_g <- seq(min_N,max_N,by=step_N) #values must be in ascending order mgrid <- function(a,b) { #create a grid of values to test for P-I-P list( x=outer(b*0,a,FUN="+"), y=outer(b,a*0,FUN="+") ) } m <- mgrid(C_g,N_g) Par_values <- array(0, c(its,(nrow(sources)*4+3))) #create files to store data p <- array(0, c(its,(nrow(mixture)))) mix_reg <- array(0, c(res,res)) for (i in 1:its) { #run loops to generate source isotopic signatures, for iterations = 'its' v <- array(0, c(nrow(sources),2)) f <- array(0, c(nrow(TEF),2)) for (j in 1:nrow(sources)) { v[j,1] <- rnorm(1, mean=sources[j,1], sd=sources[j,2]) #generate values from norm. dist. for d13C v[j,2] <- rnorm(1, mean=sources[j,3], sd=sources[j,4]) #generate values from norm. dist. for d15N f[j,1] <- rnorm(1, mean=TEF[j,1], sd=TEF[j,2]) #generate values from norm. dist. for d13C enrichment f[j,2] <- rnorm(1, mean=TEF[j,3], sd=TEF[j,4]) #generate values from norm. dist. for d15N enrichment } V <- v+f hull <- chull(V) #create a 2D convex hull from the enriched sources hull_a <- append(hull,hull[1]) #closes the polygon P <- point.in.polygon(mixture[,1], mixture[,2], V[hull_a,1], V[hull_a,2]) #calculate P_I_P P_n <- as.numeric(P) p[i,] <- P_n poly_a <- areapl(V[hull_a,]) #calculate polygon area, for evaluating the quantity of iterations m$y_f <- m$y[res:1,] #flip y grid data to resemble axes (d13C=x, d15N=y) m_r <- point.in.polygon(m$x, m$y_f, V[hull_a,1], V[hull_a,2]) #calculate P-I-P for the mixing region m_r_s <- matrix(m_r,nrow=res,byrow=F) #convert vector into square matrix m_r_s[m_r_s > 1] <- 1 #point.in.polygon can return '2' or '3' mix_reg <- mix_reg + m_r_s vals <- c(v[,1],v[,2],f[,1],f[,2],0,0,0) #concatenate values for this iteration Par_values[i,] <- vals #store values Par_values[i,ncol(Par_values)-2] <- poly_a Par_values[i,ncol(Par_values)-1] <- i Par_values[i,ncol(Par_values)] <- var(Par_values[1:i,ncol(Par_values)-2]) if (i %% 10 ==0) cat(paste("iteration", i, "\n")) } ##FIGURE 1: variance of polygon area during simulation Iterations <- Par_values[,ncol(Par_values)-1] Variance <- Par_values[,ncol(Par_values)] plot(Iterations, Variance, type="n") #plots lines(Iterations, Variance, lty=1, lwd=1.5, col="blue") ##FIGURE 2: proportion of iterations that each consumer was inside mixing polygon p[p > 1] <- 1 #point.in.polygon can return '2' or '3' Probabilities <- colSums(p)/its print(Probabilities) windows() barplot(Probabilities, xlab="Consumer", ylab="Probability consumer is within mixing polygon", ylim=c(0,1), names.arg=seq(1,nrow(mixture),by=1)) ##FIGURE 3: mixing region, consumers, average enriched source signatures mix_reg <- mix_reg/its #convert to 0-1 scale mix_reg[mix_reg==0] <- NA #make the zeros white mix_regt <- t(mix_reg[ncol(mix_reg):1,]) #transpose matrix for use with 'image' windows() image(C_g, N_g, mix_regt, col=colorRampPalette(c("blue", "light blue", "green", "light green", "yellow", "red"))(100), xlab="d13C", ylab="d15N", useRaster=TRUE) cont <- c(0.05, seq(0.1, 1, by=0.1)) contour(C_g, N_g, mix_regt, levels=cont, add=TRUE, drawlabels=FALSE, lwd=1.9) sources_TEF <- sources + TEF points(sources_TEF[,1], sources_TEF[,3], col="white", pch=4, lwd=2, cex=1.5) points(mixture, pch=19, cex=1.3) dev.copy2pdf(file="Mix_Region.pdf") windows() #create colour bar for figure 3 cust_color <- colorRampPalette(c("blue", "light blue", "green", "light green", "yellow", "red")) z <- matrix(1:100, nrow=1) x <- 1 y <- seq(0,1,len=100) image(x,y,z,col=colorRampPalette(c("blue", "light blue", "green", "light green", "yellow", "red"))(100), xaxt="n", xlab="", ylab="", useRaster=TRUE, bty="n", las=1) ##FIGURE 4: Same as Fig. 3, but black and white windows() plot(C_g, N_g, type = "n") cont <- c(0.05, seq(0.1, 1, by=0.1)) contour(C_g, N_g, mix_regt, levels=cont, add=TRUE, drawlabels=FALSE, lwd=1.9) sources_TEF <- sources + TEF points(sources_TEF[,1], sources_TEF[,3], col="black", pch=4, lwd=2, cex=1.5) points(mixture, pch=19, cex=1.3) ##Write data to files p_a <- rbind(p,Probabilities) write.table(p_a, file = "Consumer_Probabilities.csv", sep = ",", row.names=FALSE) col_names <- c(rep("d13C",nrow(sources)),rep("d15N",nrow(sources)), rep("13C_TEF",nrow(sources)),rep("15N_TEF",nrow(sources)), "Poly_Area","Iteration","Variance") col_nums <- c(rep(1:nrow(sources),4),0,0,0) col_n <- paste(col_names, col_nums) write.table(Par_values, file = "Parameter_Values.csv", sep = ",", row.names=FALSE, col.names=col_n)