options(scipen=999) # EIQ simulation code ### Function to calculate the EIQ value from a list of risk factors: eiq<-function(dt=1, ca=1, sy=1, f=1, l=1, r=1, d=1, s=1, z=1, b=1, p=1){ EIQ<-(ca*((dt*5)+(dt*p))+ ((ca*((s+p)/2)*sy)+(l))+ ((f*r)+(d*((s+p)/2)*3)+(z*p*3)+(b*p*5)))/3 invisible(round(EIQ,1)) } ### Calculate the minimum and maximum possible EIQ values: eiq.min<-eiq(1,1,1,1,1,1,1,1,1,1,1) eiq.max<-eiq(5,5,5,5,5,5,5,5,5,5,5) ### Calculate the maximum possible EIQ value for a herbicide: eiq.maxHerb<-eiq(5,5,1,5,5,5,5,5,5,5,3) data.frame(eiq.min, eiq.max, eiq.maxHerb) ### Create 100,000 iterations of each risk factor where possible values = (1,3,5) ### except for SY, which is always = 1 for herbicides, and for P, which is 1 for ### preemergence herbicides and 3 for postemergence herbicides val<-c(1,3,5) dt<-sample(val, 100000, replace=T) ca<-sample(val, 100000, replace=T) sy<-1 f<-sample(val, 100000, replace=T) l<-sample(val, 100000, replace=T) r<-sample(val, 100000, replace=T) d<-sample(val, 100000, replace=T) s<-sample(val, 100000, replace=T) z<-sample(val, 100000, replace=T) b<-sample(val, 100000, replace=T) p<-sample(c(1,3), 100000, replace=T) ### Run each of the 100,000 iterations through the EIQ formula to calculate ### the EIQ value for each combination of values, then create a data frame with ### the simulation results. eiq.calc<-eiq(dt, ca, sy, f, l, r ,d, s, z, b, p) eiq.sim<-data.frame(dt, ca, sy, f, l, r, d, s, z, b, p, eiq.calc) median(eiq.calc) ### Run a linear regression with EIQ value as the dependent variable against each ### risk factor as independent variables. The slope coefficient then gives a ### "Relative influence" values (slope) and explained variance (using sums of ### squares) for the calculated EIQ. lm(eiq.calc~dt+ca+f+l+r+d+s+z+b+p, data=eiq.sim)->RI.lm RI<-round(coef(RI.lm),1)[2:11] RI barplot(sort(RI, decreasing=TRUE)) data.frame(SumSq=round(anova(RI.lm)[2],0), PctMeanSq=round(anova(RI.lm)[2]/sum(anova(RI.lm)[2]),3))->ssRI colnames(ssRI)<-c("SumSquares","PropOfTotalSS") ssRI ### Calculate the median EIQ for each value of each risk factor dts<-tapply(eiq.sim$eiq.calc, eiq.sim$dt, median) cas<-tapply(eiq.sim$eiq.calc, eiq.sim$ca, median) fs<-tapply(eiq.sim$eiq.calc, eiq.sim$f, median) ls<-tapply(eiq.sim$eiq.calc, eiq.sim$l, median) rs<-tapply(eiq.sim$eiq.calc, eiq.sim$r, median) ds<-tapply(eiq.sim$eiq.calc, eiq.sim$d, median) ss<-tapply(eiq.sim$eiq.calc, eiq.sim$s, median) zs<-tapply(eiq.sim$eiq.calc, eiq.sim$z, median) bs<-tapply(eiq.sim$eiq.calc, eiq.sim$b, median) ps<-tapply(eiq.sim$eiq.calc, eiq.sim$p, median) ps<-c(ps,NA) data.frame(dts, cas, fs, ls, rs, ds, ss, zs, bs, ps)->eiq.simsens colnames(eiq.simsens)<-c("DT","C","F","L","R","D","S","Z","B","P") rownames(eiq.simsens)<-c("Min.1","Med.3","Max.5") round(t(eiq.simsens),1) ### Calculate Spearman's rho between EIQ and each risk factor simcor<-data.frame(Risk=colnames(eiq.sim), Spearman=round(cor(eiq.sim,method="spearman")[,12],2)) print(simcor, row.names=FALSE) ### Subset into PRE and POST datasets pre.sim<-subset(eiq.sim, p==1) post.sim<-subset(eiq.sim, p==3) ### Relative influence for PRE herbicides pre.RI<-round(coef(lm(eiq.calc~dt+ca+f+l+r+d+s+z+b, data=pre.sim)),1)[2:10] ### Relative influence for POST herbicides post.RI<-round(coef(lm(eiq.calc~dt+ca+f+l+r+d+s+z+b, data=post.sim)),1)[2:10] ### Summary table data.frame(pre.RI, post.RI, diff=post.RI-pre.RI) ### Relative influence of P interactions rfs<-c("dt","ca","sy","f","l","r","d","s","z","b") rfdf<-data.frame(rfs, P=NA, var=NA, pintx=NA) for(i in 1:10){ round(coef(lm(eiq.sim[,12]~eiq.sim[,11]*eiq.sim[,i]))[2:4],1)->rfdf[i,2:4] } rfdf ################# End simulation code ########################### library(extrafont) # get Arial font due to PLOS request loadfonts(device="postscript") ### Multi-panel box plot figure g1<-gray(0.95) g2<-gray(0.85) g3<-gray(0.75) gcol<-c(g1,g2,g3) risks<-c("Low","Medium","High") postscript("Fig1_EIQ-SimBoxplotsBW.eps", width=6, height=7, #units="in", res=300, pointsize=12, family="Arial", paper="special", horizontal=FALSE, onefile=FALSE) par(mfrow=c(3,3), mar=c(4.2, 2.2, 2.0, 0.5), mgp=c(2.2, 1, 0), oma=c(0, 2, 0, 0)) boxplot(eiq.sim$eiq.calc~eiq.sim$dt, range=0, xlab="Dermal toxicity (DT)", ylab="", ylim=c(0,140), col=c(g1,g2,g3), names=risks, frame.plot=FALSE) mtext("A", side=2, line=2, las=2, at=155) boxplot(eiq.sim$eiq.calc~eiq.sim$ca, range=0, xlab="Chronic toxicity (C)", ylab="", ylim=c(0,140), col=gcol, names=risks, frame.plot=FALSE) mtext("B", side=2, line=2, las=2, at=155) boxplot(eiq.sim$eiq.calc~eiq.sim$f, range=0, xlab="Fish toxicity (F)", ylab="", ylim=c(0,140), col=gcol, names=risks, frame.plot=FALSE) mtext("C", side=2, line=2, las=2, at=155) boxplot(eiq.sim$eiq.calc~eiq.sim$l, range=0, xlab="Leaching potential (L)", ylab="", ylim=c(0,140), col=gcol, names=risks, frame.plot=FALSE) mtext("D", side=2, line=2, las=2, at=155) boxplot(eiq.sim$eiq.calc~eiq.sim$r, range=0, xlab="Surface loss potential (R)", ylab="", ylim=c(0,140), col=gcol, names=risks, frame.plot=FALSE) mtext("E", side=2, line=2, las=2, at=155) boxplot(eiq.sim$eiq.calc~eiq.sim$d, range=0, xlab="Bird toxicity (D)", ylab="", ylim=c(0,140), col=gcol, names=risks, frame.plot=FALSE) mtext("F", side=2, line=2, las=2, at=155) boxplot(eiq.sim$eiq.calc~eiq.sim$s, range=0, xlab="Soil half-life (S)", ylab="", ylim=c(0,140), col=gcol, names=risks, frame.plot=FALSE) mtext("G", side=2, line=2, las=2, at=155) boxplot(eiq.sim$eiq.calc~eiq.sim$z, range=0, xlab="Bee toxicity (Z)", ylab="", ylim=c(0,140), col=gcol, names=risks, frame.plot=FALSE) mtext("H", side=2, line=2, las=2, at=155) boxplot(eiq.sim$eiq.calc~eiq.sim$b, range=0, xlab="Beneficial arthropod toxicity (B)", ylab="", ylim=c(0,140), col=gcol, names=risks, frame.plot=FALSE) mtext("I", side=2, line=2, las=2, at=155) mtext("EIQ", 2, outer=T, line=0.5, at=0.856) mtext("EIQ", 2, outer=T, line=0.5, at=0.525) mtext("EIQ", 2, outer=T, line=0.5, at=0.19) dev.off() ### Histogram of EIQ values, disaggregated by PRE vs POST median(pre.sim$eiq) median(post.sim$eiq) postscript("Fig2_PREvPOSThistogram.eps", width=5, height=6, #units="in", res=300, pointsize=12, family="Arial", paper="special", horizontal=FALSE, onefile=FALSE) par(mar=c(0, 4.2, 0, 0.5), oma=c(4,1,1,0)) layout(matrix(c(2,1,0,4,3), ncol=1), heights=c(2,0.5,1,2,0.5)) boxplot(pre.sim$eiq.calc, horizontal=TRUE, ylim=c(0,150), frame.plot=FALSE, axes=TRUE, col=gray(0.95), range=0) hist(pre.sim$eiq.calc, col=gray(0.95),xlim=c(0,150), breaks=0:15*10, main="", xlab="", ylim=c(0,15000), axes=FALSE) axis(2) text(34,12000, "median = 34", pos=4, cex=1.2) legend("topright", legend=c("PRE (P=1)"), cex=1.3, bty="n") mtext("A", side=2, line=0, las=1, outer=TRUE, at=1) boxplot(post.sim$eiq.calc, horizontal=TRUE, ylim=c(0,150), frame.plot=FALSE, axes=TRUE, col=gray(0.65), range=0) hist(post.sim$eiq.calc, col=gray(0.65), xlim=c(0,150), breaks=0:15*10,main="", xlab="", ylim=c(0,15000), axes=FALSE) axis(2) text(34,12000, "median = 60", pos=4, cex=1.2) legend("topright", legend=c("POST (P=3)"), cex=1.3, bty="n") mtext("B", side=2, line=0, las=1, outer=TRUE, at=0.415) mtext("Simulated EIQ Values", side=1, line=2.8, at=0.57, outer=TRUE) dev.off() ### Repeating the eiq function in case we don't want to run all of the above code... eiq<-function(dt=1, ca=1, sy=1, f=1, l=1, r=1, d=1, s=1, z=1, b=1, p=1){ EIQ<-(ca*((dt*5)+(dt*p))+ ((ca*((s+p)/2)*sy)+(l))+ ((f*r)+(d*((s+p)/2)*3)+(z*p*3)+(b*p*5)))/3 invisible(round(EIQ,1)) } #### Atrazine EIQ atrazine.eiq<-eiq(dt=1, ca=1, sy=1, f=3, l=3, r=3, d=1, s=5, z=1, b=1.57, p=3) atrazine.L1<-eiq(dt=1, ca=1, sy=1, f=3, l=1, r=3, d=1, s=5, z=1, b=1.57, p=3) atrazine.R1<-eiq(dt=1, ca=1, sy=1, f=3, l=3, r=1, d=1, s=5, z=1, b=1.57, p=3) atrazine.pre<-eiq(dt=1, ca=1, sy=1, f=3, l=3, r=3, d=1, s=5, z=1, b=1.57, p=1) atrazine.vals<-data.frame("Atrazine EIQ"=atrazine.eiq, "Low Leaching Atrazine"=atrazine.L1, "Atrazine PRE"=atrazine.pre, "Low Runoff Atrazine"=atrazine.R1) atrazine.vals ### Histogram of EIQ values ### Not presented in manuscript median(eiq.sim$eiq) postscript("EIQ-simulation.eps", width=4.2, height=3, #units="in", res=300, pointsize=12, family="Times", paper="special", horizontal=FALSE, onefile=FALSE) par(mfrow=c(1,1), mar=c(4.2, 4.2, 0.0, 0.5), oma=c(0,0,2.5,0)) hist(eiq.sim$eiq.calc, col=gray(0.8), xlab="EIQ",main="") abline(v=47.3, lty=2) text(47.3,15000, "median = 47.3", pos=4, cex=0.8) mtext("EIQ simulation results", 3, 1.5, outer=T, cex=1.1) mtext("(N=100,000)", 3, 0.5, outer=T, cex=0.9) dev.off() ### ggplot side-by-side bar plots, instead of a 2-panel plot (Figure 2) ### Not used in manuscript pre.hist<-hist(pre.sim$eiq.calc, breaks=0:15*10, plot=FALSE) post.hist<-hist(post.sim$eiq.calc, breaks=0:15*10, plot=FALSE) library(ggplot2) pvp<-data.frame(Timing=c(rep("PRE",15),rep("POST",15)), Frequency=c(pre.hist$counts,post.hist$counts), SimulatedEIQ=c(pre.hist$mids,post.hist$mids)) postscript("EIQ-PREvPOST.eps", width=4.2, height=2.5, #units="in", res=300, pointsize=12, family="Times", paper="special", horizontal=FALSE, onefile=FALSE) ggplot(pvp, aes(x=SimulatedEIQ, y=Frequency, fill=Timing)) + geom_bar(stat="identity", position="dodge") + theme_bw() dev.off() ### Get mean values instead of medians, if interested dts<-tapply(eiq.sim$eiq.calc, eiq.sim$dt, mean) cas<-tapply(eiq.sim$eiq.calc, eiq.sim$ca, mean) fs<-tapply(eiq.sim$eiq.calc, eiq.sim$f, mean) ls<-tapply(eiq.sim$eiq.calc, eiq.sim$l, mean) rs<-tapply(eiq.sim$eiq.calc, eiq.sim$r, mean) ds<-tapply(eiq.sim$eiq.calc, eiq.sim$d, mean) ss<-tapply(eiq.sim$eiq.calc, eiq.sim$s, mean) zs<-tapply(eiq.sim$eiq.calc, eiq.sim$z, mean) bs<-tapply(eiq.sim$eiq.calc, eiq.sim$b, mean) ps<-tapply(eiq.sim$eiq.calc, eiq.sim$p, mean) ps<-c(ps,NA) data.frame(dts, cas, fs, ls, rs, ds, ss, zs, bs, ps)->eiq.simsens colnames(eiq.simsens)<-c("DT","C","F","L","R","D","S","Z","B","P") rownames(eiq.simsens)<-c("Min.1","Med.3","Max.5") round(t(eiq.simsens),1)