How does car work with nonlinear formula?

I cannot get car to run with non-linear formula specification. See example code:

library(brms)
library(cmdstanr)
library(tidyverse)
east <- north <- 1:10
Grid <- expand.grid(east, north)
K <- nrow(Grid)

# set up distance and neighbourhood matrices
distance <- as.matrix(dist(Grid))
W <- array(0, c(K, K))
W[distance <= 5] <- 1
rownames(W) <- 1:nrow(W)

# generate the covariates and response data
x1 <- rnorm(K)
x2 <- rnorm(K)
theta <- rnorm(K, sd = 0.05)
phi <- rmulti_normal(
  1, mu = rep(0, K), Sigma = 0.4 * exp(-0.1 * distance)
)
eta <- x1 + x2 + phi
prob <- exp(eta) / (1 + exp(eta))
size <- rep(50, K)
gr <- 1:length(size)
xx=tibble( size, x1, x2, gr)
set.seed(666)
dat=bind_rows(replicate(xx,n=6, simplify = FALSE))%>%
  mutate(name=rep(paste("Sim", 1:6), each = K))%>%
  st_as_sf(coords=c("x1","x2"))%>%
mutate(y=round(abs(rstudent_t(n=3,1, 0,1)*rpois(n=K*6,lambda = runif(1, min=10,max=125)))))
dat%>%st_drop_geometry()%>%group_by(name)%>%summarise(mean(y),var(y),min(y),max(y))

# fit a CAR model
fam= negbinomial()
fit <- brm(y  ~ 0+name + car(W, gr = gr),
           data = dat, data2 = list(W = W),
           family=fam,
           backend="cmdstanr",
           cores=4, threads=4) #adjust accordingly

# nonlinear with identity
fam= negbinomial(link="identity")
f0=bf(y  ~ exp(a)*size^b/g,
      a+b+g~0+name,
      shape~0+name,
      nl=T)

#get_prior(f0,fam,data=dat)
p1=c(prior(normal(0, 1), nlpar = a),
     prior(normal(0, 1), nlpar = b, lb = 0, ub=4),
      prior(exponential(1), nlpar = g, lb = 0),
     prior(normal(0,1), class=b,dpar = shape)
)
# ensure it works
fit0 <- brm(f0, 
            family=fam,
            data = dat, data2 = list(W = W),
            prior=p1,
            backend="cmdstanr",
           cores=4, threads=4) #adjust accordingly
#out=add_epred_draws(fit0,newdata=dat%>%st_drop_geometry()%>%select(y,name, size), ndraw=30)
#out%>%group_by(name)%>%mean_qi()

############# add in car

f1=bf(y  ~ exp(a)*size^b/g+car(W, gr = gr),
      a+b+g~0+name,
      shape~0+name,
      nl=T)
# this doesn't work probably because data2 isn't correctly repeated for name
get_prior(f1,fam,data=dat,data2=list(W=W, gr=gr))

# try just with single name
dat1=dat%>%filter(name == "Sim 1")
f1s<-bf(y  ~ exp(a)*size^b/g+car(W, gr = gr),
        a+b+g~1,
        shape~1,
        nl=T)  
# still can't find W in data, and it should look in data2...
get_prior(f1s,fam,data=dat,data2=list(W=W, gr=gr))
>Error in get(covars[i], data) : object 'W' not found

# checking for problem in brm, yep...
fit1s <- brm(f1s, 
            family=fam,
            data = dat, data2 = list(W = W),
            prior=p1,
            backend="cmdstanr",
            cores=4, threads=4)
>Error in get(covars[i], data) : object 'W' not found

What am I doing wrong?

Thanks, Herry

  • Operating System:x86_64, linux-gnu, R version 4.4.2 (2024-10-31)
  • brms Version: ‘2.22.0’