Background
This example was developed by Julie Baniszewski, a PhD student in the Department of Entomology at Penn State. Julie participated in our last workshop in Mexico under the INTAD-Tag Along program (International Agriculture and Development graduate program). This is a robust example of using dose-response methods in R based on generalized linear modeling concepts (including mixed model).
Data set: Mosquito toxicity was tested with 4 instars and monitored until pupation. The experimental design was 3 blocks with 4 replicates each to test mosquito toxicity.
The aim is to look at ultimate %pupation and LC50, LC90 for 24, 48 hrs.
What is in the database? * Concentration = weight:volume concentration of chemical * Instar = 1-4 stages of mosquito larvae introduced to chemical treatment * Block = Growth Chamber * Rep = 1-4 replicates within each block * Total = total number of initial larvae * Pupae = total number of larvae that reached pupation * %Pupated = % larvae that pupated and ultimately survived the treatment * Day0 = total number of initial larvae * Day1p = proportion of larvae mortality on Day 1 post chemical exposure * Day2p = proportion of larvae mortality on Day 2 post chemical exposure
Load packages
Here, we will use the readxl package to work with Excel-oriented files. Like the nonparametric regression example, we have defined a local repository for the file and this can be changed for individual use. We have several other different packages specific to work with dose-response curves and model fitting.
library(readxl)
library(drc)
library(car)
library(cowplot)
library(tidyverse)
Importing data set:
DR <- read_excel("DR_Data_Sheet.xlsx")
str(DR)
## Classes 'tbl_df', 'tbl' and 'data.frame': 288 obs. of 22 variables:
## $ Concentration: num 0 0 0 0 1 1 1 1 0.75 0.75 ...
## $ Instar : num 1 1 1 1 1 1 1 1 1 1 ...
## $ Block : num 1 1 1 1 1 1 1 1 1 1 ...
## $ Rep : num 1 2 3 4 1 2 3 4 1 2 ...
## $ Total : num 10 11 10 10 10 10 10 10 10 10 ...
## $ Pupae : num 9 11 8 9 0 0 0 0 0 0 ...
## $ %Pupated : num 0.9 1 0.8 0.9 0 0 0 0 0 0 ...
## $ Day0 : num 10 11 10 10 10 10 10 10 10 10 ...
## $ Day1p : num 0.1 0 0.1 0.1 1 0.8 0.9 0.9 0.8 0.7 ...
## $ Day2p : num 0.1 0 0.1 0.1 1 1 1 1 1 0.9 ...
## $ Day3p : num 0.1 0 0.1 0.1 1 1 1 1 1 1 ...
## $ Day4p : num 0.1 0 0.1 0.1 1 1 1 1 1 1 ...
## $ Day5p : num 0.1 0 0.1 0.1 1 1 1 1 1 1 ...
## $ Day6p : num 0.1 0 0.1 0.1 1 1 1 1 1 1 ...
## $ Day7p : num 0.1 0 0.1 0.1 1 1 1 1 1 1 ...
## $ Day8p : num 0.1 0 0.1 0.1 1 1 1 1 1 1 ...
## $ Day9p : num 0.1 0 0.1 0.1 1 1 1 1 1 1 ...
## $ Day10p : num 0.1 0 0.1 0.1 1 1 1 1 1 1 ...
## $ Day11p : num 0.1 0 0.1 0.1 1 1 1 1 1 1 ...
## $ Day12p : num 0.1 0 0.1 0.1 1 1 1 1 1 1 ...
## $ Day13p : num 0.1 0 0.2 0.1 1 1 1 1 1 1 ...
## $ Day14p : num 0.1 0 0.2 0.1 1 1 1 1 1 1 ...
summary(DR)
## Concentration Instar Block Rep Total Pupae %Pupated Day0 Day1p Day2p Day3p Day4p Day5p Day6p Day7p Day8p Day9p Day10p Day11p Day12p Day13p Day14p
## Min. :0.0000 Min. :1.00 Min. :1 Min. :1.00 Min. :10.00 Min. : 0.000 Min. :0.000 Min. :10.00 Min. :0.0000 Min. :0.0000 Min. :0.0000 Min. :0.00000 Min. :0.0000 Min. :0.0000 Min. :0.0000 Min. :0.0000 Min. :0.0000 Min. :0.0000 Min. :0.0000 Min. :0.0000 Min. :0.0000 Min. :0.0000
## 1st Qu.:0.1000 1st Qu.:1.75 1st Qu.:1 1st Qu.:1.75 1st Qu.:10.00 1st Qu.: 0.000 1st Qu.:0.000 1st Qu.:10.00 1st Qu.:0.0000 1st Qu.:0.0000 1st Qu.:0.0000 1st Qu.:0.08333 1st Qu.:0.1000 1st Qu.:0.1000 1st Qu.:0.1000 1st Qu.:0.1000 1st Qu.:0.1000 1st Qu.:0.1000 1st Qu.:0.1404 1st Qu.:0.1404 1st Qu.:0.4000 1st Qu.:0.4000
## Median :0.3750 Median :2.50 Median :2 Median :2.50 Median :10.00 Median : 0.000 Median :0.000 Median :10.00 Median :0.3000 Median :0.6500 Median :0.7500 Median :0.80000 Median :0.8500 Median :0.9000 Median :0.9000 Median :1.0000 Median :1.0000 Median :1.0000 Median :1.0000 Median :1.0000 Median :1.0000 Median :1.0000
## Mean :0.4333 Mean :2.50 Mean :2 Mean :2.50 Mean :10.17 Mean : 3.615 Mean :0.346 Mean :10.17 Mean :0.3924 Mean :0.5186 Mean :0.5499 Mean :0.56945 Mean :0.5846 Mean :0.6026 Mean :0.6179 Mean :0.6258 Mean :0.6367 Mean :0.6425 Mean :0.6745 Mean :0.6778 Mean :0.7434 Mean :0.7454
## 3rd Qu.:0.7500 3rd Qu.:3.25 3rd Qu.:3 3rd Qu.:3.25 3rd Qu.:10.00 3rd Qu.: 9.000 3rd Qu.:0.900 3rd Qu.:10.00 3rd Qu.:0.8000 3rd Qu.:1.0000 3rd Qu.:1.0000 3rd Qu.:1.00000 3rd Qu.:1.0000 3rd Qu.:1.0000 3rd Qu.:1.0000 3rd Qu.:1.0000 3rd Qu.:1.0000 3rd Qu.:1.0000 3rd Qu.:1.0000 3rd Qu.:1.0000 3rd Qu.:1.0000 3rd Qu.:1.0000
## Max. :1.0000 Max. :4.00 Max. :3 Max. :4.00 Max. :14.00 Max. :14.000 Max. :1.000 Max. :14.00 Max. :1.0000 Max. :1.0000 Max. :1.0000 Max. :1.00000 Max. :1.0000 Max. :1.0000 Max. :1.0000 Max. :1.0000 Max. :1.0000 Max. :1.0000 Max. :1.0000 Max. :1.0000 Max. :1.0000 Max. :1.0000
Preliminary examination of data
Start by looking at data (ultimate survival): dependent variable ‘%pupation’
op <- par(mfrow = c(1, 2), mar=c(3.2,3.2,2,.5), mgp=c(2,.7,0)) #make two plots in two columns
plot(DR$`%Pupated` ~ DR$Concentration, data = DR, main="Original Dose Scale")
plot(DR$`%Pupated` ~ logit(DR$Concentration+0.01), data = DR, main="Logarithmic Dose Scale")
Look at control data
#if mortality is >> 5%, may need Abbot's Formula for correction (Correction%= (1-treatmetn/control)*100)
aggregate(DR[,7], list(DR$Concentration), mean)
## Group.1 %Pupated
## 1 0.00 0.9429293
## 2 0.10 0.9127889
## 3 0.25 0.2204545
## 4 0.50 0.0000000
## 5 0.75 0.0000000
## 6 1.00 0.0000000
#Control is ~5% motality, is okay
Initial models: dose-response and linear
Option 1: use Dose Response Model
DR1<-drm(DR$`%Pupated` ~ log1p(DR$Concentration), DR$Instar, data = DR, fct=LL.2(names=c("Slope", "LD50")), type=("binomial"), na.action=na.omit)
summary(DR1)
##
## Model fitted: Log-logistic (ED50 as parameter) with lower limit at 0 and upper limit at 1 (2 parms)
##
## Parameter estimates:
##
## Estimate Std. Error t-value p-value
## Slope:1 5.281684 1.480907 3.5665 0.0003618 ***
## Slope:2 4.639606 1.259559 3.6835 0.0002300 ***
## Slope:3 5.063119 1.466544 3.4524 0.0005556 ***
## Slope:4 4.753037 1.414136 3.3611 0.0007764 ***
## LD50:1 0.148070 0.019217 7.7050 1.309e-14 ***
## LD50:2 0.147669 0.019483 7.5795 3.466e-14 ***
## LD50:3 0.167355 0.021347 7.8398 4.477e-15 ***
## LD50:4 0.193382 0.023076 8.3800 < 2.2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#look at residuals
op <- par(mfrow = c(1, 2), mar=c(3.2,3.2,2,.5), mgp=c(2,.7,0)) #put two graphs together
plot(residuals(DR1) ~ fitted(DR1), main="Residuals vs Fitted")
abline(h=0) #should look random
qqnorm(residuals(DR1))
qqline(residuals(DR1))
#shows slope of pupation, LD50 is significantly different than 0 for each instar
par(mfrow = c(1, 1), mar=c(3.2,3.2,.5,.5), mgp=c(2,.7,0))
plot(DR1, broken=TRUE, xlim=c(0,2), bty="l", xlab="Concentration", ylab="Survival to Pupation")
modelFit(DR1)
## Goodness-of-fit test
##
## Df Chisq value p value
##
## DRC model 232 16.065 1
EDcomp(DR1,c(50,50), reverse=TRUE)
##
## Estimated ratios of effect doses
##
## Estimate Std. Error t-value p-value
## 2/1:50/50 0.997289 0.184569 -0.014688 0.988281
## 3/1:50/50 1.130243 0.205675 0.633247 0.526572
## 4/1:50/50 1.306015 0.230260 1.328998 0.183849
## 3/2:50/50 1.133315 0.207978 0.641007 0.521518
## 4/2:50/50 1.309565 0.232965 1.328803 0.183913
## 4/3:50/50 1.155517 0.201836 0.770511 0.440997
#Instar has little effect on pupation, instars 1 and 2 very similar, 3 and 4 increasing survival. Overall, model doesn't fit well.
Option 2: look at linear model
pairs(DR$`%Pupated` ~ (DR$Block) + (DR$Rep) + DR$Concentration + DR$Instar)
#Concentration has trend with % pupated; block/reps random, no pattern as expected. Instar appears to have little effect
op <- par(mfrow = c(1, 1), mar=c(3.2,3.2,0,.5), mgp=c(2,.7,0))
plot(DR$`%Pupated` ~ DR$Concentration, data = DR, bty="l")
pupation.lm1 <- lm(DR$`%Pupated` ~ (Block) + (Rep) + Concentration + Instar + Concentration:Instar, data = DR)
summary(pupation.lm1)
##
## Call:
## lm(formula = DR$`%Pupated` ~ (Block) + (Rep) + Concentration +
## Instar + Concentration:Instar, data = DR)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.55033 -0.25374 -0.01523 0.21556 0.38197
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.667166 0.073091 9.128 <2e-16 ***
## Block 0.003084 0.017585 0.175 0.8609
## Rep 0.003364 0.012842 0.262 0.7936
## Concentration -0.895659 0.098928 -9.054 <2e-16 ***
## Instar 0.037893 0.020247 1.871 0.0623 .
## Concentration:Instar -0.039072 0.036123 -1.082 0.2803
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.2437 on 282 degrees of freedom
## Multiple R-squared: 0.6835, Adjusted R-squared: 0.6778
## F-statistic: 121.8 on 5 and 282 DF, p-value: < 2.2e-16
plot(pupation.lm1, bty="l")
#look at residuals
op <- par(mfrow = c(1, 2), mar=c(3.2,3.2,2,.5), mgp=c(2,.7,0)) #put two graphs together
plot(residuals(pupation.lm1) ~ fitted(pupation.lm1), main="Residuals vs Fitted")
abline(h=0) #should look random
qqnorm(residuals(pupation.lm1))
qqline(residuals(pupation.lm1))
#not quite normal on QQ plot, residuals not random -> use logit or beta distribution
#logit binomial dist
pupation.lm2 <- glm((DR$`%Pupated`)~ (DR$Block) + (DR$Rep) + (DR$Concentration) + (DR$Instar) + (DR$Concentration:DR$Instar), family = binomial(link = "logit"))
plot(pupation.lm2, bty="l")
#look at residuals
plot(residuals(pupation.lm2) ~ fitted(pupation.lm2), main="Residuals vs Fitted")
abline(h=0) #should look random
qqnorm(residuals(pupation.lm1))
qqline(residuals(pupation.lm1))
#residuals random, more normal on qqplot
summary(pupation.lm2)
##
## Call:
## glm(formula = (DR$`%Pupated`) ~ (DR$Block) + (DR$Rep) + (DR$Concentration) +
## (DR$Instar) + (DR$Concentration:DR$Instar), family = binomial(link = "logit"))
##
## Deviance Residuals:
## Min 1Q Median 3Q Max
## -1.25219 -0.06925 -0.00233 0.12168 0.72655
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 3.03900 1.56721 1.939 0.05249 .
## DR$Block 0.05845 0.31427 0.186 0.85247
## DR$Rep 0.06374 0.22962 0.278 0.78132
## DR$Concentration -22.86314 7.28283 -3.139 0.00169 **
## DR$Instar 0.22619 0.52014 0.435 0.66366
## DR$Concentration:DR$Instar 0.96115 2.62361 0.366 0.71411
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 295.246 on 287 degrees of freedom
## Residual deviance: 24.113 on 282 degrees of freedom
## AIC: 58.259
##
## Number of Fisher Scoring iterations: 8
#compare linear model with non linear, linear > DR2 due to much lower AIC
AIC(DR1, pupation.lm2)
## df AIC
## DR1 8 245.08353
## pupation.lm2 6 58.25937
Log-logistic and Weibull models
Other tools related to dose-response models
#compare log-logistic and Weibull models (pooling instar because non-significant)
DR0 <- drm(DR$`%Pupated` ~ DR$Concentration, data = DR, fct = LL.4())
DR1 <- drm(DR$`%Pupated` ~ DR$Concentration, data = DR, fct = W1.4())
DR2 <- drm(DR$`%Pupated` ~ DR$Concentration, data = DR, fct = W2.4())
par(mfrow=c(1,1), mar=c(3.2,3.2,.5,.5), mgp=c(2,.7,0))
plot(DR0, broken=TRUE, xlab="Conc", ylab="% Pupation", lwd=2, cex=1.2, cex.axis=1.2, cex.lab=1.2, bty="l")
plot(DR1, add=TRUE, broken=TRUE, lty=2, lwd=2) #Weibull-1
plot(DR2, add=TRUE, broken=TRUE, lty=3, lwd=2) #Weibull-2
#Effective dose
ED(DR1,50,interval="delta")
##
## Estimated effective doses
##
## Estimate Std. Error Lower Upper
## e:1:50 0.2092415 0.0066148 0.1962212 0.2222618
ED(DR1,90,interval="delta")
##
## Estimated effective doses
##
## Estimate Std. Error Lower Upper
## e:1:90 0.2795042 0.0057066 0.2682715 0.2907369
ED(DR1,95,interval="delta")
##
## Estimated effective doses
##
## Estimate Std. Error Lower Upper
## e:1:95 0.2978175 0.0088051 0.2804860 0.3151490
edLL<-data.frame(ED(DR0,c(10,50,90),interval="delta", display=FALSE),ll="Log-logistic")
edW1<-data.frame(ED(DR1,c(10,50,90),interval="delta", display=FALSE),ll="Weibull 1")
edW2<-data.frame(ED(DR2,c(10,50,90),interval="delta", display=FALSE),ll="Weibull 2")
CombED<-rbind(edLL,edW1,edW2)
p1 <- ggplot(data=CombED[c(1,4,7),], aes(x=ll, y=Estimate))+ geom_bar(stat="identity", fill="lightgreen", colour="black")+
geom_errorbar(aes(ymin=Lower, ymax=Upper), width=0.1) + ylab("ED10")+ xlab("")
p2 <- ggplot(data=CombED[c(2,5,8),], aes(x=ll, y=Estimate))+ geom_bar(stat="identity", fill="lightgreen", colour="black")+
geom_errorbar(aes(ymin=Lower, ymax=Upper), width=0.1) + ylab("ED50")+ xlab("")
p3 <- ggplot(data=CombED[c(3,6,9),], aes(x=ll, y=Estimate))+ geom_bar(stat="identity", fill="lightgreen", colour="black")+
geom_errorbar(aes(ymin=Lower, ymax=Upper), width=0.1) + ylab("ED90")+ xlab("Sigmoid four parameter models")
plot_grid(p1,p2,p3, ncol=1)
#look at different tests, either Log-logistic or Weibull 1 most appropriate
comped(CombED[c(1,4),1],CombED[c(1,4),2],log=F,operator = "-")
##
## Estimated difference of effective doses
##
## Estimate Std. Error Lower Upper
## [1,] -0.0034982 0.0186068 -0.0399669 0.033
Mortality Example 24 hr
Look at Day 1 (24hr Mortality)
summary(DR)
## Concentration Instar Block Rep Total Pupae %Pupated Day0 Day1p Day2p Day3p Day4p Day5p Day6p Day7p Day8p Day9p Day10p Day11p Day12p Day13p Day14p
## Min. :0.0000 Min. :1.00 Min. :1 Min. :1.00 Min. :10.00 Min. : 0.000 Min. :0.000 Min. :10.00 Min. :0.0000 Min. :0.0000 Min. :0.0000 Min. :0.00000 Min. :0.0000 Min. :0.0000 Min. :0.0000 Min. :0.0000 Min. :0.0000 Min. :0.0000 Min. :0.0000 Min. :0.0000 Min. :0.0000 Min. :0.0000
## 1st Qu.:0.1000 1st Qu.:1.75 1st Qu.:1 1st Qu.:1.75 1st Qu.:10.00 1st Qu.: 0.000 1st Qu.:0.000 1st Qu.:10.00 1st Qu.:0.0000 1st Qu.:0.0000 1st Qu.:0.0000 1st Qu.:0.08333 1st Qu.:0.1000 1st Qu.:0.1000 1st Qu.:0.1000 1st Qu.:0.1000 1st Qu.:0.1000 1st Qu.:0.1000 1st Qu.:0.1404 1st Qu.:0.1404 1st Qu.:0.4000 1st Qu.:0.4000
## Median :0.3750 Median :2.50 Median :2 Median :2.50 Median :10.00 Median : 0.000 Median :0.000 Median :10.00 Median :0.3000 Median :0.6500 Median :0.7500 Median :0.80000 Median :0.8500 Median :0.9000 Median :0.9000 Median :1.0000 Median :1.0000 Median :1.0000 Median :1.0000 Median :1.0000 Median :1.0000 Median :1.0000
## Mean :0.4333 Mean :2.50 Mean :2 Mean :2.50 Mean :10.17 Mean : 3.615 Mean :0.346 Mean :10.17 Mean :0.3924 Mean :0.5186 Mean :0.5499 Mean :0.56945 Mean :0.5846 Mean :0.6026 Mean :0.6179 Mean :0.6258 Mean :0.6367 Mean :0.6425 Mean :0.6745 Mean :0.6778 Mean :0.7434 Mean :0.7454
## 3rd Qu.:0.7500 3rd Qu.:3.25 3rd Qu.:3 3rd Qu.:3.25 3rd Qu.:10.00 3rd Qu.: 9.000 3rd Qu.:0.900 3rd Qu.:10.00 3rd Qu.:0.8000 3rd Qu.:1.0000 3rd Qu.:1.0000 3rd Qu.:1.00000 3rd Qu.:1.0000 3rd Qu.:1.0000 3rd Qu.:1.0000 3rd Qu.:1.0000 3rd Qu.:1.0000 3rd Qu.:1.0000 3rd Qu.:1.0000 3rd Qu.:1.0000 3rd Qu.:1.0000 3rd Qu.:1.0000
## Max. :1.0000 Max. :4.00 Max. :3 Max. :4.00 Max. :14.00 Max. :14.000 Max. :1.000 Max. :14.00 Max. :1.0000 Max. :1.0000 Max. :1.0000 Max. :1.00000 Max. :1.0000 Max. :1.0000 Max. :1.0000 Max. :1.0000 Max. :1.0000 Max. :1.0000 Max. :1.0000 Max. :1.0000 Max. :1.0000 Max. :1.0000
op <- par(mfrow = c(1, 2), mar=c(3.2,3.2,2,.5), mgp=c(2,.7,0))
plot(DR$Day1p~ DR$Concentration, data = DR, main="Original Dose Scale")
plot(DR$Day1p ~ logit(DR$Concentration+0.01), data = DR, main="Logarithmic Dose Scale")
#Look at control data, make sure mortality is < ~ 5%
aggregate(DR[,9], list(DR$Concentration), mean)
## Group.1 Day1p
## 1 0.00 0.02083333
## 2 0.10 0.01666667
## 3 0.25 0.09166667
## 4 0.50 0.55416667
## 5 0.75 0.78541667
## 6 1.00 0.88541667
Option 1:
#option 1: use DR
Day1DR<-drm(DR$Day1p ~ DR$Concentration, DR$Instar, data = DR, fct=LL.2(names=c("Slope", "LD50")), type=("binomial"), na.action=na.omit)
summary(Day1DR)
##
## Model fitted: Log-logistic (ED50 as parameter) with lower limit at 0 and upper limit at 1 (2 parms)
##
## Parameter estimates:
##
## Estimate Std. Error t-value p-value
## Slope:1 -2.384882 0.608538 -3.9190 8.890e-05 ***
## Slope:2 -3.182438 0.801062 -3.9728 7.104e-05 ***
## Slope:3 -3.345483 0.905529 -3.6945 0.0002203 ***
## Slope:4 -3.460856 0.880632 -3.9300 8.496e-05 ***
## LD50:1 0.457671 0.066102 6.9237 4.400e-12 ***
## LD50:2 0.461353 0.056611 8.1495 4.047e-16 ***
## LD50:3 0.561857 0.062752 8.9536 < 2.2e-16 ***
## LD50:4 0.470069 0.054920 8.5592 < 2.2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#shows slope, LD50 is significantly different than 0 for each instar
par(mfrow = c(1, 1), mar=c(3.2,3.2,.5,.5), mgp=c(2,.7,0))
plot(Day1DR, broken=TRUE, xlim=c(0,2), bty="l", xlab="Concentration", ylab="Mortality")
EDcomp(Day1DR,c(50,50), reverse=TRUE)
##
## Estimated ratios of effect doses
##
## Estimate Std. Error t-value p-value
## 2/1:50/50 1.008045 0.191044 0.042111 0.966410
## 3/1:50/50 1.227643 0.224140 1.015629 0.309806
## 4/1:50/50 1.027089 0.190803 0.141975 0.887100
## 3/2:50/50 1.217845 0.202070 1.078068 0.281003
## 4/2:50/50 1.018892 0.172632 0.109437 0.912856
## 4/3:50/50 0.836635 0.135225 -1.208096 0.227010
#Instar has little effect on mortality, instars 1 and 2 similar, 3 and 4 less responsive. Overall, model doesn't fit well.
#look at residuals
op <- par(mfrow = c(1, 2), mar=c(3.2,3.2,2,.5), mgp=c(2,.7,0))
plot(residuals(Day1DR) ~ fitted(Day1DR), main="Residuals vs Fitted")
qqnorm(residuals(Day1DR))
qqline(residuals(Day1DR))
#data not normally distributed
op <- par(mfrow = c(1, 2), mar=c(3.2,3.2,.5,.5), mgp=c(2,.7,0))
plot(Day1DR, broken=TRUE, bty="l", xlab="Conc", ylab="Mortality")
plot(Day1DR, broken=TRUE, bty="l", xlab="Concentration", ylab="Mortality",type="all")
modelFit(Day1DR)
## Goodness-of-fit test
##
## Df Chisq value p value
##
## DRC model 232 57.143 1
#model doesn't fit very well, instar doesnt have much effect on DR
Option 2:
#Option 2: look at linear model
pairs(DR$Day1p ~ (DR$Block) + (DR$Rep) + DR$Concentration + DR$Instar)
op <- par(mfrow = c(1, 1), mar=c(3.2,3.2,0,.5), mgp=c(2,.7,0))
plot(DR$Day1p ~ DR$Concentration, data = DR, bty="l")
day1.lm <- lm(DR$Day1p ~ (Block) + (Rep) + Concentration + Instar + Concentration:Instar, data = DR)
summary(day1.lm)
##
## Call:
## lm(formula = DR$Day1p ~ (Block) + (Rep) + Concentration + Instar +
## Concentration:Instar, data = DR)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.56986 -0.08445 0.00331 0.07096 0.53949
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.021339 0.048693 0.438 0.6615
## Block 0.005729 0.011715 0.489 0.6252
## Rep -0.006667 0.008556 -0.779 0.4365
## Concentration 0.913095 0.065906 13.855 <2e-16 ***
## Instar -0.022310 0.013489 -1.654 0.0993 .
## Concentration:Instar 0.033535 0.024065 1.393 0.1646
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.1623 on 282 degrees of freedom
## Multiple R-squared: 0.83, Adjusted R-squared: 0.827
## F-statistic: 275.3 on 5 and 282 DF, p-value: < 2.2e-16
plot(day1.lm, which=1, bty="l")
#look at residuals
plot(residuals(day1.lm) ~ fitted(day1.lm), main="Residuals vs Fitted")
abline(h=0) #should look random
qqnorm(residuals(day1.lm))
qqline(residuals(day1.lm))
# fit with binomial dist
day1.lm2 <- glm((DR$Day1p)~ (DR$Block) + (DR$Rep) + (DR$Concentration) + (DR$Instar) + (DR$Concentration:DR$Instar), family = binomial(link = "logit"))
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
summary(day1.lm2)
##
## Call:
## glm(formula = (DR$Day1p) ~ (DR$Block) + (DR$Rep) + (DR$Concentration) +
## (DR$Instar) + (DR$Concentration:DR$Instar), family = binomial(link = "logit"))
##
## Deviance Residuals:
## Min 1Q Median 3Q Max
## -1.6080 -0.3367 -0.1780 0.2638 1.3359
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -2.51902 1.05333 -2.391 0.01678 *
## DR$Block 0.05248 0.21850 0.240 0.81017
## DR$Rep -0.06107 0.15964 -0.383 0.70205
## DR$Concentration 4.84531 1.53331 3.160 0.00158 **
## DR$Instar -0.39914 0.35381 -1.128 0.25926
## DR$Concentration:DR$Instar 0.64192 0.61519 1.043 0.29674
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 234.383 on 287 degrees of freedom
## Residual deviance: 53.056 on 282 degrees of freedom
## AIC: 153.42
##
## Number of Fisher Scoring iterations: 6
plot(day1.lm2, which=1, bty="l")
plot(residuals(day1.lm2) ~ fitted(day1.lm2), main="Residuals vs Fitted")
qqnorm(residuals(day1.lm2))
qqline(residuals(day1.lm2))
#binomial logit fits better
#compare linear model with DR, linear > DR due to lower AIC
AIC(Day1DR, day1.lm2, k=2)
## df AIC
## Day1DR 8 256.6130
## day1.lm2 6 153.4244
summary(day1.lm2)
##
## Call:
## glm(formula = (DR$Day1p) ~ (DR$Block) + (DR$Rep) + (DR$Concentration) +
## (DR$Instar) + (DR$Concentration:DR$Instar), family = binomial(link = "logit"))
##
## Deviance Residuals:
## Min 1Q Median 3Q Max
## -1.6080 -0.3367 -0.1780 0.2638 1.3359
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -2.51902 1.05333 -2.391 0.01678 *
## DR$Block 0.05248 0.21850 0.240 0.81017
## DR$Rep -0.06107 0.15964 -0.383 0.70205
## DR$Concentration 4.84531 1.53331 3.160 0.00158 **
## DR$Instar -0.39914 0.35381 -1.128 0.25926
## DR$Concentration:DR$Instar 0.64192 0.61519 1.043 0.29674
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 234.383 on 287 degrees of freedom
## Residual deviance: 53.056 on 282 degrees of freedom
## AIC: 153.42
##
## Number of Fisher Scoring iterations: 6
Other Tools:
#Using drm package to determine effective dose.
#compare log-logistic and Weibull models (pooling instar because non-significant)
Day1DR <- drm(DR$Day1p ~ DR$Concentration, data = DR, fct = LL.4())
Day1DR2 <- drm(DR$Day1p ~ DR$Concentration, data = DR, fct = W1.4())
Day1DR3 <- drm(DR$Day1p ~ DR$Concentration, data = DR, fct = W2.4())
par(mfrow=c(1,1), mar=c(3.2,3.2,.5,.5), mgp=c(2,.7,0))
plot(Day1DR, broken=TRUE, xlab="Conc", ylab="% Pupation", lwd=2, cex=1.2, cex.axis=1.2, cex.lab=1.2, bty="l")
plot(Day1DR2, add=TRUE, broken=TRUE, lty=2, lwd=2) #Weibull-1
plot(Day1DR3, add=TRUE, broken=TRUE, lty=3, lwd=2) #Weibull-2
#Effective dose using log-logistic model
ED(Day1DR,50,interval="delta")
##
## Estimated effective doses
##
## Estimate Std. Error Lower Upper
## e:1:50 0.45532 0.01532 0.42517 0.48548
ED(Day1DR,90,interval="delta")
##
## Estimated effective doses
##
## Estimate Std. Error Lower Upper
## e:1:90 0.809377 0.069525 0.672527 0.946227
ED(Day1DR,95,interval="delta")
##
## Estimated effective doses
##
## Estimate Std. Error Lower Upper
## e:1:95 0.98426 0.10692 0.77380 1.19473
edLL<-data.frame(ED(Day1DR,c(10,50,90),interval="delta", display=FALSE),ll="Log-logistic")
edW1<-data.frame(ED(Day1DR2,c(10,50,90),interval="delta", display=FALSE),ll="Weibull 1")
edW2<-data.frame(ED(Day1DR3,c(10,50,90),interval="delta", display=FALSE),ll="Weibull 2")
CombED<-rbind(edLL,edW1,edW2)
p1 <- ggplot(data=CombED[c(1,4,7),], aes(x=ll, y=Estimate))+ geom_bar(stat="identity", fill="lightgreen", colour="black")+
geom_errorbar(aes(ymin=Lower, ymax=Upper), width=0.1) + ylab("ED10")+ xlab("")
p2 <- ggplot(data=CombED[c(2,5,8),], aes(x=ll, y=Estimate))+ geom_bar(stat="identity", fill="lightgreen", colour="black")+
geom_errorbar(aes(ymin=Lower, ymax=Upper), width=0.1) + ylab("ED50")+ xlab("")
p3 <- ggplot(data=CombED[c(3,6,9),], aes(x=ll, y=Estimate))+ geom_bar(stat="identity", fill="lightgreen", colour="black")+
geom_errorbar(aes(ymin=Lower, ymax=Upper), width=0.1) + ylab("ED90")+ xlab("Sigmoid four parameter models")
plot_grid(p1,p2,p3, ncol=1)
Mortality Example 48 hr
Look at Day 2 (48hr) Mortality
summary(DR)
## Concentration Instar Block Rep Total Pupae %Pupated Day0 Day1p Day2p Day3p Day4p Day5p Day6p Day7p Day8p Day9p Day10p Day11p Day12p Day13p Day14p
## Min. :0.0000 Min. :1.00 Min. :1 Min. :1.00 Min. :10.00 Min. : 0.000 Min. :0.000 Min. :10.00 Min. :0.0000 Min. :0.0000 Min. :0.0000 Min. :0.00000 Min. :0.0000 Min. :0.0000 Min. :0.0000 Min. :0.0000 Min. :0.0000 Min. :0.0000 Min. :0.0000 Min. :0.0000 Min. :0.0000 Min. :0.0000
## 1st Qu.:0.1000 1st Qu.:1.75 1st Qu.:1 1st Qu.:1.75 1st Qu.:10.00 1st Qu.: 0.000 1st Qu.:0.000 1st Qu.:10.00 1st Qu.:0.0000 1st Qu.:0.0000 1st Qu.:0.0000 1st Qu.:0.08333 1st Qu.:0.1000 1st Qu.:0.1000 1st Qu.:0.1000 1st Qu.:0.1000 1st Qu.:0.1000 1st Qu.:0.1000 1st Qu.:0.1404 1st Qu.:0.1404 1st Qu.:0.4000 1st Qu.:0.4000
## Median :0.3750 Median :2.50 Median :2 Median :2.50 Median :10.00 Median : 0.000 Median :0.000 Median :10.00 Median :0.3000 Median :0.6500 Median :0.7500 Median :0.80000 Median :0.8500 Median :0.9000 Median :0.9000 Median :1.0000 Median :1.0000 Median :1.0000 Median :1.0000 Median :1.0000 Median :1.0000 Median :1.0000
## Mean :0.4333 Mean :2.50 Mean :2 Mean :2.50 Mean :10.17 Mean : 3.615 Mean :0.346 Mean :10.17 Mean :0.3924 Mean :0.5186 Mean :0.5499 Mean :0.56945 Mean :0.5846 Mean :0.6026 Mean :0.6179 Mean :0.6258 Mean :0.6367 Mean :0.6425 Mean :0.6745 Mean :0.6778 Mean :0.7434 Mean :0.7454
## 3rd Qu.:0.7500 3rd Qu.:3.25 3rd Qu.:3 3rd Qu.:3.25 3rd Qu.:10.00 3rd Qu.: 9.000 3rd Qu.:0.900 3rd Qu.:10.00 3rd Qu.:0.8000 3rd Qu.:1.0000 3rd Qu.:1.0000 3rd Qu.:1.00000 3rd Qu.:1.0000 3rd Qu.:1.0000 3rd Qu.:1.0000 3rd Qu.:1.0000 3rd Qu.:1.0000 3rd Qu.:1.0000 3rd Qu.:1.0000 3rd Qu.:1.0000 3rd Qu.:1.0000 3rd Qu.:1.0000
## Max. :1.0000 Max. :4.00 Max. :3 Max. :4.00 Max. :14.00 Max. :14.000 Max. :1.000 Max. :14.00 Max. :1.0000 Max. :1.0000 Max. :1.0000 Max. :1.00000 Max. :1.0000 Max. :1.0000 Max. :1.0000 Max. :1.0000 Max. :1.0000 Max. :1.0000 Max. :1.0000 Max. :1.0000 Max. :1.0000 Max. :1.0000
op <- par(mfrow = c(1, 2), mar=c(3.2,3.2,2,.5), mgp=c(2,.7,0))
plot(DR$Day2p ~ DR$Concentration, data = DR, main="Original Dose Scale")
plot(DR$Day2p ~ logit(DR$Concentration+0.01), data = DR, main="Logarithmic Dose Scale")
#Look at control data, make sure mortality is < ~ 5%
aggregate(DR[,10], list(DR$Concentration), mean)
## Group.1 Day2p
## 1 0.00 0.02500000
## 2 0.10 0.02689394
## 3 0.25 0.18882576
## 4 0.50 0.90416667
## 5 0.75 0.98541667
## 6 1.00 0.98125000
Option 1: Dose Response Curve
#option 1: use DR
Day2DR<-drm(DR$Day2p ~ (DR$Concentration), DR$Instar, data = DR, fct=LL.2(names=c("Slope", "LD50")), type=("binomial"), na.action=na.omit)
summary(Day2DR)
##
## Model fitted: Log-logistic (ED50 as parameter) with lower limit at 0 and upper limit at 1 (2 parms)
##
## Parameter estimates:
##
## Estimate Std. Error t-value p-value
## Slope:1 -4.275095 1.136144 -3.7628 0.0001680 ***
## Slope:2 -3.852419 0.963761 -3.9973 6.408e-05 ***
## Slope:3 -5.163489 1.361471 -3.7926 0.0001491 ***
## Slope:4 -4.556448 1.151696 -3.9563 7.612e-05 ***
## LD50:1 0.299385 0.035025 8.5478 < 2.2e-16 ***
## LD50:2 0.317748 0.039065 8.1339 4.299e-16 ***
## LD50:3 0.333927 0.036185 9.2284 < 2.2e-16 ***
## LD50:4 0.347131 0.039313 8.8299 < 2.2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#shows slope, LD50 is significantly different than 0 for each instar
par(mfrow = c(1, 1), mar=c(3.2,3.2,.5,.5), mgp=c(2,.7,0))
plot(Day2DR, broken=TRUE, xlim=c(0,2), bty="l", xlab="Concentration", ylab="Mortality")
EDcomp(Day2DR,c(50,50), reverse=TRUE)
##
## Estimated ratios of effect doses
##
## Estimate Std. Error t-value p-value
## 2/1:50/50 1.06134 0.18012 0.34053 0.73345
## 3/1:50/50 1.11538 0.17786 0.64870 0.51653
## 4/1:50/50 1.15948 0.18879 0.84473 0.39826
## 3/2:50/50 1.05092 0.17223 0.29566 0.76749
## 4/2:50/50 1.09247 0.18261 0.50639 0.61259
## 4/3:50/50 1.03954 0.16294 0.24266 0.80827
#Instar has little effect on mortality, instars 1 and 2 similar, 3 and 4 less responsive. Overall, model doesn't fit well.
#look at residuals
op <- par(mfrow = c(1, 2), mar=c(3.2,3.2,2,.5), mgp=c(2,.7,0))
plot(residuals(Day2DR) ~ fitted(Day2DR), main="Residuals vs Fitted")
qqnorm(residuals(Day2DR))
qqline(residuals(Day2DR))
#data not normally distributed
op <- par(mfrow = c(1, 2), mar=c(3.2,3.2,.5,.5), mgp=c(2,.7,0))
plot(Day2DR, broken=TRUE, bty="l", xlab="Conc", ylab="Mortality")
modelFit(Day2DR)
## Goodness-of-fit test
##
## Df Chisq value p value
##
## DRC model 232 71.717 1
#model doesn't fit very well, instar doesnt have much effect on DR
Option 2: Linear Model
#Option 2: look at linear model
pairs(DR$Day2p ~ (DR$Block) + (DR$Rep) + DR$Concentration + DR$Instar)
op <- par(mfrow = c(1, 1), mar=c(3.2,3.2,0,.5), mgp=c(2,.7,0))
plot(DR$Day2p ~ DR$Concentration, data = DR, bty="l")
day2.lm <- lm(DR$Day2p ~ (Block) + (Rep) + Concentration + Instar + Concentration:Instar, data = DR)
summary(day2.lm)
##
## Call:
## lm(formula = DR$Day2p ~ (Block) + (Rep) + Concentration + Instar +
## Concentration:Instar, data = DR)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.35969 -0.16212 -0.02192 0.11120 0.47196
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.061467 0.057127 1.076 0.283
## Block 0.007197 0.013744 0.524 0.601
## Rep -0.001654 0.010037 -0.165 0.869
## Concentration 1.112013 0.077320 14.382 <2e-16 ***
## Instar -0.021014 0.015825 -1.328 0.185
## Concentration:Instar 0.016180 0.028233 0.573 0.567
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.1904 on 282 degrees of freedom
## Multiple R-squared: 0.8257, Adjusted R-squared: 0.8226
## F-statistic: 267.1 on 5 and 282 DF, p-value: < 2.2e-16
plot(day2.lm, which=1, bty="l")
#look at residuals
plot(residuals(day2.lm) ~ fitted(day2.lm), main="Residuals vs Fitted")
abline(h=0) #should look random
qqnorm(residuals(day2.lm))
qqline(residuals(day2.lm))
# fit with binomial dist
day2.lm2 <- glm((DR$Day2p)~ (DR$Block) + (DR$Rep) + (DR$Concentration) + (DR$Instar) + (DR$Concentration:DR$Instar), family = binomial(link = "logit"))
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
summary(day2.lm2)
##
## Call:
## glm(formula = (DR$Day2p) ~ (DR$Block) + (DR$Rep) + (DR$Concentration) +
## (DR$Instar) + (DR$Concentration:DR$Instar), family = binomial(link = "logit"))
##
## Deviance Residuals:
## Min 1Q Median 3Q Max
## -1.4176 -0.2332 0.0301 0.1454 1.3145
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -3.6102 1.4276 -2.529 0.011443 *
## DR$Block 0.1167 0.2910 0.401 0.688496
## DR$Rep -0.0268 0.2122 -0.126 0.899487
## DR$Concentration 11.1180 3.3689 3.300 0.000966 ***
## DR$Instar -0.3291 0.4657 -0.707 0.479807
## DR$Concentration:DR$Instar 0.3105 1.2578 0.247 0.805051
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 313.890 on 287 degrees of freedom
## Residual deviance: 37.273 on 282 degrees of freedom
## AIC: 61.664
##
## Number of Fisher Scoring iterations: 7
plot(day2.lm2, which=1, bty="l")
plot(residuals(day2.lm2) ~ fitted(day2.lm2), main="Residuals vs Fitted")
qqnorm(residuals(day2.lm2))
qqline(residuals(day2.lm2))
#compare linear model with DR, linear > DR due to lower AIC
AIC(Day2DR, day2.lm, day2.lm2)
## df AIC
## Day2DR 8 189.95387
## day2.lm 7 -129.99081
## day2.lm2 6 61.66438