This is the dataset of women where we measure equilibrium values and body composition values.
dato=read.csv("Data_Gervazoni_Natacha.csv",sep=";",dec=",",stringsAsFactors = TRUE,row.names = "ID") %>%
dplyr::select(-"X")
nutrition=colnames(dato)[1:15]
equilibrium=colnames(dato)[16:33]
tutte.variabili=c(nutrition,equilibrium)
dat=dato %>%
na.omit()
Equilibrium variables:
equilibrium
## [1] "FT.DELTA.desl" "FT.DELTA.deslap" "FT.DELTA.deslml" "FT.DELTA.vel"
## [5] "FT.DELTA.vel.ap" "FT.DELTA.vel.ml" "FT.DELTA.area" "FT.DELTA.ampap"
## [9] "FT.DELTA.ampml" "ST.DELTA.desl" "ST.DELTA.deslap" "ST.DELTA.deslml"
## [13] "ST.DELTA.vel" "ST.DELTA.vel.ap" "ST.DELTA.vel.ml" "ST.DELTA.area"
## [17] "ST.DELTA.ampap" "ST.DELTA.ampml"
Nutritional variables:
nutrition
## [1] "Age" "Weight" "Height"
## [4] "BMI" "Calf.C" "Arm.C"
## [7] "Waist.C" "Handgrip" "PhA"
## [10] "Z" "Zsp" "Flexion.Highest"
## [13] "Flexion.Media" "Extension.Highest" "Ext.Media"
Here is a summary of the data set removing missing data on the variables of interest. Values are reported for all visits.
variabili_numeriche <- dat %>%
dplyr::select(where(is.numeric)) %>%
names()
# Overall summary for numerical variables
totali_num <- dat %>%
summarise(across(all_of(variabili_numeriche),
list(mean = ~mean(.x, na.rm = TRUE),
sd = ~sd(.x, na.rm = TRUE),
n = ~sum(!is.na(.x)),
min = ~min(.x, na.rm = TRUE),
max=~max(.x, na.rm = TRUE)))) %>%
pivot_longer(cols = everything(),
names_to = c("var", ".value"),
names_sep = "_")
# Set options to avoid scientific notation
options(scipen = 999)
tabella_finale_num=totali_num %>%
mutate(across(c(mean, sd,min,max), ~round(., 1))) %>%
mutate(across(c(n), as.integer)) %>%
dplyr::select(var, mean, sd, min,max,n)
# Display the final table
kableExtra::kable(tabella_finale_num)
| var | mean | sd | min | max | n |
|---|---|---|---|---|---|
| Age | 69.5 | 5.9 | 60.1 | 87.6 | 112 |
| Weight | 65.5 | 11.2 | 40.7 | 95.6 | 112 |
| Height | 156.9 | 6.4 | 140.0 | 176.0 | 112 |
| BMI | 26.6 | 4.0 | 17.9 | 37.8 | 112 |
| Calf.C | 35.8 | 3.2 | 29.0 | 46.0 | 112 |
| Arm.C | 30.6 | 3.7 | 23.0 | 44.0 | 112 |
| Waist.C | 90.3 | 10.0 | 57.0 | 116.5 | 112 |
| Handgrip | 20.3 | 5.0 | 2.0 | 38.0 | 112 |
| PhA | 5.9 | 0.8 | 3.6 | 8.4 | 112 |
| Z | 387.4 | 42.0 | 265.7 | 493.5 | 112 |
| Zsp | 508.4 | 72.4 | 357.8 | 714.9 | 112 |
| Flexion.Highest | 58.5 | 14.9 | 21.7 | 103.7 | 112 |
| Flexion.Media | 56.1 | 14.6 | 19.9 | 101.5 | 112 |
| Extension.Highest | 94.1 | 24.7 | 45.2 | 164.2 | 112 |
| Ext.Media | 89.5 | 24.8 | 43.0 | 163.5 | 112 |
| FT.DELTA.desl | 2443.8 | 4667.7 | -7539.9 | 13109.2 | 112 |
| FT.DELTA.deslap | 1308.0 | 4593.5 | -9944.8 | 16838.8 | 112 |
| FT.DELTA.deslml | 1816.2 | 3246.2 | -4827.4 | 10188.4 | 112 |
| FT.DELTA.vel | 2.2 | 2.3 | -3.9 | 9.9 | 112 |
| FT.DELTA.vel.ap | 1.7 | 1.5 | -2.1 | 8.3 | 112 |
| FT.DELTA.vel.ml | 1.1 | 1.9 | -3.2 | 6.6 | 112 |
| FT.DELTA.area | 62.3 | 117.5 | -194.8 | 422.4 | 112 |
| FT.DELTA.ampap | 2.2 | 6.5 | -11.4 | 26.9 | 112 |
| FT.DELTA.ampml | 2.2 | 4.9 | -8.1 | 16.2 | 112 |
| ST.DELTA.desl | 2416.2 | 4644.4 | -17605.3 | 17867.0 | 112 |
| ST.DELTA.deslap | 1847.5 | 3560.3 | -11430.4 | 9401.1 | 112 |
| ST.DELTA.deslml | 1229.3 | 3383.1 | -13743.5 | 13776.1 | 112 |
| ST.DELTA.vel | 2.6 | 2.9 | -7.2 | 10.7 | 112 |
| ST.DELTA.vel.ap | 1.4 | 1.8 | -3.8 | 6.2 | 112 |
| ST.DELTA.vel.ml | 1.8 | 2.4 | -7.4 | 7.7 | 112 |
| ST.DELTA.area | 60.7 | 118.0 | -486.7 | 491.6 | 112 |
| ST.DELTA.ampap | 1.9 | 5.2 | -20.2 | 14.1 | 112 |
| ST.DELTA.ampml | 1.6 | 5.3 | -16.8 | 11.8 | 112 |
The response variables are the equilibrium variables and we want to investigate how body composition affect them.
We perform a principal component analysis on the equilibrium variables to reduce the number of response variables and then project the body composition variables on the principal components.
pca_equilibrium <- prcomp(dat %>% dplyr::select(all_of(equilibrium)), center = TRUE, scale. = TRUE)
summary(pca_equilibrium)
## Importance of components:
## PC1 PC2 PC3 PC4 PC5 PC6 PC7
## Standard deviation 2.7220 1.7936 1.4201 1.20489 0.99077 0.85130 0.73392
## Proportion of Variance 0.4116 0.1787 0.1120 0.08065 0.05453 0.04026 0.02992
## Cumulative Proportion 0.4116 0.5904 0.7024 0.78304 0.83757 0.87784 0.90776
## PC8 PC9 PC10 PC11 PC12 PC13 PC14
## Standard deviation 0.70693 0.56573 0.51099 0.48618 0.46198 0.28316 0.19844
## Proportion of Variance 0.02776 0.01778 0.01451 0.01313 0.01186 0.00445 0.00219
## Cumulative Proportion 0.93552 0.95330 0.96781 0.98094 0.99280 0.99725 0.99944
## PC15 PC16 PC17 PC18
## Standard deviation 0.06251 0.05909 0.03735 0.03549
## Proportion of Variance 0.00022 0.00019 0.00008 0.00007
## Cumulative Proportion 0.99966 0.99985 0.99993 1.00000
The first two principal components explain about 60% of the total variance. We can therefore use these two components as response variables in our analysis.
# Add the principal component scores to the original dataset
dat_pca <- dat %>%
mutate(PC1 = pca_equilibrium$x[, 1],
PC2 = pca_equilibrium$x[, 2])
Let’s plot the correlation circle to visualize the most important equilibrium variable into the PC according to the COS2 values and then project the body composition variables.
# Calculate coordinates for the correlation circle
correlation_circle <- as.data.frame(pca_equilibrium$rotation[, 1:2])
correlation_circle$Variable <- rownames(correlation_circle)
correlation_circle <- correlation_circle %>%
mutate(COS2 = correlation_circle$PC1^2 + correlation_circle$PC2^2)
# Calculate the correlation between PC and body composition variables
body_composition_vars <- dat %>%
dplyr::select(all_of(nutrition))
pc_scores <- dat_pca %>%
dplyr::select(PC1, PC2)
correlations <- map_dfr(names(body_composition_vars), function(var) {
cor_PC1 <- cor(body_composition_vars[[var]], pc_scores$PC1)
cor_PC2 <- cor(body_composition_vars[[var]], pc_scores$PC2)
data.frame(PC1 = cor_PC1, PC2 = cor_PC2,Variable = var,COS2 = cor_PC1^2 + cor_PC2^2)
})
# Add the correlations to the correlation circle
correlation_circle <- rbind(correlation_circle, correlations)
# Plot of the correlation circle with body composition variables projected in red to differentiate them from the others. Red-to-green gradient is applied for COS2 values of the body composition and equilibrium variables.
ggplot(correlation_circle, aes(x = PC1, y = PC2, label = Variable)) +
geom_segment(aes(xend = 0, yend = 0), arrow = arrow(length = unit(0.2, "cm")), color = ifelse(correlation_circle$Variable %in% nutrition, "red", "blue")) +
# geom_text(aes(color = ifelse(Variable %in% nutrition, COS2, NA)), hjust = 1.2, vjust = 1.2,size=1.5) +
scale_color_gradient(low = "green", high = "red", na.value = "black") +
xlim(-0.5, 0.2) + ylim(-0.5, 0.5) +
labs(title = "Correlation Circle with Body Composition Variables",
x = "PC1",
y = "PC2",
color = "COS2") +
theme_minimal() +
theme(legend.position = "right")
## Ignoring unknown labels:
## • colour : "COS2"
Orthogonality between body composition variables and equilibrium variables is a sign of independence. Some body composition variables show high correlation with the first two principal components of equilibrium.
Here we regress all equilibrium variable jointly against all body composition variables and report the coefficients along with their significance. The regression is the vector of equilibrium variables as response and all body composition variables as predictors.
For each equilibrium variable we calculate the median probability model using BayesVarSel and then we fit the regression for the equilibrium variable using only the selected body composition variables that form the median probability model.
The table below shows the body composition variables that significantly affect each equilibrium variable, along with their coefficients and p-values. These relations are in the so-called Median Probability Model, the model in which a regressor is more probable to affect the response than not to affect it.
# Combine all results into a single data frame
final_results <- bind_rows(results_list)
# Filter results for significant variables (p-value < 0.5) excluding the intercept
significant_results <- final_results %>%
filter(Variable != "(Intercept)" & `Pr(>|t|)` < 0.5) %>%
arrange(Equilibrium_Variable, `Pr(>|t|)`)
# Display the significant results
kableExtra::kable(significant_results, digits = 4, caption = "Significant Body Composition Variables Affecting Equilibrium Variables in some Median Probability Models")
| Estimate | Std. Error | t value | Pr(>|t|) | Variable | Equilibrium_Variable | |
|---|---|---|---|---|---|---|
| Calf.C…1 | 0.3713 | 0.1591 | 2.3337 | 0.0214 | Calf.C | FT.DELTA.ampml |
| Zsp | 0.0135 | 0.0069 | 1.9428 | 0.0546 | Zsp | FT.DELTA.ampml |
| Calf.C…3 | 0.2296 | 0.0658 | 3.4913 | 0.0007 | Calf.C | FT.DELTA.vel |
This analysis helps to identify which aspects of body composition are most relevant for maintaining equilibrium.
Here we calculate the regression models for the corresponding equilibrium variable using only those covariates in the median probability model. We report coefficients and model diagnostics. These models globally explain very little variability of the response.
# Fit the regression model for FT.DELTA.ampml using only Zsp and Calf.C
model_FT_DELTA_ampml <- lm(FT.DELTA.ampml ~ Zsp + Calf.C, data = dat)
summary(model_FT_DELTA_ampml)
##
## Call:
## lm(formula = FT.DELTA.ampml ~ Zsp + Calf.C, data = dat)
##
## Residuals:
## Min 1Q Median 3Q Max
## -10.5993 -2.6501 -0.1213 2.9498 12.4158
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -18.003950 5.006479 -3.596 0.000487 ***
## Zsp 0.013488 0.006943 1.943 0.054625 .
## Calf.C 0.371324 0.159115 2.334 0.021446 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 4.592 on 109 degrees of freedom
## Multiple R-squared: 0.1438, Adjusted R-squared: 0.1281
## F-statistic: 9.154 on 2 and 109 DF, p-value: 0.0002113
The model shows that both Zsp and Calf.C significantly affect FT.DELTA.ampml.
# Fit the regression model for FT.DELTA.vel using only Zsp
model_FT_DELTA_vel <- lm(FT.DELTA.vel ~ Zsp, data = dat)
summary(model_FT_DELTA_vel)
##
## Call:
## lm(formula = FT.DELTA.vel ~ Zsp, data = dat)
##
## Residuals:
## Min 1Q Median 3Q Max
## -6.1895 -1.4107 -0.2076 1.2214 7.0685
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -0.198623 1.535675 -0.129 0.897
## Zsp 0.004753 0.002990 1.589 0.115
##
## Residual standard error: 2.283 on 110 degrees of freedom
## Multiple R-squared: 0.02245, Adjusted R-squared: 0.01356
## F-statistic: 2.526 on 1 and 110 DF, p-value: 0.1148
The model shows that Zsp significantly affects FT.DELTA.vel.