tl;dr: Your model already accounts for the fact that you have repeated measures. Nonetheless, if it fits, you would do best to use:
glmer(y ~ x1*x2 + (x1:x2|subject), family=binomial)
but if that isn't tractable, you could try:
glmer(y ~ x1*x2 + (1|subject) + (0+x1|subject) + (0+x2|subject), family=binomial)
For an explanation of the syntax here, see: R's lmer cheat-sheet.
Full version: You don't need to "tell" R that $x_1$ and $x_2$ are repeated measures variables. (This is really just a small semantic distinction, but) I wouldn't say that variables can be "repeated measures variables" vs. "non-repeated measures variables". Variables are just variables. I would say that, e.g., 'variable 1 is measured within patients, and variable 2 is measured between patients' or something like that. Of course, your phrasing is fine, you just don't want it to lead to some confusion where you think of repeated measures-ness as some ontological status intrinsic to the variable.
At any rate, instead of telling R that a variable is measured within people, you simply need to formulate a model using random and/or effects fixed to account for the non-independence of the data that come from the same person. (Yes, you can use a fixed effect to account for this: every person would be a level of a categorical variable that is included. However, this will answer a slightly different question—almost certainly not the one you are interested in—and unless you have many measurements on the same person in every combination of conditions, the model will not be tractable.) In practice, you will use random effects to account for this. Specifically, you will have a random effect for each subject.
Next you need to specify what you want random effects for. The syntax you used, (1|subject)
, will cause R to include a random intercept for each person. This will shift someone's line of best fit up or down relative to the mean. You should think about whether people are also likely to differ in their slopes—i.e., how strongly they respond to changes in your variables. You should also think about whether the random effects are correlated with each other, e.g., maybe people who start off higher when $x_1=0$ tend to also respond more strongly to increases in $x_1$. Common advice is to include all possible random effects and intercorrelations (Barr et al., 2013, "Keep it maximal", pdf). However, bear in mind that GLMMs are more difficult computationally than LMMs, so such a model may not be tractable.
I believe there are some important problems to be addressed with your estimation.
From what I gathered by examining your data, your units are not geographically grouped, i.e. census tracts within counties. Thus, using tracts as a grouping factor is not appropriate to capture spatial heterogeneity as this means that you have the same number of individuals as groups (or to put another way, all your groups have only one observation each). Using a multilevel modelling strategy allows us to estimate individual-level variance, while controlling for between-group variance. Since your groups have only one individual each, your between-group variance is the same as your individual-level variance, thus defeating the purpose of the multilevel approach.
On the other hand, the grouping factor can represent repeated measurements over time. For example, in the case of a longitudinal study, an individual's "maths" scores may be recored yearly, thus we would have a yearly value for each student for n years (in this case, the grouping factor is the student as we have n number of observations "nested" within students). In your case, you have repeated measures of each census tract by decade
. Thus, you could use your TRTID10
variable as a grouping factor to capture "between decade variance". This leads to 3142 observations nested in 635 tracts, with approximately 4 and 5 observations per census tract.
As mentioned in a comment, using decade
as a grouping factor is not very appropriate, as you have only around 5 decades for each census tract, and their effect can be better captured introducing decade
as a covariate.
Second, to determine whether your data ought to be modelled using a poisson or negative binomial model (or a zero inflated approach). Consider the amount of overdispersion in your data. The fundamental characteristic of a Poisson distribution is equidispersion, meaning that the mean is equal to the variance of the distribution. Looking at your data, it is pretty clear that there is much overdispersion. Variances are much much greater than the means.
library(dplyr)
dispersionstats <- scaled.mydata %>%
+ group_by(decade) %>%
+ summarise(
+ means = mean(R_VAC),
+ variances = var(R_VAC),
+ ratio = variances/means)
## dispersionstats
## # A tibble: 5 x 5
## decade means variances ratio
## <int> <dbl> <dbl> <dbl>
## 1 1970 45.43513 4110.89 90.47822
## 2 1980 103.52365 17323.34 167.33707
## 3 1990 177.68038 62129.65 349.67087
## 4 2000 190.23150 91059.60 478.67784
## 5 2010 247.68246 126265.60 509.78821
Nonetheless, to determine if the negative binomial is more appropriate statistically, a standard method is to do a likelihood ratio test between a Poisson and a negative binomial model, which suggests that the negbin is a better fit.
library(MASS)
library(lmtest)
modelformula <- formula(R_VAC ~ factor(decade) + P_NONWHT * a_hinc + offset(HU_ln))
poismodel <- glm(modelformula, data = scaled.mydata, family = "poisson")
nbmodel <- glm.nb(modelformula, data = scaled.mydata)
lrtest(poismodel, nbmodel)
## Likelihood ratio test
## Model 1: R_VAC ~ factor(decade) + P_NONWHT * a_hinc + offset(HU_ln)
## Model 2: R_VAC ~ factor(decade) + P_NONWHT * a_hinc + offset(HU_ln)
## #Df LogLik Df Chisq Pr(>Chisq)
## 1 8 -154269
## 2 9 -17452 1 273634 < 2.2e-16 ***
## ---
## Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
After establishing this, a next test could consider whether the multilevel (mixed model) approach is warranted using similar approach, which suggests that the multilevel version provides a better fit. (A similar test could be used to compare a glmer fit assuming a poisson distribution to the glmer.nb object, as long as the models are otherwise the same.)
library(lme4)
glmmformula <- update(modelformula, . ~ . + (1|TRTID10))
nbglmm <- glmer.nb(glmmformula, data = scaled.mydata)
lrtest(nbmodel, nbglmm)
## Model 1: R_VAC ~ factor(decade) + P_NONWHT * a_hinc + offset(HU_ln)
## Model 2: R_VAC ~ factor(decade) + P_NONWHT + a_hinc + (1 | TRTID10) +
## P_NONWHT:a_hinc + offset(HU_ln)
## #Df LogLik Df Chisq Pr(>Chisq)
## 1 9 -17452
## 2 10 -17332 1 239.3 < 2.2e-16 ***
## ---
## Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Regarding the estimates of the poisson and nb models they are actually expected to be very similar to each other, with the main distinction being the standard errors, ie if overdispersion is present, the poisson model tends to provide biased standard errors. Taking your data as an example:
poissonglmm <- glmer(glmmformula, data = scaled.mydata)
summary(poissonglmm)
## Random effects:
## Groups Name Variance Std.Dev.
## TRTID10 (Intercept) 0.2001 0.4473
## Number of obs: 3142, groups: TRTID10, 635
## Fixed effects:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -2.876013 0.020602 -139.60 <2e-16 ***
## factor(decade)1980 0.092597 0.007602 12.18 <2e-16 ***
## factor(decade)1990 0.903543 0.007045 128.26 <2e-16 ***
## factor(decade)2000 0.854821 0.006913 123.65 <2e-16 ***
## factor(decade)2010 0.986126 0.006723 146.67 <2e-16 ***
## P_NONWHT -0.125500 0.014007 -8.96 <2e-16 ***
## a_hinc -0.107335 0.001480 -72.52 <2e-16 ***
## P_NONWHT:a_hinc 0.160937 0.003117 51.64 <2e-16 ***
## ---
## Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
summary(nbglmm)
## Random effects:
## Groups Name Variance Std.Dev.
## TRTID10 (Intercept) 0.09073 0.3012
## Number of obs: 3142, groups: TRTID10, 635
## Fixed effects:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -2.797861 0.056214 -49.77 < 2e-16 ***
## factor(decade)1980 0.118588 0.039589 3.00 0.00274 **
## factor(decade)1990 0.903440 0.038255 23.62 < 2e-16 ***
## factor(decade)2000 0.843949 0.038172 22.11 < 2e-16 ***
## factor(decade)2010 1.068025 0.037376 28.58 < 2e-16 ***
## P_NONWHT 0.020012 0.089224 0.22 0.82253
## a_hinc -0.129094 0.008109 -15.92 < 2e-16 ***
## P_NONWHT:a_hinc 0.149223 0.018967 7.87 3.61e-15 ***
## ---
## Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Notice how the coefficient estimates are all very similar, the main difference being only the significance of one of your covariates, as well as the difference in the random effects variance, which suggests that the unit-level variance captured by the overdispersion parameter in the nb model (the theta
value in the glmer.nb object) captures some of the between tract variance captured by the random effects.
Regarding exponentiated coefficients (and associated confidence intervals), you can use the following:
fixed <- fixef(nbglmm)
confnitfixed <- confint(nbglmm, parm = "beta_", method = "Wald") # Beware: The Wald method is less accurate but much, much faster.
# The exponentiated coefficients are also known as Incidence Rate Ratios (IRR)
IRR <- exp(cbind(fixed, confintfixed)
IRR
## fixed 2.5 % 97.5 %
## (Intercept) 0.06094028 0.05458271 0.06803835
## factor(decade)1980 1.12590641 1.04184825 1.21674652
## factor(decade)1990 2.46807856 2.28979339 2.66024515
## factor(decade)2000 2.32553168 2.15789585 2.50619029
## factor(decade)2010 2.90962703 2.70410073 3.13077444
## P_NONWHT 1.02021383 0.85653208 1.21517487
## a_hinc 0.87889172 0.86503341 0.89297205
## P_NONWHT:a_hinc 1.16093170 1.11856742 1.20490048
Final thoughts, regarding zero inflation. There is no multilevel implementation (at least that I am aware of) of a zero inflated poisson or negbin model that allows you to specify an equation for zero inflated component of the mixture. the glmmADMB
model lets you estimate a constant zero inflation parameter. An alternative approach would be to use the zeroinfl
function in the pscl
package, though this does not support multilevel models. Thus, you could compare the fit of a single level negative binomial, to the single level zero inflated negative binomial. Chances are that if zero inflation is not significant for single level models, it is likely that it would not be significant for the multilevel specification.
Addendum
If you are concerned about spatial autocorrelation, you could control for this using some form of geographical weighted regression (though I believe this uses point data, not areas). Alternatively, you could group your census tracts by an additional grouping factor (states, counties) and include this as a random effect. Lastly, and I am not sure if this is entirely feasible, it may be possible to incorporate spatial dependence using, for example, the average count of R_VAC
in first order neighbours as a covariate. In any case, prior to such approaches, it would be sensible to determine if spatial autocorrelation is indeed present (using Global Moran's I, LISA tests, and similar approaches).
Best Answer
You included id as a random coefficient in your model and are allowing each intercept to vary by id.
For example, if id represents a person, then repeated observations were taken for this person. You expect the slope (x) to be the same for each person but you wish to allow the intercept to vary (because people have different starting points perhaps). The random intercept term is normally distributed with mean equal to the overall intercept and variance equal to the estimated variance.
coef(model) is giving you the estimated intercept for each id. However, in your example, all the random intercepts are about the same and this additional parameter is not needed.