rggplot2mle

How do I plot a mle2 fit from frair package in ggplot2?


So I'm trying to plot a functional response curve in ggplot2, to do this I am using the frait_fit() and frair_boot() functions from the frair package (https://cran.r-project.org/web/packages/frair/frair.pdf). So I call frair_fit:

FRAM18.fitII<- frair_fit(eaten~density, data=FRAM18, 
                       response="rogersII", 
                       start = list(a = 1, h = 0.1), 
                       fixed = list(T = 3))

and get this

> summary(FRAM18.fitII)
             Length Class  Mode     
call          6     -none- call     
x            56     -none- numeric  
y            56     -none- numeric  
response      1     -none- character
xvar          1     -none- character
yvar          1     -none- character
optimvars     2     -none- character
fixedvars     1     -none- character
coefficients  3     -none- numeric  
sample       56     -none- numeric  
fit           1     mle2   S4 

And for frair_boot it looks like this:

FRAM18.bootII <- frair_boot(FRAM18.fitII, nboot=3000)
> summary(FRAM18.bootII)
             Length Class  Mode     
call              6 -none- call     
x                56 -none- numeric  
y                56 -none- numeric  
response          1 -none- character
xvar              1 -none- character
yvar              1 -none- character
optimvars         2 -none- character
fixedvars         1 -none- character
coefficients      3 -none- numeric  
bootcoefs      9000 -none- numeric  
sample       168000 -none- numeric  
n_failed          1 -none- numeric  
n_duplicated      1 -none- numeric  
n_boot            1 -none- numeric  
stratified        1 -none- logical  
fit              11 boot   list

I've tried using the predict and melt functions as outlined in this question How do I plot a mle2 fit of a model in ggplot2, along with the data? only to get:

> FRAM18.fitII2$mle2 <- predict(FRAM18.fitII,newdata=FRAM18.fitII2)
Error in UseMethod("predict") : 
  no applicable method for 'predict' applied to an object of class "c('frfit', 'list')"

With similar results with the boot function output.

I can create a graph using

plot(FRAM18.fitII$x,FRAM18.fitII$y, pch=20, col='skyblue2', xlim=c(0,300))
lines(FRAM18.fitII, col='skyblue3') 

but I'd like something more visually appealing.

The frair package tells me it uses mle2 to do its calculations so I'm wondering if there is a way to still get its output into ggplot2

My data looks like this:

density eaten
180 40
180 4
160 70
180 55
100 13
50 16
25 4
15 15
140 46
160 22
25 25
50 0
25 18
160 11
100 6
50 50
100 75
15 9
15 15
140 138
140 140

Solution

  • Load packages and data, do initial fit:

    library(frair)
    library(emdbook)
    data(ReedfrogFuncresp)
    newfit <- frair_fit(Killed~Initial, data=ReedfrogFuncresp,
                        response="rogersII", 
                        start = list(a = 1, h = 0.1), 
                        fixed = list(T = 1))
    

    Here's a predict method for the fitted model, which uses a bootstrap object (if provided) to construct confidence intervals:

    #' @param object fitted frair model
    #' @param newdata specified densities for prediction; data frame
    #' with density column name matching that of original model (\code{object$xvar})
    #' @param boot output of \code{frair_boot}
    #' @param quantiles for confidence intervals
    
    predict.frfit <- function(object, newdata = NULL, boot = NULL, quantiles = c(0.025, 0.975)) {
        fitfun <- get(object$response, pos = "package:frair")
        if (!is.null(newdata)) {
            newx <- newdata[[object$xvar]]
        } else {
            newx <- object$x
        }
        fitted <- fitfun(newx, as.list(object$coefficients))
        if (is.null(boot)) return(fitted)
        nms <- names(object$coefficients)
        bootvars <- boot$fit$t[,names(boot$fit$t0) %in% nms]
        colnames(bootvars) <- nms
        bootres <- apply(bootvars, 1,
                         function(b) fitfun(newx, as.list(b)))
        envelope <- t(apply(bootres, 1, quantile, quantiles))
        ret <- data.frame(fitted, envelope)
        names(ret) <- c(object$yvar, "lwr", "upr")
        return(ret)
    }
    
    library(ggplot2)
    pframe0 <- with(ReedfrogFuncresp,
                   data.frame(Initial = seq(0, max(Initial), length = 101)))
    
    ## basic (predicted value only)
    pframe <- data.frame(pframe0, Killed= predict(newfit, newdata=pframe0))
    
    ## with confidence intervals
    b <- frair_boot(newfit, ncores=3, nboot=250)
    pframe_b <- data.frame(pframe0, predict(newfit, newdata=pframe0, boot = b))
    
    ggplot(ReedfrogFuncresp, aes(Initial, Killed)) +
        geom_point() +
        geom_line(data = pframe_b) +
        geom_ribbon(data = pframe_b, aes(ymin=lwr, ymax=upr),
                    colour = NA, alpha = 0.4)
    

    points and predicted values, CI ribbon