I’d say it is a limitation of how random effects are implemented in (g)lmer
and how the so
basis, in particular, is constructed. In the same way that te()
smooths don’t work in gamm4()
and brm()
because the way those penalties are formed is incompatible with how random effects are represented in those functions.
Writing that got me thinking, however; I’d forgotten that Simon had implemented separate basis types for the hoop (boundary; bs = 'sf'
) and the film inside the hoop (bs = 'sw')
. These should have separable penalties which can be fit in lme()
and (g)lmer()
and hence smooth2random()
should work for these and thence (fingers crossed) should also work in brms.
Here is a modified version of your reproducible example:
library('tibble')
library('dplyr')
library('mgcv')
library('brms')
library('gamm4')
x <- c(0, 0, 1, 1,0)
y <- c(0, 1, 1, 0, 0)
x2 <- runif(100)
y2 <- runif(100)
z <- rnorm(100)
knots_test <- expand.grid(seq(0.1,0.9, length=5),
seq(0.1,0.9, length=5)) %>%
rename(x = Var1, y = Var2)
testdata <- tibble(z = z, x= x2, y=y2)
gam(z ~ s(x, y, bs = "so", xt = list(bnd = list(list(x=x, y=y)))),
data = testdata, method = "REML", knots = knots_test)
bndry <- list(list(x = x, y = y))
gamm(z ~ s(x, y, bs = "sf", xt = list(bnd = bndry)) +
s(x, y, bs = "sw", xt = list(bnd = bndry)),
data = testdata, method = "REML", knots = knots_test)
# works
gamm4(z ~ s(x, y, bs = "sf", xt = list(bnd = bndry)) +
s(x, y, bs = "sw", xt = list(bnd = bndry)),
data = testdata, method = "REML", knots = knots_test)
# works
brm(z ~ s(x, y, bs = "sf", xt = list(bnd = bndry)) +
s(x, y, bs = "sw", xt = list(bnd = bndry)),
data = testdata, knots = knots_test)
The brm()
call ends with the original error:
Error in smooth.construct.sw.smooth.spec(object, dk$data, dk$knots) :
need at least one interior knot
but I believe @paul.buerkner has this fixed in the GitHub version of brms. I haven’t had chance to test that version yet so if someone wanted to try this out I suspect it should work, at least in principle now.