Greetings! Thank you very much for the provided code and apologies for getting back to this so late, I just got back from my holidays.
I’ve tried to run your code, but I am getting some errors. Most of them are just some small syntax errors. Firstly, I think that there was a closing bracket missing in line 89. Could you confirm that this bracket needs to be placed here and not in any of the sub-expressions in the lines before?
Secondly, there was a semicolon missing in line 101. Thirdly, in lines 59, 63 and 67 it needs to say n_respondents
instead of n_resp
. As a forth thing, in lines 65 and 67 n_items_B
needs to be changed to n_items_C
. But as I said, these are all smaller problems.
I am running into a more serious problem at line 104. The induced_dirichlet_0
requires two vectors as arguments, c
and alpha
. It seems that c
is passed to the function in your code, but nothing that could represent alpha is being passed here. To try to bypass this problem I created the following variables in the data block:
vector[n_ordered_options_per_item_A] blah_a;
vector[n_ordered_options_per_item_B] blah_b;
vector[n_ordered_options_per_item_C] blah_c;
and I passed these as alpha
arguments to the induced_dirichlet_0
functions in the model block. My code now looks like this:
functions {
// Michael Betancourt's recommended prior for ordinal cutpoints:
real induced_dirichlet_0_lpdf(vector c, vector alpha) {
int K = num_elements(c) + 1;
vector[K - 1] sigma = inv_logit( - c);
vector[K] p;
matrix[K, K] J = rep_matrix(0, K, K);
// Induced ordinal probabilities
p[1] = 1 - sigma[1];
for (k in 2:(K - 1))
p[k] = sigma[k - 1] - sigma[k];
p[K] = sigma[K - 1];
// Baseline column of Jacobian
for (k in 1:K) J[k, 1] = 1;
// Diagonal entries of Jacobian
for (k in 2:K) {
real rho = sigma[k - 1] * (1 - sigma[k - 1]);
J[k, k] = - rho;
J[k - 1, k] = rho;
}
return dirichlet_lpdf(p | alpha)
+ log_determinant(J);
}
real induced_dirichlet_lpdf(vector c, vector alpha, real phi) {
int K = num_elements(c) + 1;
vector[K - 1] sigma = inv_logit(phi - c);
vector[K] p;
matrix[K, K] J = rep_matrix(0, K, K);
// Induced ordinal probabilities
p[1] = 1 - sigma[1];
for (k in 2:(K - 1))
p[k] = sigma[k - 1] - sigma[k];
p[K] = sigma[K - 1];
// Baseline column of Jacobian
for (k in 1:K) J[k, 1] = 1;
// Diagonal entries of Jacobian
for (k in 2:K) {
real rho = sigma[k - 1] * (1 - sigma[k - 1]);
J[k, k] = - rho;
J[k - 1, k] = rho;
}
return dirichlet_lpdf(p | alpha)
+ log_determinant(J);
}
}
data{
int n_respondents ;
int n_items_A ;
int n_ordered_options_per_item_A ;
matrix [n_respondents,n_items_A] A ;
int n_items_B ;
int n_ordered_options_per_item_B ;
matrix [n_respondents,n_items_B] B ;
int n_items_C ;
int n_ordered_options_per_item_C ;
matrix [n_respondents,n_items_C] C ;
vector[n_ordered_options_per_item_A] blah_a;
vector[n_ordered_options_per_item_B] blah_b;
vector[n_ordered_options_per_item_C] blah_c;
}
parameters{
// SEM parameters
vector[n_respondents] a_unique ;
vector[n_respondents] b_latent ;
vector[n_respondents] c_latent ;
vector<lower=-1,upper=1>[2] weights_bc ;
real<lower=0,upper=1> weight_a ;
// response-level parameters
array[n_items_A] ordered[n_ordered_options_per_item_A-1] cutpoints_A ;
array[n_items_B] ordered[n_ordered_options_per_item_B-1] cutpoints_B ;
array[n_items_C] ordered[n_ordered_options_per_item_C-1] cutpoints_C ;
}
transformed parameters{
vector[3] weights ;
weights[1] = weight_a ;
weights[2:3] = (
weights_bc
/ sqrt(sum(weights_bc.^2) // makes weights_bc have a unit norm
* sqrt(1-(weight_a.^2)) // makes weights have a unit norm
)) ;
}
model{
// priors for SEM
a_unique ~ std_normal() ;
b_latent ~ std_normal() ;
c_latent ~ std_normal() ;
// derived value for a
vector[n_respondents] a_latent = (
weights[1]*a_unique
+ weights[2]*b_latent
+ weights[3]*c_latent
);
// response-level priors & likelihood
for(i in 1:n_items_A){
cutpoints_A[i] ~ induced_dirichlet_0(n_ordered_options_per_item_A, blah_a);
A[:,i] ~ ordered_logistic( a_latent , cutpoints_A[i] );
}
for(i in 1:n_items_B){
cutpoints_B[i] ~ induced_dirichlet_0(n_ordered_options_per_item_B, blah_b);
B[:,i] ~ ordered_logistic( b_latent , cutpoints_B[i] );
}
for(i in 1:n_items_C){
cutpoints_C[i] ~ induced_dirichlet_0(n_ordered_options_per_item_C, blah_c);
C[:,i] ~ ordered_logistic( c_latent , cutpoints_C[i] );
}
}
However, that didn’t seem to work. For some reason, Stan now thinks that I am passing three arguments to the the induced_dirichlet_0
function instead of two. I don’t understand why since there is clearly only one comma in the brackets, thus clearly indicating that there are two and not three arguments. This is the error that I am getting:
Semantic error in 'string', line 107, column 2 to column 77:
-------------------------------------------------
105: // response-level priors & likelihood
106: for(i in 1:n_items_A){
107: cutpoints_A[i] ~ induced_dirichlet_0(n_ordered_options_per_item_A, blah_a);
^
108: A[:,i] ~ ordered_logistic( a_latent , cutpoints_A[i] );
109: }
-------------------------------------------------
Ill-typed arguments supplied to function 'induced_dirichlet_0':
(vector, int, vector)
Available signatures:
(vector, vector) => real
Expected 2 arguments but found 3 arguments.
Any ideas on how to continue with this? Any help would be appreciated.