── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr 1.1.4 ✔ readr 2.1.5
✔ forcats 1.0.0 ✔ stringr 1.5.1
✔ ggplot2 3.5.1 ✔ tibble 3.2.1
✔ lubridate 1.9.3 ✔ tidyr 1.3.1
✔ purrr 1.0.2
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag() masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(haven)library(ggstatsplot)
Warning: package 'ggstatsplot' was built under R version 4.4.1
You can cite this package as:
Patil, I. (2021). Visualizations with statistical details: The 'ggstatsplot' approach.
Journal of Open Source Software, 6(61), 3167, doi:10.21105/joss.03167
library(lme4)
Warning: package 'lme4' was built under R version 4.4.1
Loading required package: Matrix
Attaching package: 'Matrix'
The following objects are masked from 'package:tidyr':
expand, pack, unpack
library(effects)
Warning: package 'effects' was built under R version 4.4.1
Loading required package: carData
lattice theme set by effectsTheme()
See ?effectsTheme for details.
library(ggeffects)
Warning: package 'ggeffects' was built under R version 4.4.1
library(emmeans)
Warning: package 'emmeans' was built under R version 4.4.1
Welcome to emmeans.
Caution: You lose important information if you filter this package's results.
See '? untidy'
library(gtsummary)
Warning: package 'gtsummary' was built under R version 4.4.1
library(sjPlot)
Warning: package 'sjPlot' was built under R version 4.4.1
Install package "strengejacke" from GitHub (`devtools::install_github("strengejacke/strengejacke")`) to load all sj-packages at once!
The following warnings were returned during `modify_header()`:
! For variable `Usability` (`Group = "Control-Z"`) and "min" statistic: no
non-missing arguments to min; returning Inf
! For variable `Usability` (`Group = "Control-Z"`) and "max" statistic: no
non-missing arguments to max; returning -Inf
! For variable `Usability` (`Group = "Control-A"`) and "min" statistic: no
non-missing arguments to min; returning Inf
! For variable `Usability` (`Group = "Control-A"`) and "max" statistic: no
non-missing arguments to max; returning -Inf
Variable
N
Control-Z
N = 59
1
Control-A
N = 37
1
Zapworks
N = 54
1
Augmentaty
N = 49
1
p-value
2
Sex
199
0.4
Male
27 (46%)
15 (41%)
24 (44%)
28 (57%)
Female
32 (54%)
22 (59%)
30 (56%)
21 (43%)
Age
199
<0.001
Mean (SD)
20.88 (0.97)
21.45 (1.04)
20.23 (1.30)
21.62 (1.36)
Median [Q1, Q3]
20.86 [20.37, 21.17]
21.06 [20.81, 22.00]
19.83 [19.46, 20.47]
20.99 [20.65, 22.45]
Min, Max
19.15, 24.62
20.33, 25.76
19.07, 25.71
20.31, 26.29
Rating
199
<0.001
Mean (SD)
7.44 (0.76)
7.31 (0.95)
8.36 (0.52)
8.87 (0.37)
Median [Q1, Q3]
7.40 [6.90, 8.10]
7.40 [6.80, 8.00]
8.40 [8.10, 8.70]
9.00 [8.80, 9.00]
Min, Max
6.00, 8.90
5.30, 8.90
6.30, 9.20
7.30, 9.40
Usability
93
0.049
Mean (SD)
NA (NA)
NA (NA)
61.6 (4.0)
63.9 (6.1)
Median [Q1, Q3]
NA [NA, NA]
NA [NA, NA]
61.0 [59.0, 64.0]
63.0 [60.0, 64.0]
Min, Max
Inf, -Inf
Inf, -Inf
54.0, 76.0
54.0, 80.0
1
n (%)
2
Pearson’s Chi-squared test; Kruskal-Wallis rank sum test
Esta es la nueva estructura de la base de datos, etiquetada de la forma adecuada para poder usarla en formato de publicaciones.
En ese gráfico tenemos la distribución de sexos según grupo, y no se aprecian diferencias en la distribución del sexo entre los tres grupos. Hay algo más de hombres en el grupo Augmentaty, pero la “V de Cramer” nos indica que el effect size es muy pequeño.
df %>%ggbetweenstats(x=Group, y=Age, bf.message =FALSE)+ylab("Age in years")+xlab("")
#Hacemos la prueba no paramétrica de Kruskal-Wallis para confirmar que hay diferencias en la edad entre los tres gruposdf %>%ggbetweenstats(x=Group, y=Age, bf.message =FALSE, type="non-parametric")+ylab("Age in years")+xlab("")
Prácticamente todos los grupos se diferencian entre sí por edades. No es que sea importante, pero es dificil justificar que la asignación de los individuos a su respectivo grupo es aleatoria. Cuidado con dar mucho peso a la aleatorización.
De esto os interesa especialmente que los grupos de control son similares entre sí, y que a su vez ambos controles se diferencian de cada intervención. Además las intervenciones se diferencian entre sí.
Análisis Univariante en forma de tablas en lugar de gráficos
En forma de tabla y dada la falta de normalidad de los datos, lo más conveniente es usar pruebas robustas no paramétricas
df %>%tbl_summary(include=c(Age,Rating,Usability),by = Group, # split table by groupmissing ="no"# don't list missing data separately ) |>add_n() |># add column with total number of non-missing observationsadd_p() |># test for a difference between groupsmodify_header(label ="**Variable**") |># update the column headerbold_labels()
Variable
N
Control-Z
N = 59
1
Control-A
N = 37
1
Zapworks
N = 54
1
Augmentaty
N = 49
1
p-value
2
Age
199
20.86 (20.37, 21.17)
21.06 (20.81, 22.00)
19.83 (19.46, 20.47)
20.99 (20.65, 22.45)
<0.001
Rating
199
7.40 (6.90, 8.10)
7.40 (6.80, 8.00)
8.40 (8.10, 8.70)
9.00 (8.80, 9.00)
<0.001
Usability
93
NA (NA, NA)
NA (NA, NA)
61.0 (59.0, 64.0)
63.0 (60.0, 64.0)
0.049
1
Median (Q1, Q3)
2
Kruskal-Wallis rank sum test
Análisis multivariante
En estos análisis anteriores no hemos corregido por edad, y ya que existían diferencias significativs entre los grupos, vamos a tenerlo en cuenta. Adicionalmente añadimos la variable sexo. No se espera que cambie nada, pero añadimos que se ha hecho para tener más robustez en la interpretación de los resultados:
No diría que la edad tiene mucho que decir en cuanto a afectar la Usability. No se alejan los modelo significativamente de la horizontal. Las diferencias en edad entre grupos no deberían tener consecuencia.