I have a gam model that is:


the s(range) produces an e.d.f of 1, so I made the model:


There is very high concurvity (~0.85) between day and range in the first model (gam), but that goes away in the gam1 model. I am wondering why that is if s(range) is essentially the same as the parametric form of range. Is the concurvity/collinearity (not sure what to call it between a smoother and parametric term) still there, but simply not calculated by mgcv when it is a parametric term? Or are any co-dependence effects truly removed by simply changing "range" to its parametric form?


1 Answer 1


The concurvity moves from the stated smooth terms to the parametric terms, which concurvity groups in total under the para column of the matrix or matrices returned.

Here's a modified example from ?concurvity

## simulate data with concurvity...
n<- 200
f2 <- function(x) 0.2 * x^11 * (10 * (1 - x))^6 + 10 *
            (10 * x)^3 * (1 - x)^10
t <- sort(runif(n)) ## first covariate
## make covariate x a smooth function of t + noise...
x <- f2(t) + rnorm(n)*3
## simulate response dependent on t and x...
y <- sin(4*pi*t) + exp(x/20) + rnorm(n)*.3

## fit model...
b <- gam(y ~ s(t,k=15) + s(x,k=15), method="REML")

Now add a linear term and refit

x2 <- seq_len(n) + rnorm(n)*3
b2 <- update(b, . ~ . + x2)

Now look at the concurvity of the two models

## assess concurvity between each term and `rest of model'...

These produce

> concurvity(b)
                para       s(t)      s(x)
worst    1.06587e-24 0.60269087 0.6026909
observed 1.06587e-24 0.09576829 0.5728602
estimate 1.06587e-24 0.24513981 0.4659564
> concurvity(b2)
              para      s(t)      s(x)
worst    0.9990068 0.9970541 0.6042295
observed 0.9990068 0.7866776 0.5733337
estimate 0.9990068 0.9111690 0.4668871

Note that x2 is essentially a noisy version of t:

> cor(t, x2)
[1] 0.9975977

and hence the concurvity is gone up from essentially 0 in b to almost 1 in b2.

Now if we add x2 as a smooth function instead...

concurvity(update(b, . ~ . + s(x2)))

we see that the para entries return to being very small and we get a measure for the spline term s(x2) directly

> concurvity(update(b, . ~ . + s(x2)))
                 para      s(t)      s(x)     s(x2)
worst    1.506201e-24 0.9977153 0.6264654 0.9976988
observed 1.506201e-24 0.9838018 0.5893737 0.9963857
estimate 1.506201e-24 0.9909506 0.4921592 0.9943990

This is just how the function works in terms of the parametric terms; the focus is on the smooth terms.

Note: you are specifying gamma but fitting using REML. gamma only affects GCV and UBRE/AIC methods of smoothness selection, so you can remove this argument as it is having zero effect on the model fits. From version 1.8-23 of mgcv, the gamma argument no also affects models fitted using REML/ML, where smoothness parameters are selected BY REML/ML as if the sample size was $n/\gamma$ instead of $n$.

  • 2
    $\begingroup$ Thank-you, that was extremely informative! In general do you think it is necessary to remove highly concurve terms from the model? I have seen some studies in which they modify the gam based on concurvity, and others in which they cite the robustness of mgcv gams to concurvity and leave the model as is. $\endgroup$
    – Hannah
    Commented Oct 28, 2015 at 18:02
  • 1
    $\begingroup$ I'd be worried and want to dig in deeper. One thing Simon mentions in ?concurvity is that the model can be sensitive to modelling details. I suspect he means to the basis dimension and type, where the knots are, or other knobs you can fiddle which wouldn't ordinarily qualitatively change the model fit. So I'd play around with those things to see if the fit was robust to fiddling with them. Interpreting a model with high concurvity is tricky; two co-linear terms could be irrelevant but get high coefs as they cancel out. How would you deal with this with splines? Hard. $\endgroup$ Commented Oct 28, 2015 at 18:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.