I'm trying to run a cross classified model using panel data and was hoping to get some help to verify if I'm on the right track (and get advice on my stata code).

My data looks at how student achievement is impacted by environmental factors, for simplicity sake let's just say it's air pollution. I have 4 years worth of data and in year 3, there was a major event that lead to a drop in air pollution during that year which started going up again in the 4th year.

Air pollution data was collected at the school level, and at the student neighbourhood level. Based on this structure, I believe I should be using a cross classified model.

Here's an example of my data:

Sample Data

With this data I believe time would be level 1, which is nested in student (level 2), which are both located in schools, and neighbourhoods (level 3).

Does this seem like a cross-classified application? If not, why not?

For my data, Mark is my dependent variable, and School and Home pollution, along with median income are the predictor variables.

In terms of implementing the cross-classified model in Stata, I've cobbled together some code based on the examples that I've seen in the online course from here:


and here:


xtmixed Mark i.time  School_Pollution Home_Pollution Income || _all: R.SCHOOL ||  Student_Neighbourhood: Home_Pollution, mle variance

Is my thinking about this being a cross-classified data structure correct and would this modeling approach in Stata be the best way to move forward?


1 Answer 1


This is a very good example of a cross-classified data structure, in which students are simultaneously nested in neighborhoods and schools. It is in fact one of the classic examples used to illustrate these models. You have the added twist of having longitudinal data, which does complicate matters.

From your example data it looks like both school pollution and home pollution are time-varying variables, which means that they vary both within- and across-persons. In other words some students, by virtue of where they go to school are exposed to more pollution whereas others, by virtue of where they live, are exposed to more pollution. By extension, some students might get doubly higher exposure by attending a school and living in a neighborhood with high pollution.

In terms of modeling this in Stata, your code is a start but not complete. You do not currently account for the Student_ID in the random part of your model. You only account for neighborhood and school. Here is the variance components model I would start with before adding predictors:

mixed Mark || _all: R.SCHOOL || Student_Neighbourhood || Student_ID:, mle variance

This allows you to have a random intercept for students (essential because you have repeated measures of students), schools and neighborhoods. By the way, I assume that because you have R.SCHOOL, there are fewer schools than neighborhoods? If so, then this is the right specification. The one thing this model lacks is the possibility that there are unique school by neighborhood effects, as I mentioned earlier. I would test for that possibility by creating an interaction term, running another mixed model with the interaction as a random intercept, and then run a likelihood ratio test (lrtest) to see if this more complicated model is warranted (a significant result would suggest that it is):

gen SchXNeigh = SCHOOL*Student_Neighbourhood 
mixed Mark || _all: R.SCHOOL || Student_Neighbourhood || SchXNeigh: || Student_ID:, mle variance

The other big piece to this is that it is not clear to me why you are modeling the association between home pollution and Mark as varying across neighborhoods. What is the research question driving such a model?

As a final software note, you are very likely going to be running up against Stata's limits with this model. R's lmer is much better at estimating these types of models.

  • $\begingroup$ Hi Erik, Thank you so much for your response I really appreciate it.I tried to run the model with the interaction effect, as you suggested but it won’t converge, it just keeps repeating and I get a message saying something like “Iteration 8: log likelihood = -82087.974 (backed up)”. I ended up using the iteration command to stop the model before it got stuck and from looking at the coefficients and then using lrtest it seems that the original model, without the interaction, is preferred. I’ve only used R once before but I’ll give it a shot to see if it can the interaction model. $\endgroup$ Dec 7, 2019 at 6:32
  • $\begingroup$ Regarding your question about why I included neighbourhood, I think the confusion is due to my own poor variable naming, sorry for that. When I said neighbourhood, I actually meant student’s home postal code (I thought neighbhourhood would be more universally understood since some countries use a different term than “postal code”, which I also referred to as student’s home pollution. So, my research question is does pollution impact student achievement? And I use home postal code and school level pollution measures as predictors. $\endgroup$ Dec 7, 2019 at 6:55
  • $\begingroup$ FYI, first install the haven() and lme4() packages. haven's read_dta will allow you to read Stata files in R. To run the model in R, you need to install the lme4 package. The model code would be as follows: lmer(Mark ~ 1 + (1|SCHOOL) + (1|Student_Neighbourhood) + (1|Student_ID). Then you can run a second model that adds (1|SchXNeigh) and run the anova() command to test which of the two models is a better fit to your data. $\endgroup$
    – Erik Ruzek
    Dec 9, 2019 at 15:05
  • $\begingroup$ In regards to your research question, I would start with a model that only allows Mark to vary across groups (often referred to as a random intercepts model), add in your predictors as non-varying "fixed" effects, and then consider whether to allow the association between the predictors and Mark to vary across groups (referred to as random slopes). The model where you allow home pollution's association with mark to vary across neighborhoods does not make a lot of sense to me, but perhaps you can justify it. $\endgroup$
    – Erik Ruzek
    Dec 9, 2019 at 15:10
  • $\begingroup$ Hi Erik, thank you so much for the information about using R and the code, I'll try it out. Regarding your second comment, just to make sure I understand correctly, you're saying I should start with a formula like this: xtmixed Mark schoolPollution HomePollution i.time || _all: R.SCHOOL || Student_Neighbourhood|| Student_ID:, mle variance $\endgroup$ Dec 11, 2019 at 20:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.