La detección temprana de fatiga vocal y la evaluación objetiva de la técnica vocal en cantantes y profesionales de la voz requieren enfoques cuantitativos que integren variables acústicas y medidas psicométricas. Este artículo presenta un estudio simulado (n = 240 mediciones) donde se modela la relación entre indicadores acústicos (HNR, jitter, shimmer, intensidad) y un puntaje de fatiga vocal (0–100), además de comparar un grupo con entrenamiento técnico versus un grupo control.
Cuantificar:
library(tidyverse)
library(knitr)
library(kableExtra)
library(psych)
library(broom)
set.seed(42)
n <- 240
datos <- tibble(
ID = 1:n,
Grupo = sample(c("Entrenamiento_técnico", "Control"), size = n, replace = TRUE),
Sesion = sample(1:6, size = n, replace = TRUE),
F0_Hz = rnorm(n, mean = 220, sd = 30),
Intensidad_dB = rnorm(n, mean = 75, sd = 5) + ifelse(Grupo == "Entrenamiento_técnico", 1.5, 0),
Jitter_pct = rgamma(n, shape = 2.0, scale = 0.15),
Shimmer_pct = rgamma(n, shape = 2.2, scale = 0.20),
HNR_dB = rnorm(n, mean = 18, sd = 3) + ifelse(Grupo == "Entrenamiento_técnico", 0.8, 0),
SpectralTilt_dB = rnorm(n, mean = -12, sd = 2)
)
fatiga_lat <- 0.8*datos$Jitter_pct + 0.6*datos$Shimmer_pct - 0.25*(datos$HNR_dB - 18) +
0.15*(datos$Sesion - 3) + rnorm(n, 0, 0.4)
tecnica_lat <- ifelse(datos$Grupo == "Entrenamiento_técnico", 1.0, 0) +
0.1*(datos$Intensidad_dB - 75) - 0.05*(datos$SpectralTilt_dB + 12) + rnorm(n, 0, 0.5)
datos <- datos %>%
mutate(
Fatiga_0_100 = pmin(pmax(50 + 12*fatiga_lat, 0), 100),
Tecnica_0_100 = pmin(pmax(60 + 10*tecnica_lat, 0), 100)
)
# Vista rápida (primeras 12 filas)
datos %>%
select(ID, Grupo, Sesion, HNR_dB, Jitter_pct, Shimmer_pct, Fatiga_0_100, Tecnica_0_100) %>%
slice(1:12) %>%
mutate(across(where(is.numeric), ~round(.x, 3))) %>%
kable(caption = "Tabla 1. Extracto de la base de datos (primeras 12 filas).") %>%
kable_styling(full_width = FALSE)
| ID | Grupo | Sesion | HNR_dB | Jitter_pct | Shimmer_pct | Fatiga_0_100 | Tecnica_0_100 |
|---|---|---|---|---|---|---|---|
| 1 | Entrenamiento_técnico | 1 | 12.975 | 0.138 | 1.374 | 72.966 | 62.489 |
| 2 | Entrenamiento_técnico | 3 | 23.687 | 0.305 | 0.385 | 40.165 | 56.766 |
| 3 | Entrenamiento_técnico | 3 | 17.714 | 0.351 | 1.018 | 60.123 | 66.058 |
| 4 | Entrenamiento_técnico | 6 | 16.919 | 0.072 | 0.409 | 53.176 | 66.647 |
| 5 | Control | 4 | 15.260 | 0.898 | 0.821 | 77.542 | 62.198 |
| 6 | Control | 4 | 13.004 | 0.132 | 0.478 | 70.878 | 57.831 |
| 7 | Control | 4 | 19.250 | 0.282 | 0.344 | 59.652 | 50.428 |
| 8 | Control | 3 | 12.866 | 0.309 | 0.389 | 77.797 | 63.268 |
| 9 | Entrenamiento_técnico | 1 | 19.761 | 0.526 | 0.269 | 48.579 | 82.477 |
| 10 | Control | 1 | 14.885 | 0.256 | 0.034 | 51.013 | 67.531 |
| 11 | Entrenamiento_técnico | 1 | 20.367 | 0.264 | 0.467 | 45.405 | 66.908 |
| 12 | Control | 6 | 20.235 | 0.350 | 0.984 | 57.444 | 55.026 |
desc_global <- datos %>%
select(HNR_dB, Jitter_pct, Shimmer_pct, Intensidad_dB, Fatiga_0_100, Tecnica_0_100) %>%
pivot_longer(cols = everything(), names_to = "Variable", values_to = "Valor") %>%
group_by(Variable) %>%
summarise(
n = sum(!is.na(Valor)),
Media = round(mean(Valor, na.rm = TRUE), 3),
DE = round(sd(Valor, na.rm = TRUE), 3),
Min = round(min(Valor, na.rm = TRUE), 3),
Q1 = round(quantile(Valor, 0.25, na.rm = TRUE), 3),
Mediana = round(median(Valor, na.rm = TRUE), 3),
Q3 = round(quantile(Valor, 0.75, na.rm = TRUE), 3),
Max = round(max(Valor, na.rm = TRUE), 3),
.groups = "drop"
)
desc_global %>%
kable(caption = "Tabla 2. Estadísticos descriptivos globales.") %>%
kable_styling(full_width = FALSE)
| Variable | n | Media | DE | Min | Q1 | Mediana | Q3 | Max |
|---|---|---|---|---|---|---|---|---|
| Fatiga_0_100 | 240 | 55.979 | 11.031 | 28.020 | 48.682 | 56.039 | 64.374 | 80.067 |
| HNR_dB | 240 | 18.494 | 3.067 | 10.731 | 16.263 | 18.507 | 20.682 | 25.762 |
| Intensidad_dB | 240 | 75.352 | 5.009 | 61.410 | 71.930 | 75.352 | 78.862 | 91.145 |
| Jitter_pct | 240 | 0.307 | 0.211 | 0.011 | 0.138 | 0.271 | 0.419 | 1.325 |
| Shimmer_pct | 240 | 0.439 | 0.282 | 0.034 | 0.236 | 0.385 | 0.607 | 2.123 |
| Tecnica_0_100 | 240 | 64.681 | 8.582 | 39.754 | 59.021 | 64.188 | 70.115 | 87.547 |
desc_por_grupo <- datos %>%
group_by(Grupo) %>%
summarise(
n = n(),
Fatiga_media = round(mean(Fatiga_0_100), 3),
Fatiga_DE = round(sd(Fatiga_0_100), 3),
Tecnica_media = round(mean(Tecnica_0_100), 3),
Tecnica_DE = round(sd(Tecnica_0_100), 3),
HNR_media = round(mean(HNR_dB), 3),
HNR_DE = round(sd(HNR_dB), 3),
.groups = "drop"
)
desc_por_grupo %>%
kable(caption = "Tabla 3. Descriptivos por grupo.") %>%
kable_styling(full_width = FALSE)
| Grupo | n | Fatiga_media | Fatiga_DE | Tecnica_media | Tecnica_DE | HNR_media | HNR_DE |
|---|---|---|---|---|---|---|---|
| Control | 133 | 56.952 | 10.890 | 60.028 | 6.410 | 18.296 | 3.114 |
| Entrenamiento_técnico | 107 | 54.768 | 11.136 | 70.465 | 7.344 | 18.739 | 3.005 |
En investigación correlacional, el coeficiente de correlación de Pearson (r) evalúa la relación lineal entre dos variables cuantitativas continuas.
vars <- datos %>%
select(HNR_dB, Jitter_pct, Shimmer_pct, Intensidad_dB, Tecnica_0_100, Fatiga_0_100)
cor_mat <- cor(vars)
cor_mat %>%
round(3) %>%
as.data.frame() %>%
rownames_to_column("Variable") %>%
kable(caption = "Tabla 4. Matriz de correlaciones (Pearson).") %>%
kable_styling(full_width = FALSE)
| Variable | HNR_dB | Jitter_pct | Shimmer_pct | Intensidad_dB | Tecnica_0_100 | Fatiga_0_100 |
|---|---|---|---|---|---|---|
| HNR_dB | 1.000 | 0.001 | 0.020 | 0.004 | 0.043 | -0.814 |
| Jitter_pct | 0.001 | 1.000 | -0.029 | 0.066 | 0.088 | 0.160 |
| Shimmer_pct | 0.020 | -0.029 | 1.000 | -0.038 | -0.113 | 0.155 |
| Intensidad_dB | 0.004 | 0.066 | -0.038 | 1.000 | 0.566 | -0.021 |
| Tecnica_0_100 | 0.043 | 0.088 | -0.113 | 0.566 | 1.000 | -0.069 |
| Fatiga_0_100 | -0.814 | 0.160 | 0.155 | -0.021 | -0.069 | 1.000 |
Para el IC 95% de r se utiliza la transformación de Fisher (z).
pearson_ci <- function(r, n, alpha = 0.05){
z <- atanh(r)
se <- 1/sqrt(n - 3)
zcrit <- qnorm(1 - alpha/2)
lo <- tanh(z - zcrit*se)
hi <- tanh(z + zcrit*se)
c(lo, hi)
}
pares <- tribble(
~Variable_X, ~Variable_Y,
"HNR_dB", "Fatiga_0_100",
"Jitter_pct", "Fatiga_0_100",
"Shimmer_pct", "Fatiga_0_100",
"Tecnica_0_100", "Fatiga_0_100"
)
tabla_pearson <- pares %>%
rowwise() %>%
mutate(
n = nrow(datos),
r = cor(datos[[Variable_X]], datos[[Variable_Y]]),
p = cor.test(datos[[Variable_X]], datos[[Variable_Y]], method = "pearson")$p.value,
IC = list(pearson_ci(r, n))
) %>%
ungroup() %>%
mutate(
r = round(r, 4),
p_valor = format(p, scientific = TRUE, digits = 3),
IC95 = map_chr(IC, ~paste0("[", round(.x[1],3), ", ", round(.x[2],3), "]"))
) %>%
select(Variable_X, Variable_Y, r, IC95, p_valor)
tabla_pearson %>%
kable(caption = "Tabla 5. Correlaciones de Pearson con IC 95% (Fisher-z).") %>%
kable_styling(full_width = FALSE)
| Variable_X | Variable_Y | r | IC95 | p_valor |
|---|---|---|---|---|
| HNR_dB | Fatiga_0_100 | -0.8142 | [-0.853, -0.767] | 3.96e-58 |
| Jitter_pct | Fatiga_0_100 | 0.1597 | [0.034, 0.281] | 1.32e-02 |
| Shimmer_pct | Fatiga_0_100 | 0.1555 | [0.029, 0.277] | 1.59e-02 |
| Tecnica_0_100 | Fatiga_0_100 | -0.0694 | [-0.194, 0.058] | 2.84e-01 |
# Dispersión HNR vs Fatiga con recta de regresión
ggplot(datos, aes(x = HNR_dB, y = Fatiga_0_100)) +
geom_point(alpha = 0.65) +
geom_smooth(method = "lm", se = TRUE) +
labs(
title = "Figura 1. Dispersión: HNR vs Fatiga",
x = "HNR (dB)",
y = "Fatiga (0–100)"
)
# Boxplot Fatiga por grupo
ggplot(datos, aes(x = Grupo, y = Fatiga_0_100)) +
geom_boxplot() +
labs(
title = "Figura 2. Boxplot de fatiga por grupo",
x = NULL,
y = "Fatiga (0–100)"
) +
theme(axis.text.x = element_text(angle = 10, hjust = 1))
# Histograma de fatiga
ggplot(datos, aes(x = Fatiga_0_100)) +
geom_histogram(bins = 20) +
labs(
title = "Figura 3. Histograma del puntaje de fatiga",
x = "Fatiga (0–100)",
y = "Frecuencia"
)
# Barras: promedio de técnica por grupo
datos %>%
group_by(Grupo) %>%
summarise(Tecnica_media = mean(Tecnica_0_100), .groups = "drop") %>%
ggplot(aes(x = Grupo, y = Tecnica_media)) +
geom_col() +
labs(
title = "Figura 4. Promedio de técnica por grupo",
x = NULL,
y = "Técnica promedio (0–100)"
) +
theme(axis.text.x = element_text(angle = 10, hjust = 1))
# Tendencia: fatiga promedio por sesión
datos %>%
group_by(Sesion) %>%
summarise(Fatiga_media = mean(Fatiga_0_100), .groups = "drop") %>%
ggplot(aes(x = Sesion, y = Fatiga_media)) +
geom_line() +
geom_point(size = 2) +
scale_x_continuous(breaks = 1:6) +
labs(
title = "Figura 5. Tendencia del promedio de fatiga por sesión",
x = "Sesión",
y = "Fatiga promedio (0–100)"
)
t_welch <- t.test(Fatiga_0_100 ~ Grupo, data = datos)
# d de Cohen (aprox., usando DE combinada)
x <- datos %>% filter(Grupo == "Entrenamiento_técnico") %>% pull(Fatiga_0_100)
y <- datos %>% filter(Grupo == "Control") %>% pull(Fatiga_0_100)
d_cohen <- (mean(x) - mean(y)) / sqrt((sd(x)^2 + sd(y)^2)/2)
tabla_t <- tibble(
Comparacion = "Fatiga (Entrenamiento vs Control)",
Media_entrenamiento = round(mean(x), 3),
Media_control = round(mean(y), 3),
t = round(unname(t_welch$statistic), 3),
gl = round(unname(t_welch$parameter), 1),
p_valor = format(t_welch$p.value, scientific = TRUE, digits = 3),
d_Cohen = round(d_cohen, 3)
)
tabla_t %>%
kable(caption = "Tabla 6. Prueba t (Welch) y tamaño de efecto (d de Cohen).") %>%
kable_styling(full_width = FALSE)
| Comparacion | Media_entrenamiento | Media_control | t | gl | p_valor | d_Cohen |
|---|---|---|---|---|---|---|
| Fatiga (Entrenamiento vs Control) | 54.768 | 56.952 | 1.525 | 224.9 | 1.29e-01 | -0.198 |
modelo <- lm(Fatiga_0_100 ~ HNR_dB + Jitter_pct + Shimmer_pct + Sesion + Grupo, data = datos)
resumen_modelo <- broom::tidy(modelo) %>%
mutate(
estimate = round(estimate, 4),
std.error = round(std.error, 4),
statistic = round(statistic, 3),
p.value = format(p.value, scientific = TRUE, digits = 3)
)
glance_modelo <- broom::glance(modelo) %>%
transmute(R2 = round(r.squared, 3), R2_ajustado = round(adj.r.squared, 3), AIC = round(AIC, 2))
resumen_modelo %>%
kable(caption = "Tabla 7. Coeficientes del modelo lineal (OLS).") %>%
kable_styling(full_width = FALSE)
| term | estimate | std.error | statistic | p.value |
|---|---|---|---|---|
| (Intercept) | 98.8719 | 2.0588 | 48.025 | 3.65e-123 |
| HNR_dB | -3.0054 | 0.1006 | -29.875 | 8.18e-82 |
| Jitter_pct | 8.9249 | 1.4557 | 6.131 | 3.68e-09 |
| Shimmer_pct | 7.5480 | 1.0942 | 6.898 | 4.88e-11 |
| Sesion | 1.9749 | 0.1757 | 11.239 | 1.02e-23 |
| GrupoEntrenamiento_técnico | -0.2599 | 0.6206 | -0.419 | 6.76e-01 |
glance_modelo %>%
kable(caption = "Tabla 8. Métricas globales del modelo.") %>%
kable_styling(full_width = FALSE)
| R2 | R2_ajustado | AIC |
|---|---|---|
| 0.819 | 0.815 | 1436.62 |
# Diagnósticos básicos
par(mfrow = c(2,2))
plot(modelo)
par(mfrow = c(1,1))
En el marco del estudio simulado realizado, los resultados obtenidos permiten extraer varias conclusiones relevantes sobre la relación entre variables acústicas objetivas, fatiga vocal y entrenamiento técnico.
En primer lugar, el Harmonics-to-Noise Ratio (HNR) mostró una asociación negativa fuerte y consistente con la fatiga vocal, lo que sugiere que una mayor proporción armónico-ruido indicativa de una producción vocal más estable y eficiente se relaciona con menores niveles de percepción de fatiga. Este hallazgo es coherente con la literatura previa que vincula una mejor calidad vocal con menor esfuerzo fonatorio.
Por otro lado, los parámetros de jitter y shimmer, indicadores de inestabilidad en la frecuencia y amplitud de la señal vocal, presentaron asociaciones positivas débiles pero estadísticamente significativas con la fatiga vocal. Aunque la magnitud de estas asociaciones fue moderada, los resultados sugieren que incrementos en la irregularidad vibratoria de las cuerdas vocales podrían contribuir, incluso de forma sutil, a una mayor percepción de cansancio vocal.
Asimismo, el grupo con entrenamiento técnico vocal evidenció mayores puntajes de técnica vocal y una leve reducción en los niveles de fatiga, lo que respalda la hipótesis de que la formación técnica puede actuar como un factor protector frente al esfuerzo vocal excesivo. Si bien la diferencia en fatiga fue moderada, la tendencia observada resulta clínicamente relevante.
Finalmente, el modelo multivariable confirmó que el efecto negativo del HNR sobre la fatiga vocal se mantiene incluso tras ajustar por covariables acústicas y técnicas, lo que refuerza la importancia de este parámetro como predictor independiente de la fatiga vocal en el contexto analizado.
En conjunto, estos resultados resaltan el valor de integrar medidas acústicas objetivas y variables de entrenamiento técnico en el estudio de la fatiga vocal, aportando evidencia preliminar que podría orientar futuras investigaciones con muestras empíricas y diseños longitudinales.