Data replication ( update : new version of ggplot2
may not like strange data frames with matrices in them?)
mydata <- data.frame( LogPesticide = rep(log(c(0, 0.1, 0.2, 0.4, 0.8, 1.6) + 0.05), 4), LogFood = rep(log(c(1, 2, 4, 8)), each = 6) ) set.seed(seed=16) growth <- function(x, a = 1, K = 1, r = 1) {
For comfort:
cc <- setNames(coef(model),c("b_int","b_P","b_F","b_PF")) vv <- vcov(model) dimnames(vv) <- list(names(cc),names(cc))
Baseline frame of forecast data:
pframe <- with(mydata, expand.grid(LogPesticide=seq(min(LogPesticide),max(LogPesticide), length=51), LogFood=unique(LogFood))) pframe$pmort <- predict(model,newdata=pframe,type="response")
Now let me break it. The predicted value at this level of (log) food F
and (log) pesticide P
is
logit(surv) = b_int + b_P*P + b_F*F + b_PF*F*P
Thus, the logistic curve for pesticide at level F
is
logit(surv) = (b_int+b_F*F) + (b_P+b_PF*F)*P
We want to know the value of P
for which logit (surv) is 0 (LC50), so we need
0 = (b_int+b_F*F) + (b_P+b_PF*F)*P50 P50 = -(b_int+b_F*F)/(b_P+b_PF*F)
Code translation:
P50mean <- function(logF) { with(as.list(cc), -(b_int+b_F*logF)/(b_P+b_PF*logF)) } with(mydata,P50mean(c(min=min(LogFood),max=max(LogFood)))) pLC50 <- data.frame(LogFood=unique(mydata$LogFood)) pLC50 <- transform(pLC50, pmort=0.5, LogPesticide=P50mean(LogFood))
To obtain confidence intervals, the two easiest methods are (1) the delta method and (2) retrospective prediction intervals (also referred to as “parametric bytes” in some contexts). (You can also perform nonparametric loading.)
Delta h2 method>
I tried to do it manually, but realized that it was getting too hairy (all four coefficients are strongly correlated, and all these correlations need to be tracked in the calculation - it's not as simple as the usual formulas, where the numerator and denominator are independent values ...)
library("emdbook") deltavar(-(b_int+b_F*2)/(b_P+b_PF*2),meanval=cc,Sigma=vv)
Population prediction intervals
This suggests (slightly weaker) that the distribution of sample parameters is multidimensional.
PP <- function(logF,n=1000) { b <- MASS::mvrnorm(n,mu=cc,Sigma=vv) pred <- with(as.data.frame(b), -(b_int+b_F*logF)/(b_P+b_PF*logF)) return(var(pred)) } set.seed(101) pLC50$var2 <- sapply(pLC50$LogFood,PP)
PPI would actually allow us to weaken our assumptions a bit by obtaining the quantiles of the distribution of the projected LC50 ... as it turns out (see below), PPI-based confidence intervals are slightly wider than Delta but they are not terribly far apart.
Now sketch the whole mess:
library(ggplot2); theme_set(theme_bw()) gg0 <- ggplot(mydata,aes(LogPesticide,pmort, colour=factor(LogFood), fill = factor(LogFood))) + geom_point() + ## individual fits -- a bit ugly ## geom_smooth(method="glm",aes(weight=N), ## method.args=list(family=binomial),alpha=0.1)+ geom_line(data=pframe,linetype=2)+ geom_point(data=pLC50,pch=5,size=4)+ geom_hline(yintercept=0.5,col="gray") gg0 + geom_errorbarh(data=pLC50,lwd=2,alpha=0.5, aes(xmin=LogPesticide-1.96*sqrt(var1), xmax=LogPesticide+1.96*sqrt(var1)), height=0)+ geom_errorbarh(data=pLC50, aes(xmin=LogPesticide-1.96*sqrt(var2), xmax=LogPesticide+1.96*sqrt(var2)), height=0.02)
