Prediction for a new observation in a new group

In page 274 of Data Analysis Using Regression and Multilevel/Hierarchical Models Gelman and Hill discuss how to do predictions for a new observation in a new group. Is there any example out there that shows how to implement this in Stan using the generated quantities block?

Hi, I don’t know of any specific examples, but you just use the values of the hyperparameters to draw new group-level predictors using the appropriate XXX_rng functions and then use those to directly compute the prediction. It is conceptually quite simple - are you struggling with the concept or with the actual implementation?

Thanks, @martinmodrak. I was able to implement what you describe but I just wanted to take a look at someone else’s code just to make sure I was following best practices. This is the code that I wrote:

generated quantities { 
  int<lower=0,upper=1>  y_rep[N] ;
  int<lower=0,upper=1>  y_pred[pred_N] ;
  vector[N] log_lik;
  real new_sch;
  real new_neighborhood;
  real new_sch_x_neighborhood;

  for(n in 1:N){
     y_rep[n]=bernoulli_logit_rng(lambda[n]) ;
     log_lik[n] = bernoulli_logit_lpmf(y[n] | lambda[n]);
  }
  
  for(n in 1:pred_N){
    // nothing new
    if(pred_idx_sch[n] < new_sch_idx && 
       pred_idx_neighborhood[n]  < new_neighborhood_idx) {
        y_pred[n]=bernoulli_logit_rng(sch[pred_idx_sch[n]] + 
                                      neighborhood[pred_idx_neighborhood[n]]  +
                                      sch_x_neighborhood[pred_idx_sch_x_neighborhood[n]] + 
                                      pred_X_centered[n,] * beta);
        } else if(pred_idx_sch[n] == new_sch_idx &&                            //  new school
                  pred_idx_neighborhood[n]  < new_neighborhood_idx){ 
                          
                  new_sch = normal_rng(mu_sch, sigma_sch);
                  new_sch_x_neighborhood = normal_rng(0, sigma_sch_x_neighborhood);
                  
                  y_pred[n] = bernoulli_logit_rng(new_sch + 
                              neighborhood[pred_idx_neighborhood[n]]  +
                              new_sch_x_neighborhood + 
                              pred_X_centered[n,] * beta);
       } else if(pred_idx_sch[n]== new_sch_idx &&                             // both new
                 pred_idx_neighborhood[n]  == new_neighborhood_idx){
                 
                 
                 new_sch = normal_rng(mu_sch, sigma_sch);
                 new_neighborhood = normal_rng(0, sigma_neighborhood);
                 new_sch_x_neighborhood = normal_rng(0, sigma_sch_x_neighborhood);
                 y_pred[n]=bernoulli_logit_rng(new_sch + 
                                                new_neighborhood +
                                                new_sch_x_neighborhood + 
                                                pred_X_centered[n,] * beta);
                 
       }else{                                                                       //  new neighborhood school
                  new_neighborhood = normal_rng(0, sigma_neighborhood);
                  new_sch_x_neighborhood = normal_rng(0, sigma_sch_x_neighborhood);
                  y_pred[n]=bernoulli_logit_rng(sch[pred_idx_sch[n]]  + 
                                                new_neighborhood +
                                                new_sch_x_neighborhood + 
                                                pred_X_centered[n,] * beta);
       }
    
  }
}