Anthony Hauser
Anthony Hauser

Reputation: 719

STAN in R: dimensions error in linear regression

Below you can find a simple example of linear regression with 2 predictors. It works well. However, when having only 1 predictor (see second script), the following error message appears:

Exception: mismatch in number dimensions declared and found in context; processing stage=data initialization; variable name=x; dims declared=(20,1); dims found=(20)

The problem is that a matrix with 1 row is automatically transformed in a vector and therefore, doesn't match with the declared dimensions. One solution would be to declare xas a vector, but the problem is that I'm running the same scripts with different number of predictors (could be 1 or more).

STAN script:

write("// Stan model for simple linear regression
data {
int<lower=0> N;  // number of data items
int<lower=0> K;// number of predictors
matrix[N, K] x;// predictor matrix
vector[N] y;// outcome vector
}
parameters {
real alpha;       // intercept
vector[K] beta;       // coefficients for predictors
real<lower=0> sigma;  // error scale
}
model {
y ~ normal(x * beta + alpha, sigma);  // likelihood
}", "ex_dimension.stan")

R script with 2 predictors (working):

N=20
K=2
x1=1:N+rnorm(N,0,0.5)
x2=rnorm(N,2,1)
x=cbind(x1,x2)
a=2
b=3
y=a*x1+b*x2+rnorm(N,0,1)


stan_data=list(N=N,
               K=K,
               x=x,
               y=y)
fit <- stan(file = "ex_dimension.stan",
            data = stan_data,
            warmup = 500,
            iter = 2000,
            chains = 4,
            cores = 4,
            thin = 1,
            control=list(adapt_delta=0.8))
fit

Script with 1 predictor (not working):

stan_data=list(N=N,
               K=1,
               x=x[,1],
               y=y)
fit <- stan(file = "ex_dimension.stan",
            data = stan_data,
            warmup = 500,
            iter = 2000,
            chains = 4,
            cores = 4,
            thin = 1,
            control=list(adapt_delta=0.8))
fit

Upvotes: 2

Views: 1403

Answers (1)

Joris C.
Joris C.

Reputation: 6234

Subset the matrix with drop = FALSE to avoid collapsing it to a vector and thereby passing the wrong input to the Stan model (see also e.g. Advanced R - Subsetting Chapter).

library(rstan)

stan_data <- list(N = N, K = 1, x = x[, 1, drop = FALSE], y = y)

fit <- stan(
    model_code = "// Stan model for simple linear regression
        data {
            int<lower=0> N;       // number of data items
            int<lower=0> K;       // number of predictors
            matrix[N, K] x;       // predictor matrix
            vector[N] y;          // outcome vector
        }
        parameters {
            real alpha;           // intercept
            vector[K] beta;       // coefficients for predictors
            real<lower=0> sigma;  // error scale
        }
        model {
            y ~ normal(x * beta + alpha, sigma);  // likelihood
        }",
    data = stan_data,
    chains = 1
)

fit
#> Inference for Stan model: 4f8ba0f0c644593f519910e9d2741995.
#> 1 chains, each with iter=2000; warmup=1000; thin=1; 
#> post-warmup draws per chain=1000, total post-warmup draws=1000.
#> 
#>           mean se_mean   sd   2.5%    25%    50%    75%  97.5% n_eff Rhat
#> alpha     6.26    0.06 1.20   3.93   5.49   6.25   7.04   8.68   470    1
#> beta[1]   2.00    0.00 0.10   1.81   1.94   2.00   2.06   2.19   453    1
#> sigma     2.70    0.02 0.50   1.87   2.35   2.62   2.97   3.88   458    1
#> lp__    -28.15    0.06 1.21 -31.12 -28.80 -27.84 -27.23 -26.74   366    1
#> 
#> Samples were drawn using NUTS(diag_e) at Thu Aug 15 12:41:19 2019.
#> For each parameter, n_eff is a crude measure of effective sample size,
#> and Rhat is the potential scale reduction factor on split chains (at 
#> convergence, Rhat=1).

Upvotes: 2

Related Questions