Hi everyone,
I am trying to create a non-linear model to estimate trophic position based on Post 2002 and Heuvel et al. 2024. I can write this model in JAGS and use {rjags} to estimate ac
and tp
but would like to move over to stan and use {brms}. However, I consistently run into the following error message Error: The parameter 'd15n' is not a valid distributional or non-linear parameter. Did you forget to set 'nl = TRUE'?
. From what I can understand {brms} has issues with circular phased estimates considering I’m first estimating ac
which is then to be used in the formula for tp
. Is that correct? If so how can I get around this? I’ve thought of just inserting the formula for ac
into the tp
but this doesn’t seem to doing what I expect. Would it be best to write this in {rstan} instead?
If this question has been asked and answered before, sorry for taking up your time. Thanks
suppressPackageStartupMessages(
library(brms)
)
test <- structure(list(common_name = c("Lake Trout", "Lake Trout", "Lake Trout",
"Lake Trout", "Lake Trout", "Lake Trout", "Lake Trout", "Lake Trout",
"Lake Trout", "Lake Trout", "Lake Trout", "Lake Trout", "Lake Trout",
"Lake Trout", "Lake Trout"), d13c = c(-22.24432219, -22.19363157,
-23.12710892, -21.94797704, -22.09868526, -23.15772812, -22.46564577,
-22.06822162, -22.58020397, -22.78587869, -23.2490471, -22.09275059,
-22.27354166, -21.77119478, -22.02081495), d15n = c(18.0137765,
17.9057604, 17.04653059, 18.08178664, 17.44761289, 17.20065531,
17.98916764, 17.602950331349, 16.84128291, 17.14235167, 16.65215117,
17.7093308, 16.77823155, 18.284430048708, 17.12016153), n1 = c(8.823124606,
8.823124606, 8.823124606, 8.823124606, 8.823124606, 8.823124606,
8.823124606, 8.823124606, 8.823124606, 8.823124606, 8.823124606,
8.823124606, 8.823124606, 8.823124606, 8.823124606), n2 = c(12.629882536375,
12.629882536375, 12.629882536375, 12.629882536375, 12.629882536375,
12.629882536375, 12.629882536375, 12.629882536375, 12.629882536375,
12.629882536375, 12.629882536375, 12.629882536375, 12.629882536375,
12.629882536375, 12.629882536375), lambda = c(2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2), alpha = c(1.23643632363876, 1.24970560263278,
1.00534932149529, 1.31401056664222, 1.27455968957911, 0.99733413629192,
1.17850047020125, 1.28253415385541, 1.14851258059064, 1.0946731278142,
0.973429575190285, 1.27611320760606, 1.22878754563037, 1.36028684278827,
1.29494379355616), amin = c(0.885791396936097, 0.885791396936097,
0.885791396936097, 0.885791396936097, 0.885791396936097, 0.885791396936097,
0.885791396936097, 0.885791396936097, 0.885791396936097, 0.885791396936097,
0.885791396936097, 0.885791396936097, 0.885791396936097, 0.885791396936097,
0.885791396936097), amax = c(1.53574192008444, 1.53574192008444,
1.53574192008444, 1.53574192008444, 1.53574192008444, 1.53574192008444,
1.53574192008444, 1.53574192008444, 1.53574192008444, 1.53574192008444,
1.53574192008444, 1.53574192008444, 1.53574192008444, 1.53574192008444,
1.53574192008444)), row.names = c(NA, -15L), spec = structure(list(
cols = list(common_name = structure(list(), class = c("collector_character",
"collector")), d13c = structure(list(), class = c("collector_double",
"collector")), d15n = structure(list(), class = c("collector_double",
"collector")), n1 = structure(list(), class = c("collector_double",
"collector")), n2 = structure(list(), class = c("collector_double",
"collector")), lambda = structure(list(), class = c("collector_double",
"collector")), alpha = structure(list(), class = c("collector_double",
"collector")), amin = structure(list(), class = c("collector_double",
"collector")), amax = structure(list(), class = c("collector_double",
"collector"))), default = structure(list(), class = c("collector_guess",
"collector")), delim = ","), class = "col_spec"), class = c("spec_tbl_df",
"tbl_df", "tbl", "data.frame"))
tp_formula <- bf(
alpha ~ ac * (amax - amin) + amin,
d15n ~ dn * (tp - (lambda + n1 * ac + n2 * (1 - ac))),
ac ~ 1,
n1 ~ 1,
n2 ~ 1,
tp ~ 1,
dn ~ 1,
nl = TRUE
)
tp_priors <- c(
# Beta prior for 'ac'
brms::prior(beta(1, 1), class = "b", lb = 0, ub = 1, nlpar = "ac"),
# Baseline (n1)
brms::prior(normal(8, 1), class = "b", coef = "Intercept", nlpar = "n1"),
# Baseline (n2)
brms::prior(normal(10, 1), class = "b", coef = "Intercept", nlpar = "n2"),
# Trophic enrichment factor (ΔN)
brms::prior(normal(3.4, 0.5), class = "b", lb = 3, ub = 4, nlpar = "dn"),
# Trophic Position (tp)
brms::prior(uniform(2, 10), class = "b", nlpar = "tp", lb = 2, ub = 10),
# Standard deviation prior
brms::prior(uniform(0, 10), class = "sigma")
)
tp_fit <- brm(
formula = tp_formula,
data = test,
family = gaussian(),
prior = tp_priors,
iter = 4000,
warmup = 1000,
chains = 2,
cores = 4,
control = list(adapt_delta = 0.95)
)
#> Error: The parameter 'd15n' is not a valid distributional or non-linear parameter. Did you forget to set 'nl = TRUE'?
Created on 2025-02-12 with reprex v2.1.1