<center> # Repeated Measures ANOVA #### Psy202 Tutorial ### Jennet Baumbach <img src="data:image/png;base64,#repeated_measures_final.gif" width="500" /> --- > Researchers were interested in whether stress responses varied during different times throughout the day. Subjects were measured across four time points during the day, and were put under stress (noisy environment), and stress was measured on an arbitrary scale (larger value indicates more stress). SSTotal has already been calculated, at 1136.55. **There are 3 tasks today** **1.** Find the F statistics **2.** Determine the Critical F statistic **3.** draw a conclusion .pull-left[ ### Raw data: | ID| 7am| 1pm| 8pm| 11pm| |--:|---:|---:|---:|----:| | 1| 19| 20| 23| 19| | 2| 11| 11| 13| 12| | 3| 30| 31| 35| 31| | 4| 11| 12| 13| 11| | 5| 21| 20| 24| 20| ] .pull-right[ <img src="data:image/png;base64,#Stress_graph.png" width="1600" /> ] --- ## Code to Generate and Organize Data -- .pull-left[ ``` r # Packages used here library(reshape2) library(tidyverse) library(rstatix) # Generate long-form data frame data <- data.frame( ID = rep(1:5,4), Time = c(1,1,1,1,1, 2,2,2,2,2, 3,3,3,3,3, 4,4,4,4,4), Stress = c(19,11,30,11,21, 20,11,31,12,20, 23,13,35,13,24, 19,12,31,11,20)) ``` ] -- .pull-right[ ``` r head(data,15) ``` ``` ## ID Time Stress ## 1 1 1 19 ## 2 2 1 11 ## 3 3 1 30 ## 4 4 1 11 ## 5 5 1 21 ## 6 1 2 20 ## 7 2 2 11 ## 8 3 2 31 ## 9 4 2 12 ## 10 5 2 20 ## 11 1 3 23 ## 12 2 3 13 ## 13 3 3 35 ## 14 4 3 13 ## 15 5 3 24 ``` ] --- ## "By-hand" Calculations .pull-left[ `$$SS_{subjects} = k \;\sum_{i = 1}^n (\bar{X}_{si} - \bar{X}_{GM})^2$$` `$$df_{subjects} = n - 1$$` ] .pull-right[ `$$SS_{treatment} = n \; \sum_{j=1}^k(\bar{X}_j - \bar{X}_{GM})^2$$` `$$df_{treatment} = k - 1$$` `$$MS_{treatment} = \frac{SS_{treatment}}{df_{treatment}}$$` --- `$$SS_{error} = SS_{total} - SS_{subjects} - SS_{treatment}$$` `$$df_{error} = df_{total} - df_{subjects} - df_{treatment}$$` `$$MS_{error} = \frac{SS_{error}}{{df_{error}}}$$` --- `$$F = \frac{MS_{treatment}}{MS_{error}}$$` ] --- ## "By-hand" Calculations -- ### Step 1: Compute means required for calcuations: -- ``` r Grand_mean = mean(data$Stress) ID_1_mean = mean(data$Stress[data$ID == 1]) ID_2_mean = mean(data$Stress[data$ID == 2]) ID_3_mean = mean(data$Stress[data$ID == 3]) ID_4_mean = mean(data$Stress[data$ID == 4]) ID_5_mean = mean(data$Stress[data$ID == 5]) ``` --- ## "By-hand" Calculations -- ### Step 2: Compute `\(SS_{subjects}\)` and `\(df_{subjects}\)` -- .pull-left[ `$$SS_{subjects} = k \;\sum_{i = 1}^n (\bar{X}_{si} - \bar{X}_{GM})^2$$` ] -- .pull-right[ ``` r SS_subjects = 4 * ((ID_1_mean - Grand_mean)^2 + (ID_2_mean - Grand_mean)^2 + (ID_3_mean - Grand_mean)^2 + (ID_4_mean - Grand_mean)^2 + (ID_5_mean - Grand_mean)^2) print(SS_subjects) ``` ``` ## [1] 1094.8 ``` ] -- .pull-left[ `$$df_{subjects} = n - 1$$` ] -- .pull-right[ ``` r (df_subjects = 5-1) ``` ``` ## [1] 4 ``` ] --- ## "By-hand" Calculations -- ### Step 3: Compute treatment effect -- Generate wide-form data: ``` r wide_data <- dcast(ID ~ Time, data=data) wide_data <- wide_data[ ,c("ID","7am","1pm","8pm","11pm")] ``` -- ``` r knitr::kable(wide_data) ``` | ID| 7am| 1pm| 8pm| 11pm| |--:|---:|---:|---:|----:| | 1| 19| 20| 23| 19| | 2| 11| 11| 13| 12| | 3| 30| 31| 35| 31| | 4| 11| 12| 13| 11| | 5| 21| 20| 24| 20| --- ## "By-hand" Calculations -- ### Step 3: Compute treatment effect -- .pull-left[ `$$SS_{treatment} = n \; \sum_{j=1}^k(\bar{X}_j - \bar{X}_{GM})^2$$` ] -- .pull-right[ ``` r (SS_treatment = 5 * ((mean(wide_data$`7am`) - Grand_mean)^2 + (mean(wide_data$`1pm`) - Grand_mean)^2 + (mean(wide_data$`8pm`) - Grand_mean)^2 + (mean(wide_data$`11pm`) - Grand_mean)^2)) ``` ``` ## [1] 34.15 ``` ] -- .pull-left[ `$$df_{treatment} = k - 1$$` ] -- .pull-right[ ``` r (df_treatment = 4 - 1) ``` ``` ## [1] 3 ``` ] -- .pull-left[ `$$MS_{treatment} = \frac{SS_{treatment}}{df_{treatment}}$$` ] -- .pull-right[ ``` r (MS_treatment = SS_treatment / df_treatment) ``` ``` ## [1] 11.38333 ``` ] --- ## "By-hand" Calculations -- ### Step 4: Compute the error term -- `$$SS_{error} = SS_{total} - SS_{subjects} - SS_{treatment}$$` -- ``` r (SS_error = 1136.55 - SS_subjects - SS_treatment) ``` ``` ## [1] 7.6 ``` -- `$$df_{error} = df_{total} - df_{subjects} - df_{treatment}$$` -- ``` r (df_error = 19 - df_subjects - df_treatment) ``` ``` ## [1] 12 ``` -- .pull-left[ `$$MS_{error} = \frac{SS_{error}}{{df_{error}}}$$` ] -- .pull-right[ ``` r (MS_error = SS_error / df_error) ``` ``` ## [1] 0.6333333 ``` ] --- ## "By-hand" Calculations -- ### Step 5: Compute the F-statistic! -- .pull-left[ `$$F = \frac{MS_{treatment}}{MS_{error}}$$` ] -- .pull-right[ ``` r (F = MS_treatment / MS_error) ``` ``` ## [1] 17.97368 ``` ] -- #### Find the critical value -- ``` r # Manually find critical F value qf(p=.05,df1=3,df2=12,lower.tail=FALSE) # Same value as textbook :) ``` ``` ## [1] 3.490295 ``` -- #### Compare and Conclude -- The obtained F value is > the critical value, therefore we **reject the null hypothesis** --- # Confirm with R function! -- ``` r # Compute ANOVA (requires rstatix package) a <- anova_test(data=data,dv=Stress,within=Time,wid=ID) knitr::kable(get_anova_table(a)) ``` |Effect | DFn| DFd| F| p|p<.05 | ges| |:------|---:|---:|------:|--------:|:-----|----:| |Time | 3| 12| 17.974| 0.000098|* | 0.03| -- - Exact same F-value :) -- Seeing the same F-statistic makes me feel super confident that my by-hand calculations are correct! -- - I recommend using this strategy to study as you prepare for your exam!