This is an R Markdown document. Markdown is a simple formatting syntax for authoring HTML, PDF, and MS Word documents. For more details on using R Markdown see http://rmarkdown.rstudio.com.
When you click the Knit button a document will be generated that includes both content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this:
summary(cars)
## speed dist
## Min. : 4.0 Min. : 2.00
## 1st Qu.:12.0 1st Qu.: 26.00
## Median :15.0 Median : 36.00
## Mean :15.4 Mean : 42.98
## 3rd Qu.:19.0 3rd Qu.: 56.00
## Max. :25.0 Max. :120.00
# Instalar una sola vez, si es necesario
# install.packages(c(
# "tidyverse", "rstatix", "knitr",
# "broom", "effectsize", "ggpubr"
# ))
library(tidyverse)
## ── 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(rstatix)
##
## Adjuntando el paquete: 'rstatix'
##
## The following object is masked from 'package:stats':
##
## filter
library(knitr)
library(broom)
library(effectsize)
##
## Adjuntando el paquete: 'effectsize'
##
## The following objects are masked from 'package:rstatix':
##
## cohens_d, eta_squared, omega_squared
library(ggpubr)
options(
digits = 4,
scipen = 999
)
alpha <- 0.05
theme_set(
theme_classic(base_size = 12)
)
library(readxl)
datos <- read_excel("D:/usuario nuevo/Downloads/datos.xlsx")
View(datos)
datos <- tibble(
resina = rep(
c(
"Transcend",
"EasyMatch",
"SimpliShade",
"Vittra",
"Filtek Z350 XT"
),
each = 8
),
contraccion = c(
# Transcend
2.555022, 2.715731, 1.980722, 1.444973,
1.025596, 1.192092, 1.292739, 2.029705,
# EasyMatch
0.499976, 0.615494, 0.723248, 0.525220,
0.084800, 1.818979, 1.897403, 1.091361,
# SimpliShade
2.833384, 1.934640, 2.776268, 2.933820,
2.611012, 3.917132, 4.572182, 4.684513,
# Vittra
3.056665, 1.013055, 1.187163, 2.213193,
1.324839, 0.830841, 1.556931, 1.329415,
# Filtek Z350 XT
3.379659, 2.053056, 1.708239, 1.976309,
2.373803, 2.004132, 1.770787, 2.078057
)
) |>
mutate(
resina = factor(
resina,
levels = c(
"Transcend",
"EasyMatch",
"SimpliShade",
"Vittra",
"Filtek Z350 XT"
)
)
)
# Verificar la base
glimpse(datos)
## Rows: 40
## Columns: 2
## $ resina <fct> Transcend, Transcend, Transcend, Transcend, Transcend, Tra…
## $ contraccion <dbl> 2.5550, 2.7157, 1.9807, 1.4450, 1.0256, 1.1921, 1.2927, 2.…
# Número de observaciones por resina
datos |>
count(resina) |>
kable(
caption = "Número de observaciones por material"
)
| resina | n |
|---|---|
| Transcend | 8 |
| EasyMatch | 8 |
| SimpliShade | 8 |
| Vittra | 8 |
| Filtek Z350 XT | 8 |
##Verificación de calidad de los datos
# Dimensiones
cat("Número de observaciones:", nrow(datos), "\n")
## Número de observaciones: 40
cat("Número de resinas:", n_distinct(datos$resina), "\n")
## Número de resinas: 5
# Datos faltantes
datos |>
summarise(
observaciones = n(),
valores_faltantes = sum(is.na(contraccion)),
valores_no_finitos = sum(!is.finite(contraccion)),
valores_negativos = sum(contraccion < 0, na.rm = TRUE)
) |>
kable(caption = "Control de calidad de la variable principal")
| observaciones | valores_faltantes | valores_no_finitos | valores_negativos |
|---|---|---|---|
| 40 | 0 | 0 | 0 |
# Valores individuales
datos |>
arrange(resina, contraccion) |>
kable(
digits = 4,
caption = "Observaciones individuales de contracción (%)"
)
| resina | contraccion |
|---|---|
| Transcend | 1.0256 |
| Transcend | 1.1921 |
| Transcend | 1.2927 |
| Transcend | 1.4450 |
| Transcend | 1.9807 |
| Transcend | 2.0297 |
| Transcend | 2.5550 |
| Transcend | 2.7157 |
| EasyMatch | 0.0848 |
| EasyMatch | 0.5000 |
| EasyMatch | 0.5252 |
| EasyMatch | 0.6155 |
| EasyMatch | 0.7232 |
| EasyMatch | 1.0914 |
| EasyMatch | 1.8190 |
| EasyMatch | 1.8974 |
| SimpliShade | 1.9346 |
| SimpliShade | 2.6110 |
| SimpliShade | 2.7763 |
| SimpliShade | 2.8334 |
| SimpliShade | 2.9338 |
| SimpliShade | 3.9171 |
| SimpliShade | 4.5722 |
| SimpliShade | 4.6845 |
| Vittra | 0.8308 |
| Vittra | 1.0131 |
| Vittra | 1.1872 |
| Vittra | 1.3248 |
| Vittra | 1.3294 |
| Vittra | 1.5569 |
| Vittra | 2.2132 |
| Vittra | 3.0567 |
| Filtek Z350 XT | 1.7082 |
| Filtek Z350 XT | 1.7708 |
| Filtek Z350 XT | 1.9763 |
| Filtek Z350 XT | 2.0041 |
| Filtek Z350 XT | 2.0531 |
| Filtek Z350 XT | 2.0781 |
| Filtek Z350 XT | 2.3738 |
| Filtek Z350 XT | 3.3797 |
##Análisis descriptivo
tabla_descriptiva <- datos |>
group_by(resina) |>
summarise(
n = n(),
media = mean(contraccion),
DE = sd(contraccion),
mediana = median(contraccion),
Q1 = quantile(contraccion, 0.25),
Q3 = quantile(contraccion, 0.75),
RIC = IQR(contraccion),
minimo = min(contraccion),
maximo = max(contraccion),
.groups = "drop"
)
tabla_descriptiva |>
mutate(
across(where(is.numeric), ~ round(.x, 3))
) |>
kable(
caption = "Estadísticos descriptivos de la contracción por polimerización (%)"
)
| resina | n | media | DE | mediana | Q1 | Q3 | RIC | minimo | maximo |
|---|---|---|---|---|---|---|---|---|---|
| Transcend | 8 | 1.780 | 0.637 | 1.713 | 1.268 | 2.161 | 0.893 | 1.026 | 2.716 |
| EasyMatch | 8 | 0.907 | 0.649 | 0.669 | 0.519 | 1.273 | 0.754 | 0.085 | 1.897 |
| SimpliShade | 8 | 3.283 | 0.991 | 2.884 | 2.735 | 4.081 | 1.346 | 1.935 | 4.685 |
| Vittra | 8 | 1.564 | 0.731 | 1.327 | 1.144 | 1.721 | 0.577 | 0.831 | 3.057 |
| Filtek Z350 XT | 8 | 2.168 | 0.530 | 2.029 | 1.925 | 2.152 | 0.227 | 1.708 | 3.380 |
#- Una media más alta indica mayor contracción promedio en las observaciones analizadas. #- Una desviación estándar elevada indica mayor dispersión de los resultados dentro del grupo. #- La diferencia entre media y mediana puede sugerir asimetría. #- El rango intercuartílico muestra la amplitud del 50 % central de las mediciones. #En estos datos, SimpliShade tiene una media de 3,283 % y una mediana de 2,884 %. EasyMatch tiene una media de 0,907 % y una mediana de 0,669 %. Esta diferencia descriptiva es importante, pero no debe interpretarse automáticamente como una diferencia estadísticamente significativa ni como una diferencia de relevancia clínica.
##Gráfico de distribución por material
ggplot(datos, aes(x = resina, y = contraccion)) +
geom_boxplot(
aes(fill = resina),
alpha = 0.45,
width = 0.55,
outlier.shape = NA
) +
geom_jitter(
width = 0.10,
size = 2.4,
alpha = 0.85
) +
labs(
title = "Distribución de la contracción por polimerización",
subtitle = "Cinco resinas dentales",
x = "Material restaurador",
y = "Contracción por polimerización (%)"
) +
theme(
legend.position = "none",
axis.text.x = element_text(
angle = 20,
hjust = 1
)
)
#la línea central de cada caja representa la mediana; la caja representa
el rango intercuartílico y los puntos son las observaciones
individuales. Se aprecia una tendencia a valores más altos en
SimpliShade y más bajos en EasyMatch. La variabilidad de cada material
debe considerarse antes de establecer conclusiones sobre las diferencias
entre grupos
##Evaluación de los supuestos estadísticos #Normalidad mediante Shapiro–Wilk
tabla_normalidad <- datos |>
group_by(resina) |>
shapiro_test(contraccion) |>
ungroup() |>
mutate(
interpretacion = if_else(
p < alpha,
"Evidencia contra la normalidad",
"Sin evidencia suficiente contra la normalidad"
)
)
tabla_normalidad |>
mutate(
across(c(statistic, p), ~ round(.x, 4))
) |>
kable(
caption = "Prueba de normalidad de Shapiro-Wilk por material"
)
| resina | variable | statistic | p | interpretacion |
|---|---|---|---|---|
| Transcend | contraccion | 0.9151 | 0.3914 | Sin evidencia suficiente contra la normalidad |
| EasyMatch | contraccion | 0.8879 | 0.2236 | Sin evidencia suficiente contra la normalidad |
| SimpliShade | contraccion | 0.9010 | 0.2953 | Sin evidencia suficiente contra la normalidad |
| Vittra | contraccion | 0.8569 | 0.1119 | Sin evidencia suficiente contra la normalidad |
| Filtek Z350 XT | contraccion | 0.7609 | 0.0108 | Evidencia contra la normalidad |
#Hipótesis de la prueba: #- \(H_0\): los datos del grupo proceden de una distribución normal. #- \(H_1\): los datos del grupo no proceden de una distribución normal. #Criterio de interpretación: si \(p<0,05\), se rechaza la hipótesis de normalidad para ese grupo. Si \(p\geq0,05\), no hay evidencia suficiente para rechazarla; esto no demuestra que la distribución sea normal.
#En el cálculo preliminar, Filtek Z350 XT presentó un valor de \(p\) cercano a 0,011, lo que constituye evidencia contra la normalidad. Los otros cuatro grupos no mostraron evidencia estadística suficiente contra ese supuesto. Esto respalda la decisión de examinar también una alternativa no paramétrica.
##Gráficos Q-Q
ggplot(datos, aes(sample = contraccion)) +
stat_qq() +
stat_qq_line(color = "red") +
facet_wrap(~ resina, scales = "free") +
labs(
title = "Gráficos Q-Q de la contracción por material",
x = "Cuantiles teóricos",
y = "Cuantiles observados"
) +
theme_classic()
#si los puntos siguen aproximadamente la línea de referencia, la
distribución es compatible con la normalidad. Desviaciones sistemáticas,
curvaturas o puntos muy alejados de la línea pueden indicar asimetría o
valores extremos.
##Homogeneidad de varianzas
prueba_levene <- datos |>
levene_test(contraccion ~ resina, center = median)
prueba_levene |>
mutate(
across(where(is.numeric), ~ round(.x, 4))
) |>
kable(
caption = "Prueba de homogeneidad de varianzas de Levene"
)
| df1 | df2 | statistic | p |
|---|---|---|---|
| 4 | 35 | 0.7331 | 0.5756 |
#Hipótesis: #- \(H_0\): las varianzas de los cinco materiales son iguales. #- \(H_1\): al menos una varianza es diferente. #El cálculo preliminar produjo \(p\approx0,576\). Por tanto, no hay evidencia estadística suficiente para rechazar la homogeneidad de varianzas. Esto no prueba que las varianzas sean idénticas.
#Decisión metodológica: debido a la evidencia contra la normalidad en uno de los grupos y al tamaño muestral reducido, utilizaremos Kruskal–Wallis como análisis principal de comparación global y Dunn con ajuste de Holm para las comparaciones por pares.
##Comparación global de las cinco resinas #Prueba de Kruskal–Wallis
resultado_kw <- kruskal.test(
contraccion ~ resina,
data = datos
)
tabla_kw <- tibble(
prueba = "Kruskal-Wallis",
estadistico_H = unname(resultado_kw$statistic),
grados_libertad = unname(resultado_kw$parameter),
valor_p = resultado_kw$p.value,
decision = if_else(
resultado_kw$p.value < alpha,
"Rechazar H0",
"No rechazar H0"
)
)
tabla_kw |>
mutate(
estadistico_H = round(estadistico_H, 3),
valor_p = signif(valor_p, 4)
) |>
kable(
caption = "Comparación global de la contracción por polimerización"
)
| prueba | estadistico_H | grados_libertad | valor_p | decision |
|---|---|---|---|---|
| Kruskal-Wallis | 22.1 | 4 | 0.0002 | Rechazar H0 |
#Las hipótesis son: #- \(H_0\): las distribuciones de contracción de las cinco resinas son iguales. #- \(H_1\): al menos una distribución difiere de las demás. #En el caso de distribuciones con formas y dispersiones similares, la prueba se puede interpretar como una comparación de localización, incluida la mediana. En general, Kruskal–Wallis contrasta las distribuciones, no exclusivamente las medias.
#Resultado preliminar: \(H\approx22,103\), con 4 grados de libertad y \(p\approx0,000191\).
#Interpretación: como \(p<0,05\), se rechaza la hipótesis nula. Existe evidencia estadística de diferencias en la distribución de la contracción entre al menos dos de los cinco materiales.
#Este resultado global no indica por sí solo qué pares de resinas son diferentes. Para responder esa pregunta se necesita el análisis post hoc.
##Tamaño del efecto
H <- as.numeric(resultado_kw$statistic)
N <- nrow(datos)
k <- n_distinct(datos$resina)
epsilon2 <- max(0, (H - k + 1) / (N - k))
tibble(
estadistico_H = H,
N = N,
grupos = k,
epsilon_cuadrado = epsilon2
) |>
mutate(
across(where(is.numeric), ~ round(.x, 4))
) |>
kable(
caption = "Estimación del tamaño del efecto para Kruskal-Wallis"
)
| estadistico_H | N | grupos | epsilon_cuadrado |
|---|---|---|---|
| 22.1 | 40 | 5 | 0.5172 |
#El valor preliminar es \(\E^2\approx0,517\). Este resultado sugiere una separación importante entre los rangos de los grupos en estos datos. Debe interpretarse como una estimación descriptiva del tamaño del efecto, no como el porcentaje de contracción explicado causalmente por el material ni como una medida directa de importancia clínica.
##Comparaciones múltiples entre resinas #Prueba post hoc de Dunn con ajuste de Holm
resultado_dunn <- datos |>
dunn_test(
contraccion ~ resina,
p.adjust.method = "holm"
) |>
mutate(
diferencia_significativa = if_else(
p.adj < alpha,
"Sí",
"No"
)
)
resultado_dunn |>
select(
group1,
group2,
statistic,
p,
p.adj,
diferencia_significativa
) |>
mutate(
across(c(statistic, p, p.adj), ~ signif(.x, 4))
) |>
kable(
caption = "Comparaciones por pares mediante Dunn con corrección de Holm"
)
| group1 | group2 | statistic | p | p.adj | diferencia_significativa |
|---|---|---|---|---|---|
| Transcend | EasyMatch | -1.9890 | 0.0467 | 0.2803 | No |
| Transcend | SimpliShade | 2.4590 | 0.0139 | 0.0974 | No |
| Transcend | Vittra | -0.5560 | 0.5782 | 0.6935 | No |
| Transcend | Filtek Z350 XT | 0.9409 | 0.3467 | 0.6935 | No |
| EasyMatch | SimpliShade | 4.4480 | 0.0000 | 0.0001 | Sí |
| EasyMatch | Vittra | 1.4330 | 0.1519 | 0.6447 | No |
| EasyMatch | Filtek Z350 XT | 2.9300 | 0.0034 | 0.0271 | Sí |
| SimpliShade | Vittra | -3.0150 | 0.0026 | 0.0231 | Sí |
| SimpliShade | Filtek Z350 XT | -1.5180 | 0.1289 | 0.6447 | No |
| Vittra | Filtek Z350 XT | 1.4970 | 0.1344 | 0.6447 | No |
#El ajuste de Holm controla el error familiar asociado a realizar varias comparaciones. Para la interpretación, debe utilizarse la columna p.adj, no solamente el valor p sin ajustar. #- EasyMatch frente a SimpliShade: SimpliShade presenta valores de contracción más altos. #- EasyMatch frente a Filtek Z350 XT: Filtek Z350 XT presenta valores de contracción más altos. #- SimpliShade frente a Vittra: SimpliShade presenta valores de contracción más altos. #Las otras siete comparaciones no alcanzan significación estadística después del ajuste de Holm. Esto no demuestra que los materiales sean equivalentes; significa que el estudio no encontró evidencia suficiente para establecer una diferencia en esas comparaciones bajo el procedimiento utilizado.
##Visualización de las diferencias estadísticas #Gráfico de medianas e intervalos intercuartílicos
resumen_grafico <- datos |>
group_by(resina) |>
summarise(
mediana = median(contraccion),
Q1 = quantile(contraccion, 0.25),
Q3 = quantile(contraccion, 0.75),
.groups = "drop"
)
ggplot(
resumen_grafico,
aes(x = resina, y = mediana)
) +
geom_errorbar(
aes(ymin = Q1, ymax = Q3),
width = 0.15,
linewidth = 0.8
) +
geom_point(size = 3) +
labs(
title = "Mediana e intervalo intercuartílico de la contracción",
x = "Material restaurador",
y = "Contracción (%)"
) +
theme(
axis.text.x = element_text(
angle = 20,
hjust = 1
)
)
#Este gráfico complementa el diagrama de cajas y facilita la comparación
de la tendencia central y la dispersión de los cinco materiales. #cada
punto representa la mediana del grupo y cada barra vertical corresponde
al intervalo entre el primer y el tercer cuartil. Una posición más alta
representa mayor contracción central. La superposición de estos
intervalos no debe utilizarse como una prueba formal de significación
estadística; para eso se utilizarán los resultados de Dunn.
##Resumen estadístico para el artículo
cat(
sprintf(
paste0(
"Se analizaron %d observaciones correspondientes a %d materiales. ",
"La prueba de Kruskal-Wallis indicó ",
"H = %.3f, con %d grados de libertad y p = %.6f. ",
"El tamaño del efecto estimado mediante epsilon cuadrado fue %.3f. "
),
nrow(datos),
n_distinct(datos$resina),
as.numeric(resultado_kw$statistic),
as.numeric(resultado_kw$parameter),
resultado_kw$p.value,
epsilon2
)
)
## Se analizaron 40 observaciones correspondientes a 5 materiales. La prueba de Kruskal-Wallis indicó H = 22.103, con 4 grados de libertad y p = 0.000191. El tamaño del efecto estimado mediante epsilon cuadrado fue 0.517.
cat("\n\nComparaciones significativas después del ajuste de Holm:\n\n")
##
##
## Comparaciones significativas después del ajuste de Holm:
resultado_dunn |>
filter(p.adj < alpha) |>
transmute(
Comparacion = paste(group1, "vs.", group2),
p_ajustado = signif(p.adj, 4)
) |>
print()
## # A tibble: 3 × 2
## Comparacion p_ajustado
## <chr> <dbl>
## 1 EasyMatch vs. SimpliShade 0.0000866
## 2 EasyMatch vs. Filtek Z350 XT 0.0271
## 3 SimpliShade vs. Vittra 0.0231
#Análisis estadístico #La variable principal fue el porcentaje de contracción por polimerización de cinco materiales restauradores: Transcend, EasyMatch, SimpliShade, Vittra y Filtek Z350 XT. Se analizaron ocho observaciones por material, para un total de 40 observaciones.
#Se calcularon estadísticos descriptivos de tendencia central y dispersión, incluyendo media, desviación estándar, mediana y rango intercuartílico. La distribución de la variable se examinó mediante gráficos y la prueba de Shapiro–Wilk. La homogeneidad de varianzas se evaluó con la prueba de Levene centrada en la mediana.
#Debido al tamaño muestral reducido y a la evidencia de desviación de la normalidad en uno de los grupos, se utilizó la prueba de Kruskal–Wallis para evaluar diferencias globales entre materiales. Cuando se detectaron diferencias estadísticamente significativas, se realizaron comparaciones por pares mediante la prueba de Dunn, con ajuste de Holm para controlar el error por comparaciones múltiples.
#Se estableció un nivel de significación de 0,05. Adicionalmente, se estimó epsilon cuadrado como medida del tamaño del efecto. Los análisis se realizaron en RStudio mediante R.
#A partir de los resultados preliminares, se puede plantear la siguiente interpretación: #1. Variación entre materiales. Los porcentajes de contracción no se distribuyeron de forma idéntica entre las cinco resinas, según la prueba de Kruskal–Wallis. #2. Mayor contracción observada. SimpliShade presentó la media y la mediana más elevadas en la muestra analizada. Este resultado describe el comportamiento de las observaciones y no implica necesariamente que el material sea clínicamente inferior. #3. Menor contracción observada. EasyMatch presentó la menor media y mediana. Sin embargo, la dispersión de sus resultados debe tenerse en cuenta al valorar su reproducibilidad. #4. Diferencias entre pares. Las comparaciones post hoc identificaron diferencias entre EasyMatch y SimpliShade, EasyMatch y Filtek Z350 XT, y SimpliShade y Vittra. Las demás comparaciones no alcanzaron significación después de la corrección por multiplicidad.