2

Solution So Far

I wanted to craft a quick function for plotting crossed random effects GAMM models since I will likely be using them a good deal in the future. Using ggplot and gratia as the backbone, I tried simulating some data and making this function that will save me some time without using the generic draw function, and so far that seems to work without issues. First, the simulated crossed random effects data:

#### Load Libraries ####
library(tidyverse)
library(mgcv)
library(gratia)

#### Sim Data ####
set.seed(123)
y <- rnorm(n=1000)
x <- rnorm(n=1000)
subjects <- factor(1:50)
items <- factor(1:20)
grid <- expand.grid(subjects,items)
df <- data.frame(x,y,subjects,items) %>% 
  as_tibble()
df

#### Sim Model ####
fit <- gam(
  y ~ s(x,k=20,sp=.001) 
  + s(subjects,bs="re") 
  + s(items,bs="re"),
  method = "REML",
  data = df
)

Then the function, which I've labeled with similar object names as shown here.

#### Craft Custom Function ####
draw.crossed <- function(model,data,x,n,re1,re2){

  ds <- data_slice(model, 
                    x = evenly({{x}}, n = n))
  
  fv <- fitted_values(model,
                       data = ds,
                       scale = "response",
                       exclude = c(re1,re2))
  fv |>
    ggplot(aes(x = x, 
               y = fitted)) +
    geom_ribbon(aes(ymin=lower,
                    ymax=upper),
                fill = "white",
                linetype = "dashed",
                color = "black")+
    geom_rug(data = data, 
             aes(x = {{x}}), 
             sides = "b",
             inherit.aes = FALSE, 
             length = grid::unit(0.01, "npc"), 
             alpha = 0.5)+
    geom_line(linewidth = 2)+
    theme_classic(base_size = 15)
}

Fitting it to my previous simulated data seems to have no problem:

draw.crossed(model = fit,
            x = x,
            data = df,
            n = 100,
            re1 = "s(subjects)",
            re2 = "s(items)")

enter image description here

Problem

However, if I try this again with another model/data, it seems to have some internal problem with the data_slice function that I can't figure out. For example, this model fit:

#### TROUBLE SHOOT ####

library(gamair)
data("wesdr")

fit.2 <- gam(
  ret ~ s(dur),
  method = "REML",
  data = wesdr,
  family = binomial
)

draw.crossed(model = fit.2,
            x = dur,
            n = 100,
            data = wesdr,
            re1 = NULL,
            re2 = NULL)

Just gives me this error, saying that my previously specified x variable isn't working:

Some specified variable(s) not used in model:
 * x

And this plot gets created which says nothing:

enter image description here

I thought maybe it was because I entered NULL into the re arguments, but even when I enter what I want into this area with other GAMM models, it throws back the same error and plot. How do I solve this?

Shawn Hemelstrand
  • 2,676
  • 4
  • 17
  • 30
  • You are setting `x = evenly({{x}},…)` in the data_slice call. You need to do the equivalent evaluation of x to yield the name, which uses := instead of =. – Gavin Simpson Mar 26 '23 at 18:42
  • I tried `ds <- data_slice(model, {{x}} := evenly({{x}}, n = n))` and `ds <- data_slice(model, {{x}} = evenly({{x}}, n = n))` and neither work. Unless you mean something else. – Shawn Hemelstrand Mar 26 '23 at 19:45
  • 1
    This might be one of those times when the developer needs to do something in their function to allow the kind of thing that you want to do in your wrapper. I’m away at the moment, but I can take a look next week when I am back – Gavin Simpson Mar 27 '23 at 15:56
  • No worries. Ill see if I can figure out a way. – Shawn Hemelstrand Mar 27 '23 at 23:09

0 Answers0