This thread from a couple of years ago describes how to extract data used to plot the smooth components of a fitted gam model. It works, but only when there is one smooth variable. I've got more than one smooth variable, and unfortunately I can only extract the smooths from the last of the series. Here is an example:
library(mgcv)
a = rnorm(100)
b = runif(100)
y = a*b/(a+b)
mod = gam(y~s(a)+s(b))
summary(mod)
plotData <- list()
trace(mgcv:::plot.gam, at=list(c(25,3,3,3)),
#this gets you to the location where plot.gam calls plot.mgcv.smooth (see ?trace)
#plot.mgcv.smooth is the function that does the actual plotting and
#we simply assign its main argument into the global workspace
#so we can work with it later.....
quote({
#browser()
plotData <<- c(plotData, pd[[i]])
}))
plot(mod,pages=1)
plotData
I'm trying to get the estimated smooth functions for both a
and b
, but the list plotData
only gives me estimates for b
. I've looked into the guts of the plot.gam
function, and I'm having a difficult time understanding how it works. If anybody has already solved this problem, I'd be grateful.
Gavin gave a great answer, but I wanted to provide one in terms of the original referenced post (as I just spent a good amount of time figuring out how that worked :).
I used the code directly from https://stats.stackexchange.com/questions/7795/how-to-obtain-the-values-used-in-plot-gam-in-mgcv and also found that I only got the last model returned. The reason for that is because of where the trace code snippet is being placed in the mgcv::plot.gam function. You need to make sure that the code is placed inside a for loop that iterates over m, and you control that by the at argument.
The following trace worked great for my version of mgcv:::plot.gam
It inserts the trace call right after this chunk in the mgcv:::plot.gam function:
and now the elements of plotData will correspond to the different variables plotted. Two functions I found very helpful for figuring out the right place to insert this trace call were
Updated Answer for mgcv >= 1.8-6
As of version 1.8-6 of mgcv,
plot.gam()
now returns the plotting data invisibly (from the ChangeLog):As such, and using
mod
from the example shown below in the original answer, one can doThe data therein can be used for custom plots etc.
The original answer below still contains useful code for generating the same sort of data used to generate these plots.
Original Answer
There are a couple of ways to do this easily, and both involve predicting from the model over the range of the covariates. The trick however is to hold one variable at some value (say its sample mean) whilst varying the other over its range.
The two methods involve:
The second of these is closer to (if not exactly what)
plot.gam
does.Here is some code that works with your example and implements the above ideas.
Now produce the prediction data
Predict fitted responses from the model for new data
This does bullet 1 from above
You can then plot
$fit
against the covariate inpdat
- though do remember I have predictions holdingb
constant then holdinga
constant, so you only need the first 100 rows when plotting the fits againsta
or the second 100 rows againstb
. For example, first addfitted
andupper
andlower
confidence interval data to the data frame of prediction dataThen plot the smooths using rows
1:100
for variablea
and101:200
for variableb
This produces
If you want a common y-axis scale then delete both
ylim
lines above, replacing the first with:Predict the contributions to the fitted values for the individual smooth terms
The idea in 2 above is done in almost the same way, but we ask for
type = "terms"
.This returns a matrix for
$fit
and$se.fit
Just plot the relevant column from
$fit
matrix against the same covariate frompdat
, again using only the first or second set of 100 rows. Again, for exampleThen plot the smooths using rows
1:100
for variablea
and101:200
for variableb
This produces
Notice the subtle difference here between this plot and the one produced earlier. The first plot include both the effect of the intercept term and the contribution from the mean of
b
. In the second plot, only the value of the smoother fora
is shown.