General Linear Models

Does strength correlate with movement skill?

  • Competency in fundamental movement skills (FMS) are seen as the “building blocks” for lifelong physical activity and long-term athlete development (LTAD).

  • Strength, fitness and perceived movement skills competence theorized to be key moderators or mediates of that relationship.

Hypotheses

We collected strength (IMTP peak and relative peak force & CMJ height) and movement skill Dragon Challenge) for 85 youth athletes (10 - 15 years of age, 59 female):

  • Strength would be associated with movement skill (Pearson’s correlations with lower 95% CI greater than 0.1)
  • Sex and maturation may be important confounding variables in the analysis.

Code

A simple Pearson’s correlation will provide the strength of the relationship between predictor (strength) and outcome movement skill:

cor.test(data$relative_strength_imtp, data$dragon_score)

    Pearson's product-moment correlation

data:  data$relative_strength_imtp and data$dragon_score
t = 3.5996, df = 83, p-value = 0.000541
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
 0.1674558 0.5384226
sample estimates:
      cor 
0.3674655 

Plotting

Linear model

We can set up the same correlation using the linear model function.

# base linear model
lm_base <- lm(dragon_score ~ relative_strength_imtp, data)
summary(lm_base)

Call:
lm(formula = dragon_score ~ relative_strength_imtp, data = data)

Residuals:
    Min      1Q  Median      3Q     Max 
-7.5601 -2.2497 -0.3844  2.5778  6.2955 

Coefficients:
                       Estimate Std. Error t value Pr(>|t|)    
(Intercept)            39.22863    2.05312   19.11  < 2e-16 ***
relative_strength_imtp  0.26940    0.07484    3.60 0.000541 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 3.125 on 83 degrees of freedom
Multiple R-squared:  0.135, Adjusted R-squared:  0.1246 
F-statistic: 12.96 on 1 and 83 DF,  p-value: 0.000541

Sex as co-variate

  • We can then plot and see if a factor such as “sex” effects the relationship
ggplot(data) +
  aes(
    x = relative_strength_imtp,
    y = time,
    colour = sex
  ) +
  geom_point(size = 2L) +
  geom_smooth(method = "lm", se = TRUE) +
  scale_color_manual(values = c(f = "#40004B", m = "#00441B")) +
  labs(
    x = "Relative Isometric Strength (N/kg)",
    y = "Dragon Challenge Time (s)"
  ) +
  theme_classic() +
  theme(
    axis.title.y = element_text(size = 13L,
                                face = "bold"),
    axis.title.x = element_text(size = 13L,
                                face = "bold"),
    axis.text.y = element_text(size = 13L),
    axis.text.x = element_text(size = 13L),
    legend.text = element_text(size = 14L),
    legend.title = element_text(size = 14L)
  ) 

Sex as co-variate

Visually boys are scoring higher than girls but the slopes look the same?

Slopes

We can model this:

lm_addsex <- lm(dragon_score ~ relative_strength_imtp + sex, data)
summary(lm_addsex)

Call:
lm(formula = dragon_score ~ relative_strength_imtp + sex, data = data)

Residuals:
    Min      1Q  Median      3Q     Max 
-7.5211 -1.7629 -0.4793  2.4677  6.1480 

Coefficients:
                       Estimate Std. Error t value Pr(>|t|)    
(Intercept)            38.26778    2.20441  17.360  < 2e-16 ***
relative_strength_imtp  0.31598    0.08447   3.741 0.000339 ***
sexm                   -0.97918    0.83032  -1.179 0.241698    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 3.118 on 82 degrees of freedom
Multiple R-squared:  0.1495,    Adjusted R-squared:  0.1287 
F-statistic: 7.204 on 2 and 82 DF,  p-value: 0.001311

Checking models

We can check models using the performance packages

compare_performance(lm_base, lm_addsex, rank = TRUE)
# Comparison of Model Performance Indices

Name      | Model |    R2 | R2 (adj.) |  RMSE | Sigma | AIC weights
-------------------------------------------------------------------
lm_addsex |    lm | 0.149 |     0.129 | 3.062 | 3.118 |       0.429
lm_base   |    lm | 0.135 |     0.125 | 3.088 | 3.125 |       0.571

Name      | AICc weights | BIC weights | Performance-Score
----------------------------------------------------------
lm_addsex |        0.404 |       0.181 |            57.14%
lm_base   |        0.596 |       0.819 |            42.86%

ANOVA

anova(lm_base, lm_addsex)
Analysis of Variance Table

Model 1: dragon_score ~ relative_strength_imtp
Model 2: dragon_score ~ relative_strength_imtp + sex
  Res.Df    RSS Df Sum of Sq      F Pr(>F)
1     83 810.67                           
2     82 797.15  1    13.519 1.3907 0.2417

Let’s look at absolute strength

Simple Pearson’s correlation?

cor.test(data$peak_force_imtp, data$dragon_score)

    Pearson's product-moment correlation

data:  data$peak_force_imtp and data$dragon_score
t = 0.97674, df = 83, p-value = 0.3315
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
 -0.109000  0.312622
sample estimates:
      cor 
0.1066005 

But let’s plot it by sex

Notice how we have opposing slopes.

Run models

  • Adding sex (keeping slopes fixed)

  • Adding force x sex interaction (modeling different slopes for boys and girls)

lm_base <- lm(dragon_score ~ peak_force_imtp, data)

lm_addsex <- lm(dragon_score ~ peak_force_imtp + sex, data)

lm_interaction <- lm(dragon_score ~ peak_force_imtp * sex, data)

Model performance

compare_performance(lm_base, lm_addsex, lm_interaction, rank = TRUE)
# Comparison of Model Performance Indices

Name           | Model |    R2 |  R2 (adj.) |  RMSE | Sigma | AIC weights
-------------------------------------------------------------------------
lm_interaction |    lm | 0.075 |      0.041 | 3.194 | 3.272 |       0.623
lm_base        |    lm | 0.011 | -5.476e-04 | 3.302 | 3.341 |       0.274
lm_addsex      |    lm | 0.012 |     -0.012 | 3.301 | 3.361 |       0.102

Name           | AICc weights | BIC weights | Performance-Score
---------------------------------------------------------------
lm_interaction |        0.574 |       0.151 |            87.12%
lm_base        |        0.318 |       0.764 |            31.78%
lm_addsex      |        0.107 |       0.084 |             0.17%

Model ANOVA

anova(lm_addsex, lm_interaction)
Analysis of Variance Table

Model 1: dragon_score ~ peak_force_imtp + sex
Model 2: dragon_score ~ peak_force_imtp * sex
  Res.Df    RSS Df Sum of Sq      F  Pr(>F)  
1     82 926.22                              
2     81 867.04  1    59.172 5.5279 0.02115 *
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Results from best model

summary(lm_interaction)

Call:
lm(formula = dragon_score ~ peak_force_imtp * sex, data = data)

Residuals:
    Min      1Q  Median      3Q     Max 
-9.5935 -2.1603  0.0473  1.9788  6.0967 

Coefficients:
                      Estimate Std. Error t value Pr(>|t|)    
(Intercept)          48.475926   1.921964  25.222   <2e-16 ***
peak_force_imtp      -0.001702   0.001517  -1.122   0.2651    
sexm                 -6.887493   3.118490  -2.209   0.0300 *  
peak_force_imtp:sexm  0.004977   0.002117   2.351   0.0211 *  
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 3.272 on 81 degrees of freedom
Multiple R-squared:  0.07488,   Adjusted R-squared:  0.04062 
F-statistic: 2.185 on 3 and 81 DF,  p-value: 0.09607

Plotting model outputs

First we generate a data set from the model

eff <- ggpredict(
  lm_interaction,
  terms = c("peak_force_imtp", "sex")
)

Plotting model outputs

head(eff)
# Predicted values of dragon_score

sex: f

peak_force_imtp | Predicted |       95% CI
------------------------------------------
            700 |     47.28 | 45.46, 49.11
            750 |     47.20 | 45.51, 48.89
            800 |     47.11 | 45.55, 48.68

sex: m

peak_force_imtp | Predicted |       95% CI
------------------------------------------
            700 |     43.88 | 40.93, 46.83
            750 |     44.04 | 41.23, 46.86
            800 |     44.21 | 41.52, 46.90

Plotting model outputs

Then we can use ggplot:

plot <- ggplot(eff, aes(x = x, y = predicted, colour = group, fill = group)) +
  geom_line(size = 1) +
  geom_ribbon(aes(ymin = conf.low, ymax = conf.high), alpha = 0.2, colour = NA) +
  labs(
    x = "IMTP Relative Peak Force (N/kg)",
    y = "Dragon Challenge Score (AU)",
    colour = "Sex",
    fill = "Sex"
  ) +
  theme_classic()

Plotting model outputs

Conclusions

  • Have a clear questions first!

  • Consider theory based hypotheses

  • Consider confounding factors

  • Quick visualisations can help inform model choices

  • Check models and go with the best ones