Cannot assign to variable

I am new to the STAN language and would like to request help here in this space by asking about the error I am facing. In the code below the following line “x[i] = (pow(x[i], lambda[i]) - 1) / (lambda[i]);” displays the following error message: “Cannot assign to variable”.
Thanks a lot in advance!

data {
int<lower=1> N;
vector[N] n;
vector[N] x;
vector[N] y;
vector[N] p;
vector[N] lambda;
}

parameters {
real beta0;
real beta1;
}

transformed parameters {
for (i in 1:N){
if (lambda[i] != 0) {
x[i] = (pow(x[i], lambda[i]) - 1) / (lambda[i]);
}else{
x[i] = log(x[i]);
}
p = inv_logit(beta0 + beta1 * x);
}
}
model {
beta0 ~ normal(0, 100);
beta1 ~ normal(0, 100);
lambda ~ uniform(-5, 5);
y[i] ~ binomial(n[i],p[i]);
}

Thank you!

Welcome to the Stan forum.

Note that you declared x as data being passed to the model. I don’t think you can re-assign to data. Rather, you can create a new variable to hold your calculations. If the transformations only depend on the data, then you can (and should, for efficiency) do this in the transformed data block. If it depends on model parameters, then you have to do this in the transformed parameters or model blocks. See the Stan guide’s discussion of the program blocks for more details. In this case, x and lambda are both data, so it can go in the transformed data block. But p depends on beta0 and beta1, so needs to stay in transformed parameters.

Edit: fixed the model code.

data {
   int<lower=1> N;
   vector[N] n;
   vector[N] x;
   vector[N] y;
   vector[N] lambda;
}
transformed data{
   vector[N] x2;
   for (i in 1:N){
      if (lambda[i] != 0) {
         x2[i] = (pow(x[i], lambda[i]) - 1) / (lambda[i]);
      }else{
         x2[i] = log(x[i]);
      }
   }
}
parameters {
   real beta0;
   real beta1;
}
transformed parameters {
   vector[N] p = inv_logit(beta0 + beta1 * x2);
}
model {
   beta0 ~ normal(0, 100);
   beta1 ~ normal(0, 100);
   lambda ~ uniform(-5, 5);
   for (i in 1:N){
      y[i] ~ binomial(n[i],p[i]);
   } 
}
1 Like

Thank you so much @simonbrauer for taking your time to help me. But I was presented with a new error message, when using your code:

Semantic error in ‘string’, line 24, column 13 to column 14:

Identifier ‘p’ is already in use.

Thanks a lot in advance!

@simonbrauer I removed the variable “p” from the “data” block and left it only in the “transformed parameters” block and the following error message is being displayed.

Semantic error in ‘string’, line 29, column 10 to column 11:

Identifier ‘i’ not in scope.

I verify that it is line 29 where I have:

y[i] ~ binomial(n[i],p[i]);

I believe I can’t declare the variable “i” in the model block. Not what could be done to resolve it.

Thanks a lot in advance!

You’re right, I missed a couple small details. I’ve fixed the code above by

  1. Removing pfrom the data block
  2. Adding back the for loop that I accidentally removed

Made the necessary corrections, in my new code the following error message is displayed:

model = stan_model(“Model_1_A.stan”)

Error in stanc(file = file, model_code = model_code, model_name = model_name, : 0

Semantic error in ‘string’, line 43, column 5 to column 30:
Ill-typed arguments to ‘~’ statement. No distribution ‘binomial’ was found with the correct signature.

Below is the code:

data
{
int<lower=1> N;
vector[N] n;
vector[N] x;
vector[N] y;
vector[N] lambda;
}
transformed data
{
vector[N] x2;
for (i in 1:N){
if (lambda[i] != 0) {
x2[i] = (pow(x[i], lambda[i]) - 1) / (lambda[i]);
}else{
x2[i] = log(x[i]);
}
}
}
parameters
{
real beta0;
real beta1;
}
transformed parameters
{
vector[N] p;

for (c in 1:N)
{
p[c] = inv_logit(beta0 + beta1 * x2[c] * lambda[c]);
}

}
model
{
beta0 ~ normal(0, 100);
beta1 ~ normal(0, 100);
lambda ~ uniform(-5, 5);

for(j in 1:N)
{
y[j] ~ binomial(n[j], p);
}
}

Hi, @simonbrauer I found the problem, in the data block the variables were incorrectly declared, in the transformed parameters block the matrix equation was incorrect and in the model block the binomial distribution variables were also incorrect.
Thank you very much for your help, really the way you showed me was correct. Thank you so much for taking your time to help me! Below is the correct STAN code:

data
{
int<lower=1> N;
array[N] int y;
array[N] int n;
array[N] real x;
array[N] real lambda;
}
transformed data
{
vector[N] x2;
for (i in 1:N){
if (lambda[i] != 0) {
x2[i] = (pow(x[i], lambda[i]) - 1) / (lambda[i]);
}else{
x2[i] = log(x[i]);
}
}
}
parameters
{
real beta0;
real beta1;
}
transformed parameters
{
array[N] real p;
for (c in 1:N)
{
p[c] = inv_logit(beta0 + beta1 * x2[c] * lambda[c]);
}
}
model
{
beta0 ~ normal(0, 100);
beta1 ~ normal(0, 100);
for(j in 1:N)
{
y[j] ~ binomial(n[j], p[j]);
}
}

Here the R code:

library(“rstan”)
library(“ggplot2”)
library(“StanHeaders”)
options(mc.cores=4)

lambda = c(0.12,0.44,0.45,0.47,0.5,0.21,0.13,0.4,0.45,0.32,
0.23,0.3,0.23,0.15,0.38,0.26,0.11,0.17,0.5,0.19,0.15,0.14,0.22,0.17,4.9)

 x = c(9.21,10.21,10.58,10.83,11.03,11.33,11.58,11.83,12.08,
       12.33,12.58,12.83,13.08,13.33,13.58,13.83,14.08,14.33,
       14.58,14.83,15.08,15.33,15.58,15.83,17.58)
 
 n = c(376,200,93,120,90,88,105,111,100,93,100,108,99,106,105,117,
       98,97,120,102,122,111,94,114,1049)
 
 y = c(0,0,0,2,2,5,10,17,16,29,39,51,47,67,81,88,79,90,113,95,117,107,92,112,1049)

model = stan_model(“Model_1_A.stan”)

fit = sampling(model,list(N=25, n=n, y=y, x=x, lambda=lambda),iter=5000,chains=4)
print(fit)

1 Like