---
title: "Intro to Multilevel Model: Lecture 7 Example Code"
author: "Sunthud Pornprasertmanit"
output: html_document
date: "`r format(Sys.time(), '%d/%m/%Y')`"
---

```{css style settings, echo = FALSE}
blockquote {
    padding: 10px 20px;
    margin: 0 0 20px;
    font-size: 14px;
    border-left: 5px solid #eee;
    font-family: "Courier New";
}
```

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```

```{r xx, include=FALSE}
library(lme4)
library(effects)
library(interactions)
library(ggplot2)
library(psych)
out <- readr::read_rds("lecture7saveresults.rds")
ss41 <- out[[1]]
ss42 <- out[[2]]
ss31 <- out[[3]]
```

## No-Centering vs. Group-Mean-Centering

##### Example 1: Customers Satisfaction within Each Table in Dining Services

Read the data set from Lecture 4.

```{r readdata1}
dat3 <-read.table("lecture4ex3.csv", sep=",", header=TRUE)
```

Calculate group means by the `ave` function. The result has the same length as the original score and provides the group means that each data point belongs to. The group-mean centered variable is the difference between the original score and the group mean.

```{r calcgroupmean1}
dat3$aveage <- ave(dat3$age, dat3$tableid)
dat3$diffage <- dat3$age - dat3$aveage
```

Calculate the output when `age` is not centered. The regression coefficient of `age` equals both the between-table and within-table effects.

```{r nocentering1}
library(lme4)
out3m1 <- lmer(sat ~ 1 + age + (1|tableid), data=dat3, REML=FALSE)
summary(out3m1)
```

Check when `age` is group-mean centered. The regression coefficient represents the within-table effect.

```{r groupcenter1}
out3m2 <- lmer(sat ~ 1 + diffage + (1|tableid), data=dat3, REML=FALSE)
summary(out3m2)
```

Let's predict the customer satisfaction with group means of `age` too. Check the result when both the original scale of `age` and the group means of `age` are the predictors. The regression coefficient of the original scale of `age` is the within-table effect. However, the regression coefficient of the `age` table averages is the difference between within- and between-table effects.

```{r nocenterwithmean1}
out3m3 <- lmer(sat ~ 1 + age + aveage + (1|tableid), data=dat3, REML=FALSE)
summary(out3m3)
```

Check the result when both the group-centered `age` and the group means of `age` are the predictors. The regression coefficient of the group-centered `age` is the within-table effect and the regression coefficient of the `age` table averages is the between-table effect.

```{r groupcenterwithmean1}
out3m4 <- lmer(sat ~ 1 + diffage + aveage + (1|tableid), data=dat3, REML=FALSE)
summary(out3m4)
```

Before trying to find the cross-level interaction of `age`, the `age` needs to be rescaled to make the multilevel analysis convergent. The scaled age, `sage`, is the original scale of `age` divided by 10.

```{r rescale1}
dat3$sage <- dat3$age / 10
dat3$avesage <- ave(dat3$sage, dat3$tableid)
dat3$diffsage <- dat3$sage - dat3$avesage
```

Let's rerun the previous analyses. 

```{r rerunwithscaleage1}
out3m1 <- lmer(sat ~ 1 + sage + (1|tableid), data=dat3, REML=FALSE)
summary(out3m1)

out3m2 <- lmer(sat ~ 1 + diffsage + (1|tableid), data=dat3, REML=FALSE)
summary(out3m2)

out3m3 <- lmer(sat ~ 1 + sage + avesage + (1|tableid), 
               data=dat3, REML=FALSE)
summary(out3m3)

out3m4 <- lmer(sat ~ 1 + diffsage + avesage + (1|tableid), 
               data=dat3, REML=FALSE)
summary(out3m4)
```

The fifth model has `sage` (the original scale divided by 10), `avesage` (the group means), and their interaction. As mentioned in the lecture, the regression coefficients are not intuitive. The effect of `sage` represents the within-table effect at `avesage` of 0. The effect of `avesage` represents the difference between the within-table and between-table effect at `avesage` of 0. The interaction effect represents the increase in both within-table and between-table effects. 

```{r nocenteringinteraction1}
out3m5 <- lmer(sat ~ 1 + sage + avesage + sage:avesage 
               + (1 + sage|tableid), data=dat3, REML=FALSE)
summary(out3m5)
```

The sixth model has `diffsage` (the group-centered age), `avesage` (the group means), and their interaction. As mentioned in the lecture, the regression coefficients are easier to understand. The effect of `diffsage` represents the within-table effect at `avesage` of 0. The effect of `avesage` represents the between-table effect. The interaction effect represents the increase in within-table effects as `avesage` increased by 1. 

```{r groupcenteringinteraction1}
out3m6 <- lmer(sat ~ 1 + diffsage + avesage + diffsage:avesage 
               + (1 + diffsage|tableid), data=dat3, REML=FALSE)
summary(out3m6)
```

## Probing Cross-Level Interactions between the Same Predictor

##### Example 2: The Effect of Math Achievement on Perceived Self-Efficacy

Read the new data set and check the variables within data.

```{r readdata2}
dat4 <- read.table("lecture7ex1.csv", sep=",", header=TRUE)
library(psych)
describe(dat4)
```

Calculate the group means and group-mean-centered math achievement scores.

```{r calcgroupmean2}
dat4$aveach <- ave(dat4$ach, dat4$schoolid)
dat4$diffach <- dat4$ach - dat4$aveach
```

Predict self-efficacy with the group-mean-centered achievement, `diffach`, group means of achievement, `aveach`, its interaction, and whether the school is private, `private`.

```{r crosslevel2}
out4m1a <- lmer(efficacy ~ 1 + diffach + aveach + private
               + diffach:aveach
               + (1 + diffach|schoolid), data=dat4, REML=FALSE)
summary(out4m1a)
```

Find values for probing interactions. Let's check the within-school and between-school standard deviations of math achievement.

```{r nullmodel2}
out4m0 <- lmer(ach ~ 1 + (1|schoolid), data=dat4, REML=FALSE)
summary(out4m0)
```

The result of the null model showed that the school-level standard deviation was 9.637 and student-level standard deviation was 9.745. The grand mean of math achievement was 54.215. Thus, `aveach` values to examine the within-group effect is 55, $55 - 10 = 45$, $55 + 10 = 65$. Thus, `diffach` values to examine the between-group effect is -10, 0, 10.

```{r modvalues2}
aveachval <- c(45, 55, 65)
diffachval <- c(-10, 0, 10)
```

Use the `interactions` package to calculate simple slopes. First, check the within-school effect of math achievement at each level of schools' math achievement averages. 

```{r simpleslope21, eval=FALSE}
library(interactions)
ss41 <- sim_slopes(model=out4m1a, pred=diffach, modx=aveach, modx.values=aveachval)
```
```{r simpleslope211}
ss41
```

Use the `interactions` package can visualize the interaction. 

```{r interactionplot21}
interact_plot(model=out4m1a, pred=diffach, modx=aveach, modx.values=aveachval)
```

Next, check the simple slope of between-school effect of math achievement at each level of within-school deviation of math achievement. 

```{r simpleslope22, eval=FALSE}
ss42 <- sim_slopes(model=out4m1a, pred=aveach, modx=diffach, modx.values=diffachval)
```
```{r simpleslope222}
ss42
```
  
The interaction can be plotted as well.

```{r interactionplot22}
interact_plot(model=out4m1a, pred=aveach, modx=diffach, modx.values=diffachval)
```

##### Example 1: Customers Satisfaction within Each Table in Dining Services

Let's examine another example of cross-level interactions. Instead of `age`, the cross-level interaction of `female` is used. Calculate the group means and group-mean-centered `female`.

```{r calcgroupmean3}
dat3$avefemale <- ave(dat3$female, dat3$tableid)
dat3$difffemale <- dat3$female - dat3$avefemale
```

First, check whether the effect of `female` is varied across tables.

```{r randomslope3}
out3g1 <- lmer(sat ~ 1 + female + avefemale 
               + (1|tableid), data=dat3, REML=FALSE)
out3g2 <- lmer(sat ~ 1 + female + avefemale 
               + (1 + female|tableid), data=dat3, REML=FALSE)
anova(out3g1, out3g2)
```

Next, check whether the table proportions of females can predict the varying effect of `female`.

```{r crosslevel3}
out3g3 <- lmer(sat ~ 1 + female + avefemale + female:avefemale 
                + (1 + female|tableid), data=dat3, REML=FALSE)
anova(out3g2, out3g3)
```

The interaction effect was significant. Check the output.

```{r crosslevel32}
summary(out3g3)
```

As explained in the lecture, the between-table effect of females is actually curvilinear. Let's check the graph.

```{r curveplot3}
avefemale <- seq(0, 1, 0.01)
est <- coef(summary(out3g3))[,"Estimate"]
cust <- est[1] + ((est[2] + est[3]) * avefemale) + (est[4]*avefemale*avefemale)
plot(avefemale, cust, type="l", xlim=c(0, 1), ylim=c(60, 70), 
     xlab="Female Proportion in a Table", ylab="Customer Satisfaction")
```

The values of 20%, 50%, and 80% females in each table are used to probe the interaction.

```{r modvalues3}
avefemaleval <- c(0.2, 0.5, 0.8)
```

Check the simple slopes of the within-table effect of females at each level of the table proportions of females. 

```{r simpleslope31, eval=FALSE}
ss31 <- sim_slopes(model=out3g3, pred=female, modx=avefemale, modx.values=avefemaleval)
```
```{r simpleslope311}
ss31
```

Check the interaction plot.

```{r interactionplot31}
interact_plot(model=out3g3, pred=female, modx=avefemale, modx.values=avefemaleval)
```

Please not that the effect of the interaction of no-centered females and the table proportions of females is not only represent the moderating within-table effect but also the between-table effect too. The model is equally constrained the within- and between-table moderating effects. 

Thus, this model is not easy to understand. The better model in this case is to use group-mean-centered females. First, check the random intercept model.

```{r groupcenterrandomintercept3}
out3f1 <- lmer(sat ~ 1 + difffemale + avefemale + (1|tableid), 
               data=dat3, REML=FALSE, 
               control = lmerControl(optimizer ="Nelder_Mead"))
summary(out3f1)
```

Next, check whether the within-table effect of females is varied across tables.

```{r groupcenterrandomslope3}
out3f2 <- lmer(sat ~ 1 + difffemale + avefemale 
               + (1 + difffemale|tableid), data=dat3, REML=FALSE, 
               control = lmerControl(optimizer ="Nelder_Mead"))
anova(out3f1, out3f2)
```

Next, check whether the cross-level interaction is significant.

```{r groupcentercrosslevel3}
out3f3 <- lmer(sat ~ 1 + difffemale + avefemale + difffemale:avefemale 
               + (1 + difffemale|tableid), data=dat3, REML=FALSE, 
               control = lmerControl(optimizer ="Nelder_Mead"))
anova(out3f2, out3f3)
```

The cross-level interaction was not significant. Thus, the variation of within-table effect of females between tables was not significantly explained by the proportion of females in each table. However, the cross-level interaction was significant in the previous analysis using no-centered females. It is possible that the interaction between levels was not equal. The within-table effect did not have interaction whereas the between-table effect has the interaction. Thus, add the quadratic term of tables' female proportion in the random slope model.

```{r groupcenterquadratic3}
out3f4 <- lmer(sat ~ 1 + difffemale + avefemale + I(avefemale^2)
               + (1 + difffemale|tableid), data=dat3, REML=FALSE, 
               control = lmerControl(optimizer ="Nelder_Mead"))
anova(out3f2, out3f4)
```

The quadratic term was significant. Make sure whether the quadratic term of tables' female proportion predict the random slopes of the within-table effect of females.

```{r groupcenterquadraticinteraction3}
out3f5 <- lmer(sat ~ 1 + difffemale + avefemale + I(avefemale^2)
               + avefemale:difffemale + I(avefemale^2):difffemale
               + (1 + difffemale|tableid), data=dat3, REML=FALSE, 
               control = lmerControl(optimizer ="Nelder_Mead"))
anova(out3f4, out3f5)
```

The interaction effect was not significant. Let's check the output of the random slope model with quadratic terms.

```{r finalfemaleeffect3}
summary(out3f4)
```

Let's visualize the quadratic effect of the tables' female proportion.

```{r quadraticplot3}
est <- coef(summary(out3f4))
avefemale <- seq(0, 1, 0.01)
cust <- est[1] + (est[3] * avefemale) + (est[4]*avefemale*avefemale)
plot(avefemale, cust, type="l", xlim=c(0, 1), ylim=c(60, 70), 
     xlab="Female Proportion in a Table", ylab="Customer Satisfaction")

```
