Mycorrhizal responsiveness trends in annual crop plants and their wild relatives- A meta-analysis on studies from 1981 to 2010 Plant and Soil Anika Lehmann1, E. Kathryn Barto1, Jeff R. Powell2 and Matthias C. Rillig1, * 1 Freie Universität Berlin, Institut für Biologie, Dahlem Center of Plant Sciences, Altensteinstr. 6, D-14195 Berlin, Germany 2 Hawkesbury Institute for the Environment, University of Western Sydney, Hawkesbury Campus, Bourke St, Richmond 2753, NSW, Australia * Author for correspondence Matthias C. Rillig Institut für Biologie, Dahlem Center of Plant Sciences Ökologie der Pflanzen Altensteinstr. 6 D- 14195 Berlin matthias.rillig@fu-berlin.de +49 (0)30 838-53165; fax -53886 Online Resource 3: “Error” bootstrap code for R ## function for implementing bootstrap methods in meta-analysis ## ## based on Van den Noortgate and Onghena 2005 Behavior Research Methods 37, 11-22 ## ## coded by Jeff Powell (jeffpowell2@gmail.com) ## ## data from Van den Noortgate and Onghena 2005 study<-factor(1:10) grade<-c(6,5,3,3,2,4,8,1,3,5) n1<-n2<-c(90,40,36,20,22,10,10,10,39,50) N<-n1+n2 d<-c(-0.583,0.535,0.779,1.052,0.563,0.308,0.081,0.598,-0.178,-0.234) err<-(N/(n1*n2))+((d^2)/(2*N)) #mima(yi=d,vi=err,mods=grade) library(metafor) z<-rma.uni(yi=d,vi=err) #init w/o mods zz<-rma.uni(yi=d,vi=err,mods=grade) #init w/ mods # error here is estimated as described in Van den Noortgate and Onghena 2005, which may be different from how you want to estimate error boot.rma<-function(init.mod,type=c('effect size','error'),n=list(),boot.reps=10,control=list(maxit=100)){ if(type!='effect size'&type!='error') stop('indicate correct type of analysis') boot.out<-matrix(NA,nrow=boot.reps,ncol=ncol(init.mod[['X']]),dimnames=list(NULL,colnames(init.mod[['X']]))) n1<-n[[1]] n2<-n[[2]] N<-n1+n2 boot.samp<-function(){ y<-init.mod if(type=='effect size'){ #effect size bootstrap (parametric) u.boot<-rnorm(length(resid(y)),0,sqrt(y[['tau2']])) # step 1 (u.boot = u*) del.boot<-fitted(y)+u.boot # step 2 (del.boot = delta*) err.boot<-(N/(n1*n2))+((del.boot^2)/(2*N)) # step 3 (err.boot = vi*) --> is this how error is estimated? e.boot<-rnorm(length(del.boot),0,sqrt(err.boot)) # step 3 (e.boot = e*) d.boot<-del.boot+e.boot # step 4 (d.boot = d*) } if(type=='error'){ #error bootstrap (nonparametric) u<-(y[['tau2']]/(y[['tau2']]+y$vi))*(y$yi-fitted(y)) # step 1 using equation 8 (u = level 2 residuals from y) #r<-(y$yi-u)/sqrt(y$vi) # step 3 using equation 8 (r = level 1 residuals from y) <-- this is wrong, don't use this (see message at end) r<-(y$yi-fitted(y)-u)/sqrt(y$vi) # step 3 using equation 3 (r = level 1 residuals from y) u.infl<-function(p) (y[['tau2']]-var(p*u))^2 # function for reflation of residuals (from paragraph containing equation 8) u<-u*optimize(u.infl,c(0,10))$minimum # reflation of residuals u.boot<-sample(u,replace=T) # step 1 (u.boot = u*) del.boot<-fitted(y)+u.boot # step 2 using equation 5 (del.boot = delta*) r.infl<-function(p) (1-var(p*r))^2 # function for reflation of residuals (from paragraph containing equation 8) r<-r*optimize(r.infl,c(0,10))$minimum # reflation of residuals r.boot<-sample(r,replace=T) # step 3 (r.boot = r*) err.boot<-(N/(n1*n2))+((del.boot^2)/(2*N)) # step 3 (err.boot = vi*) --> is this how error is estimated? e.boot<-r.boot*sqrt(err.boot) # step 3 from equations 2+3 (e.boot = e*) d.boot<-del.boot+e.boot # step 4 (d.boot = d*) } res<-list(d.boot,err.boot) names(res)<-c('d.boot','err.boot') res } for(i in 1:boot.reps){ go<-T yy<-NULL while(go){ # for dealing with convergence errors during estimation on bootstrap replicates, resamples bootstrap replicate on error bootsamp<-boot.samp() if(ncol(init.mod[['X']])==1) try(yy<-rma.uni(yi=bootsamp[['d.boot']],vi=bootsamp[['err.boot']],control=control),silent=T) else try(yy<rma.uni(yi=bootsamp[['d.boot']],vi=bootsamp[['err.boot']],mods=init.mod[['X']][,2:ncol(init.mod[['X']])],control=control),silent=T) if(!is.null(yy)) ifelse(any(attr(yy,'class')=='try-error'),go<-T,go<-F) } boot.out[i,]<-yy[['b']][,1] } boot.out } # initial testing para.boot<-boot.rma(z,type='effect size',n=list(n1,n2),boot.reps=10) summary(para.boot) mean(para.boot) sd(para.boot) nonpara.boot<-boot.rma(z,type='error',n=list(n1,n2),boot.reps=10) summary(nonpara.boot) mean(nonpara.boot) sd(nonpara.boot) para.boot<-boot.rma(zz,type='effect size',n=list(n1,n2),boot.reps=10) summary(para.boot) mean(para.boot) sd(para.boot) 1-mean(para.boot[,'mods']<0) nonpara.boot<-boot.rma(zz,type='error',n=list(n1,n2),boot.reps=10) summary(nonpara.boot) mean(nonpara.boot) sd(nonpara.boot) 1-mean(nonpara.boot[,'mods']<0) # with more than one moderator fake<-sample(15,length(grade)) zzz<-rma.uni(yi=d,vi=err,mods=cbind(grade,fake)) #init w/ mods para.boot<-boot.rma(zzz,type='effect size',n=list(n1,n2),boot.reps=10) summary(para.boot) mean(para.boot) sd(para.boot) 1-mean(para.boot[,'grade']<0) 1-mean(para.boot[,'fake']<0) nonpara.boot<-boot.rma(zzz,type='error',n=list(n1,n2),boot.reps=10) summary(nonpara.boot) mean(nonpara.boot) sd(nonpara.boot) 1-mean(nonpara.boot[,'grade']<0) 1-mean(nonpara.boot[,'fake']<0) # try forcing convergence error boot.rma(zz,type='effect size',n=list(n1,n2),boot.reps=1,control=list(maxit=1)) boot.rma(zz,type='error',n=list(n1,n2),boot.reps=1,control=list(maxit=1)) ### testing -- bias observed in the intercept estimate for 'error' bootstrap, moderator estimate appears fine boot.rma(z,type='effect size',n=list(n1,n2)) boot.rma(z,type='error',n=list(n1,n2)) boot.rma(zz,type='effect size',n=list(n1,n2)) boot.rma(zz,type='error',n=list(n1,n2)) boot.rma(zzz,type='effect size',n=list(n1,n2)) boot.rma(zzz,type='error',n=list(n1,n2)) summary(boot.rma(z,type='effect size',n=list(n1,n2),boot.reps=10000)) summary(boot.rma(z,type='error',n=list(n1,n2),boot.reps=10000)) #> summary(boot.rma(z,type='effect size',n=list(n1,n2),boot.reps=10000)) # intrcpt # Min. :-0.5280 # 1st Qu.: 0.1339 # Median : 0.2514 # Mean : 0.2522 # 3rd Qu.: 0.3734 # Max. : 0.9184 #> summary(boot.rma(z,type='error',n=list(n1,n2),boot.reps=10000)) # intrcpt # Min. :-0.3551 # 1st Qu.: 0.1893 # Median : 0.3089 # Mean : 0.3055 # 3rd Qu.: 0.4243 # Max. : 0.8530 #> #> z # #Random-Effects Model (k = 10; tau^2 estimator: REML) # #tau^2 (estimate of total amount of heterogeneity): 0.2301 (SE = 0.1497) #tau (sqrt of the estimate of total heterogeneity): 0.4797 #I^2 (% of total variability due to heterogeneity): 77.35% #H^2 (total variability / within-study variance): 4.42 # #Test for Heterogeneity: #Q(df = 9) = 47.1106, p-val < .0001 # #Model Results: # #estimate se zval pval ci.lb ci.ub # 0.2521 0.1793 1.4062 0.1597 -0.0993 0.6036 # #--#Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 # #> # summary(boot.rma(zz,type='effect size',n=list(n1,n2),boot.reps=10000)) summary(boot.rma(zz,type='error',n=list(n1,n2),boot.reps=10000)) #> summary(boot.rma(zz,type='effect size',n=list(n1,n2),boot.reps=10000)) # intrcpt mods # Min. :-0.5564 Min. :-0.4991 # 1st Qu.: 0.6213 1st Qu.:-0.2177 # Median : 0.8822 Median :-0.1575 # Mean : 0.8806 Mean :-0.1582 # 3rd Qu.: 1.1433 3rd Qu.:-0.0992 # Max. : 2.4020 Max. : 0.1714 #> summary(boot.rma(zz,type='error',n=list(n1,n2),boot.reps=10000)) # intrcpt mods # Min. :-0.4631 Min. :-0.4743 # 1st Qu.: 0.6797 1st Qu.:-0.2163 # Median : 0.9331 Median :-0.1577 # Mean : 0.9330 Mean :-0.1591 # 3rd Qu.: 1.1884 3rd Qu.:-0.1010 # Max. : 2.4071 Max. : 0.1704 #> #> zz # #Mixed-Effects Model (k = 10; tau^2 estimator: REML) # #tau^2 (estimate of residual amount of heterogeneity): 0.1627 (SE = 0.1226) #tau (sqrt of the estimate of residual heterogeneity): 0.4034 # #Test for Residual Heterogeneity: #QE(df = 8) = 27.7876, p-val = 0.0005 # #Test of Moderators (coefficient(s) 2): #QM(df = 1) = 3.2550, p-val = 0.0712 # #Model Results: # # estimate se zval pval ci.lb ci.ub #intrcpt 0.8896 0.3936 2.2604 0.0238 0.1183 1.6610 * #mods -0.1597 0.0885 -1.8042 0.0712 -0.3333 0.0138 . # #--#Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 # #> # summary(boot.rma(zzz,type='effect size',n=list(n1,n2),boot.reps=10000)) summary(boot.rma(zzz,type='error',n=list(n1,n2),boot.reps=10000)) #> summary(boot.rma(zzz,type='effect size',n=list(n1,n2),boot.reps=10000)) # intrcpt grade fake # Min. :-1.0751 Min. :-0.59458 Min. :-0.124792 # 1st Qu.: 0.5880 1st Qu.:-0.24120 1st Qu.:-0.018217 # Median : 0.8611 Median :-0.16591 Median : 0.007636 # Mean : 0.8635 Mean :-0.16620 Mean : 0.007355 # 3rd Qu.: 1.1459 3rd Qu.:-0.09213 3rd Qu.: 0.032733 # Max. : 3.0354 Max. : 0.34232 Max. : 0.161243 #> summary(boot.rma(zzz,type='error',n=list(n1,n2),boot.reps=10000)) # intrcpt grade fake # Min. :-0.5467 Min. :-0.54926 Min. :-0.105141 # 1st Qu.: 0.6423 1st Qu.:-0.24152 1st Qu.:-0.018047 # Median : 0.9237 Median :-0.16796 Median : 0.006882 # Mean : 0.9196 Mean :-0.16931 Mean : 0.007162 # 3rd Qu.: 1.1965 3rd Qu.:-0.09547 3rd Qu.: 0.032170 # Max. : 2.3813 Max. : 0.18150 Max. : 0.142709 #> #> zzz # #Mixed-Effects Model (k = 10; tau^2 estimator: REML) # #tau^2 (estimate of residual amount of heterogeneity): 0.1927 (SE = 0.1500) #tau (sqrt of the estimate of residual heterogeneity): 0.4390 # #Test for Residual Heterogeneity: #QE(df = 7) = 27.5003, p-val = 0.0003 # #Test of Moderators (coefficient(s) 2,3): #QM(df = 2) = 2.8732, p-val = 0.2377 # #Model Results: # # estimate se zval pval ci.lb ci.ub #intrcpt 0.8751 0.4162 2.1027 0.0355 0.0594 1.6907 * #grade -0.1682 0.1108 -1.5182 0.1290 -0.3854 0.0490 #fake 0.0071 0.0377 0.1876 0.8512 -0.0667 0.0809 # #--#Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 # #> # ### message regarding nonparametric bootstrap estimation of r_j ### #From: Wim Van Den Noortgate <Wim.VandenNoortgate@kuleuven-kortrijk.be> #Date: March 4, 2011 8:58:41 PM GMT+01:00 #To: Jeff Powell <jeff.powell@fu-berlin.de> #Subject: RE: nonparametric bootstrap for meta-analysis # #Dear Jeff, # #You are right, the formula is not complete... It should be the way you describe. #I am sorry for the confusion! # #Kind regards and good luck, # #Wim # #-----Oorspronkelijk bericht----#Van: Jeff Powell [mailto:jeff.powell@fu-berlin.de] #Verzonden: vrijdag 4 maart 2011 17:19 #Aan: wim.vandennoortgate@ped.kuleuven.ac.be #Onderwerp: nonparametric bootstrap for meta-analysis # #Dear Dr. Van den Noortgate, # #I'm trying to implement the 'error bootstrap' from your 2005 Behaviour  #Research Methods paper in an R script for a colleague. I've gotten to  #step 3 but I'm a little confused by the estimate of r_j in equation 8.  #It seems to me that based on equation 3 there should be a term for the  #initial estimates of the fixed parameters in this equation as well,  #i.e.: # #rhat_j = ( d_j - gammahat_0 - sum( gammahat_s x W_sj ) - uhat_j ) /  #sigmahat_j # #instead of: # # rhat_j = ( d_j - uhat_j ) / sigmahat_j # #If I am wrong about this could you please tell me why or point me to  #some literature that will help me understand? # #Thanks and best regards, #Jeff Powell # ## plotting code for troubleshooting: #plot(y$yi,pch=16,ylim=c(-1,2)) # observed effect size (d_j) #points(fitted(y),pch=1) # model prediction #points(fitted(y)+u,pch='u') # delta_j #points(fitted(y)+u+r*sqrt(y$vi),pch='E') # d_j #points(u,col='red') # level 2 residuals #points(r*sqrt(y$vi),col='blue') # level 1 residuals #