requeridos <- c("readxl", "dplyr", "tidyr", "ggplot2", "knitr", "MASS")
faltantes <- requeridos[!vapply(requeridos, requireNamespace, logical(1), quietly = TRUE)]
if (length(faltantes)) {
stop("Faltan paquetes: ", paste(faltantes, collapse = ", "),
"\nInstálalos con: install.packages(c('", paste(faltantes, collapse = "','"), "'))")
}
library(readxl); library(dplyr); library(tidyr); library(ggplot2); library(knitr)
mor_osc <- "#804bb2"; mor_cla <- "#daadfc"; mor_med <- "#b07fd6"; gris <- "#4A4A4A"
theme_set(
theme_minimal(base_size = 11) +
theme(panel.grid.minor = element_blank(),
strip.text = element_text(face = "bold", colour = gris),
plot.title = element_text(face = "bold", colour = gris))
)
tabla <- function(x, ...) knitr::kable(x, digits = 4, format.args = list(big.mark = ","), ...)
Qué se contrasta y por
qué
Este cuaderno es la continuación del diagnóstico de normalidad.
No repite el diagnóstico: parte de sus conclusiones y
las convierte en decisiones de método.
Los NUM_DOC coinciden fila a fila |
Todo contraste es pareado |
| \(\rho\) entre olas de 0,44 a
0,75 |
Tratarlas como independientes desperdiciaría 44–75 % de
precisión |
| Diferencias simétricas (asimetría ≈ 0), \(n\) = 5.333 |
La \(t\) pareada
es válida por el TLC |
| Simetría verificada de las diferencias |
Habilita el Wilcoxon de rangos con signo como
robustez |
| \(\lambda\) de Yeo-Johnson ≈ 1 |
No transformar |
E_CONTABILIDAD: 30 valores, 28,7 % de ceros |
Requiere prueba de signos, no Wilcoxon |
| 8–9 % de atípicos robustos |
Obliga a un análisis de sensibilidad |
| Colas pesadas multivariadas |
Evitar \(T^2\) de Hotelling;
contrastes univariados con ajuste por multiplicidad |
Estrategia de contraste. Cada dimensión se somete a
tres procedimientos con supuestos distintos —\(t\) pareada (media), Wilcoxon o signos
(mediana) y bootstrap (sin supuesto distribucional)—. Si los tres
coinciden, la conclusión no depende del supuesto; si difieren, la
discrepancia es informativa y se reporta.
Advertencia que atraviesa todo el documento. Las dos
olas no fueron medidas con el mismo instrumento: 2025
es DIME 1.0 y 2026 es DIME 1.0 reconstruido desde el DIME 2.0 vía la
correlativa. Todo lo que sigue mide el cambio observado en el puntaje,
que mezcla cambio real de las empresas con cualquier efecto del
recálculo. La §8 documenta por qué esto es particularmente serio en
B_DESARROLLO_PROD y F_INNOVACION.
Lectura y
preparación
dims <- c("B_DESARROLLO_PROD", "C_LIDERAZGO", "D_MERCADO_VENTAS",
"E_CONTABILIDAD", "F_INNOVACION", "General")
dims5 <- setdiff(dims, "General")
nombres_bloque <- c("GlobalID", "NUM_DOC", "LOCALIDAD_F", "RAZON_SOCIAL", dims, "Etapa")
etapas <- c("Ideación", "Nacimiento", "Crecimiento", "Aceleración", "Madurez")
crudo <- read_excel(params$archivo, sheet = params$hoja, skip = 2, col_names = FALSE)
stopifnot(ncol(crudo) == 2 * length(nombres_bloque))
names(crudo) <- c(paste0(nombres_bloque, "_25"), paste0(nombres_bloque, "_26"))
panel <- crudo %>%
mutate(across(all_of(c(paste0(dims, "_25"), paste0(dims, "_26"))), as.numeric),
Etapa_25 = factor(Etapa_25, levels = etapas),
Etapa_26 = factor(Etapa_26, levels = etapas))
X25 <- as.matrix(panel[paste0(dims, "_25")]); colnames(X25) <- dims
X26 <- as.matrix(panel[paste0(dims, "_26")]); colnames(X26) <- dims
XD <- X26 - X25
d25 <- as.data.frame(X25); d26 <- as.data.frame(X26); dif <- as.data.frame(XD)
cat("Empresas en el panel:", nrow(panel), "\n")
## Empresas en el panel: 5333
Marcado de casos
problemáticos
Ningún caso se elimina de la base principal. Se marcan, y en §4 se
repite todo el análisis sin ellos para ver si las conclusiones dependen
de un puñado de empresas.
corte <- qchisq(0.975, df = length(dims5))
rob <- MASS::cov.rob(XD[, dims5], method = "mcd", nsamp = 500, seed = params$semilla)
d_rob <- mahalanobis(XD[, dims5], rob$center, rob$cov)
marcas <- panel %>%
transmute(
NUM_DOC = NUM_DOC_25, Empresa = RAZON_SOCIAL_25,
fuera_escala = apply(X25 > 5 | X25 < 0 | X26 > 5 | X26 < 0, 1, any),
duplicado = duplicated(NUM_DOC_25) | duplicated(NUM_DOC_25, fromLast = TRUE),
atipico = d_rob > corte
) %>%
mutate(limpio = !(fuera_escala | duplicado | atipico))
tibble::tibble(
Criterio = c("Fuera de la escala 0–5", "Documento duplicado",
"Atípico multivariado (MCD)", "Excluidos en total (base depurada)",
"Base depurada"),
Casos = c(sum(marcas$fuera_escala), sum(marcas$duplicado), sum(marcas$atipico),
sum(!marcas$limpio), sum(marcas$limpio)),
`% del panel` = round(100 * c(mean(marcas$fuera_escala), mean(marcas$duplicado),
mean(marcas$atipico), mean(!marcas$limpio),
mean(marcas$limpio)), 1)
) %>% tabla(caption = "Casos marcados para el análisis de sensibilidad")
Casos marcados para el análisis de sensibilidad
| Fuera de la escala 0–5 |
3 |
0.1 |
| Documento duplicado |
2 |
0.0 |
| Atípico multivariado (MCD) |
496 |
9.3 |
| Excluidos en total (base depurada) |
496 |
9.3 |
| Base depurada |
4,837 |
90.7 |
El cambio en el centro
de la distribución
Los tres
contrastes
## t pareada -----------------------------------------------------------------
prueba_t <- function(d) {
tt <- t.test(d)
c(dif = unname(tt$estimate), ic_lo = tt$conf.int[1], ic_hi = tt$conf.int[2],
t = unname(tt$statistic), gl = unname(tt$parameter), p = tt$p.value)
}
## Wilcoxon de rangos con signo (mediana de Hodges-Lehmann) -------------------
prueba_w <- function(d) {
ww <- suppressWarnings(wilcox.test(d, conf.int = TRUE, exact = FALSE, correct = TRUE))
c(hl = unname(ww$estimate), hl_lo = ww$conf.int[1], hl_hi = ww$conf.int[2], p = ww$p.value)
}
## Prueba de signos (ignora la magnitud; correcta con empates masivos) --------
prueba_signos <- function(d) {
nz <- d[d != 0 & is.finite(d)]
bt <- binom.test(sum(nz > 0), length(nz), 0.5)
c(n_efectivo = length(nz), prop_sube = unname(bt$estimate),
ic_lo = bt$conf.int[1], ic_hi = bt$conf.int[2], p = bt$p.value)
}
## Bootstrap percentil de la media de las diferencias ------------------------
boot_media <- function(d, B = params$B_boot, semilla = params$semilla) {
d <- d[is.finite(d)]; n <- length(d)
set.seed(semilla)
m <- vapply(seq_len(B), function(i) mean(d[sample.int(n, n, replace = TRUE)]), numeric(1))
c(media = mean(d), boot_lo = unname(quantile(m, 0.025)),
boot_hi = unname(quantile(m, 0.975)), ee_boot = sd(m))
}
## Tamaños de efecto ---------------------------------------------------------
efectos <- function(d, x25, x26) {
c(dz = mean(d) / sd(d), # d de Cohen para datos pareados
d_av = mean(d) / ((sd(x25) + sd(x26)) / 2), # estandarizado por las olas
pct_escala = 100 * mean(d) / 5) # % de la escala 0–5
}
Por qué tres. La \(t\) contrasta la media y
supone normalidad (que aquí sostiene el TLC). Wilcoxon contrasta la
pseudomediana y supone simetría (verificada en el
diagnóstico). El bootstrap no supone nada sobre la forma: remuestrea las
empresas y reconstruye la distribución del estimador. La prueba de
signos solo usa la dirección del cambio, ignorando la
magnitud: es la única válida cuando la variable es discreta con muchos
empates.
contrastes <- bind_rows(lapply(dims, function(v) {
d <- dif[[v]]
tt <- prueba_t(d); ww <- prueba_w(d); ss <- prueba_signos(d)
bb <- boot_media(d); ef <- efectos(d, d25[[v]], d26[[v]])
tibble::tibble(
Dimensión = v,
`Cambio medio` = tt["dif"], `IC 95% inf` = tt["ic_lo"], `IC 95% sup` = tt["ic_hi"],
`t` = tt["t"], `p (t)` = tt["p"],
`Mediana HL` = ww["hl"], `p (Wilcoxon)` = ww["p"],
`% que sube` = 100 * ss["prop_sube"], `p (signos)` = ss["p"],
`IC boot inf` = bb["boot_lo"], `IC boot sup` = bb["boot_hi"],
dz = ef["dz"], `d promedio` = ef["d_av"], `% de la escala` = ef["pct_escala"]
)
})) %>%
mutate(`p ajustado (Holm)` = p.adjust(`p (t)`, method = "holm"), .after = `p (t)`)
contrastes %>%
dplyr::select(Dimensión, `Cambio medio`, `IC 95% inf`, `IC 95% sup`, `t`,
`p (t)`, `p ajustado (Holm)`) %>%
tabla(caption = "Contraste principal: t pareada sobre el cambio 2026 − 2025")
Contraste principal: t pareada sobre el cambio 2026 −
2025
| B_DESARROLLO_PROD |
0.4329 |
0.4120 |
0.4539 |
40.5680 |
0.0000 |
0.0000 |
| C_LIDERAZGO |
0.0470 |
0.0315 |
0.0625 |
5.9388 |
0.0000 |
0.0000 |
| D_MERCADO_VENTAS |
-0.0058 |
-0.0187 |
0.0072 |
-0.8689 |
0.3850 |
0.3850 |
| E_CONTABILIDAD |
-0.0145 |
-0.0352 |
0.0061 |
-1.3786 |
0.1681 |
0.3362 |
| F_INNOVACION |
0.4956 |
0.4681 |
0.5231 |
35.3500 |
0.0000 |
0.0000 |
| General |
0.1910 |
0.1794 |
0.2027 |
32.2091 |
0.0000 |
0.0000 |
contrastes %>%
dplyr::select(Dimensión, `Cambio medio`, `IC boot inf`, `IC boot sup`,
`Mediana HL`, `p (Wilcoxon)`, `% que sube`, `p (signos)`) %>%
tabla(caption = "Contrastes de robustez: bootstrap, Wilcoxon y prueba de signos")
Contrastes de robustez: bootstrap, Wilcoxon y prueba de
signos
| B_DESARROLLO_PROD |
0.4329 |
0.4123 |
0.4533 |
0.5002 |
0.0000 |
74.15 |
0.0000 |
| C_LIDERAZGO |
0.0470 |
0.0317 |
0.0621 |
0.0493 |
0.0000 |
54.43 |
0.0000 |
| D_MERCADO_VENTAS |
-0.0058 |
-0.0196 |
0.0073 |
-0.0065 |
0.4128 |
48.01 |
0.0039 |
| E_CONTABILIDAD |
-0.0145 |
-0.0345 |
0.0063 |
0.0001 |
0.8749 |
51.37 |
0.0947 |
| F_INNOVACION |
0.4956 |
0.4673 |
0.5229 |
0.5100 |
0.0000 |
68.66 |
0.0000 |
| General |
0.1910 |
0.1794 |
0.2024 |
0.1922 |
0.0000 |
68.57 |
0.0000 |
Convergencia de los
métodos
convergencia <- contrastes %>%
transmute(
Dimensión,
`t pareada` = ifelse(`p ajustado (Holm)` < 0.05,
ifelse(`Cambio medio` > 0, "Sube", "Baja"), "Sin cambio"),
`Wilcoxon` = ifelse(`p (Wilcoxon)` < 0.05,
ifelse(`Mediana HL` > 0, "Sube", "Baja"), "Sin cambio"),
`Signos` = ifelse(`p (signos)` < 0.05,
ifelse(`% que sube` > 50, "Sube", "Baja"), "Sin cambio"),
`Bootstrap` = ifelse(`IC boot inf` > 0, "Sube",
ifelse(`IC boot sup` < 0, "Baja", "Sin cambio")),
Coinciden = ifelse(`t pareada` == Wilcoxon & Wilcoxon == Signos & Signos == Bootstrap,
"Sí", "No")
)
tabla(convergencia, caption = "¿Coinciden los cuatro procedimientos?")
¿Coinciden los cuatro procedimientos?
| B_DESARROLLO_PROD |
Sube |
Sube |
Sube |
Sube |
Sí |
| C_LIDERAZGO |
Sube |
Sube |
Sube |
Sube |
Sí |
| D_MERCADO_VENTAS |
Sin cambio |
Sin cambio |
Baja |
Sin cambio |
No |
| E_CONTABILIDAD |
Sin cambio |
Sin cambio |
Sin cambio |
Sin cambio |
Sí |
| F_INNOVACION |
Sube |
Sube |
Sube |
Sube |
Sí |
| General |
Sube |
Sube |
Sube |
Sube |
Sí |
Cuando las cuatro columnas coinciden, la conclusión es sólida y no
depende del supuesto distribucional. Una discrepancia entre la \(t\) (media) y los signos (mediana) indica
que el cambio típico y el cambio promedio apuntan en direcciones
distintas: la distribución del cambio es asimétrica en su parte central
aunque su asimetría global sea baja. Ese caso se comenta en §7.
Magnitud del
cambio
contrastes %>%
dplyr::select(Dimensión, `Cambio medio`, dz, `d promedio`, `% de la escala`) %>%
mutate(Magnitud = cut(abs(dz), breaks = c(-Inf, 0.2, 0.5, 0.8, Inf),
labels = c("Trivial", "Pequeño", "Mediano", "Grande"))) %>%
tabla(caption = "Tamaño de efecto (convención de Cohen: 0.2 pequeño, 0.5 mediano, 0.8 grande)")
Tamaño de efecto (convención de Cohen: 0.2 pequeño, 0.5
mediano, 0.8 grande)
| B_DESARROLLO_PROD |
0.4329 |
0.5555 |
0.5261 |
8.6588 |
Mediano |
| C_LIDERAZGO |
0.0470 |
0.0813 |
0.0671 |
0.9396 |
Trivial |
| D_MERCADO_VENTAS |
-0.0058 |
-0.0119 |
-0.0095 |
-0.1151 |
Trivial |
| E_CONTABILIDAD |
-0.0145 |
-0.0189 |
-0.0168 |
-0.2906 |
Trivial |
| F_INNOVACION |
0.4956 |
0.4841 |
0.5122 |
9.9119 |
Pequeño |
| General |
0.1910 |
0.4411 |
0.3127 |
3.8209 |
Pequeño |
Con 5.333 empresas, la significancia estadística no distingue
nada: un cambio de 0,05 puntos en una escala de 0 a 5 sale
significativo. El tamaño de efecto es el que decide si el cambio es
relevante para política pública. dz estandariza por la
desviación del cambio; d promedio lo hace por la desviación
de los puntajes, que es la referencia más comparable con otros
estudios.
contrastes %>%
mutate(Dimensión = factor(Dimensión, levels = rev(dims)),
signo = ifelse(`IC 95% inf` > 0, "Aumento", ifelse(`IC 95% sup` < 0, "Descenso", "Sin cambio"))) %>%
ggplot(aes(`Cambio medio`, Dimensión, colour = signo)) +
geom_vline(xintercept = 0, colour = gris, linewidth = 0.5) +
geom_errorbar(aes(xmin = `IC 95% inf`, xmax = `IC 95% sup`),
orientation = "y", width = 0.18, linewidth = 0.8) +
geom_point(size = 2.6) +
scale_colour_manual(values = c(Aumento = mor_osc, Descenso = "#c0392b", `Sin cambio` = "grey55"),
name = NULL) +
labs(title = "Cambio medio por dimensión, con intervalo de confianza del 95 %",
subtitle = "Puntos a la derecha de la línea = el puntaje sube entre 2025 y 2026",
x = "Diferencia media (2026 − 2025)", y = NULL)

Análisis de
sensibilidad
¿Las conclusiones dependen de los 496 casos marcados en §2.1? Se
repite el contraste principal sobre la base depurada y se comparan los
dos resultados.
dif_limpio <- dif[marcas$limpio, , drop = FALSE]
sens <- bind_rows(lapply(dims, function(v) {
a <- prueba_t(dif[[v]]); b <- prueba_t(dif_limpio[[v]])
tibble::tibble(
Dimensión = v,
`Cambio (todos)` = a["dif"], `p (todos)` = a["p"],
`Cambio (depurada)` = b["dif"], `p (depurada)` = b["p"],
`Diferencia absoluta` = abs(b["dif"] - a["dif"]),
`Misma conclusión` = ifelse((a["p"] < 0.05) == (b["p"] < 0.05) &
sign(a["dif"]) == sign(b["dif"]), "Sí", "No")
)
}))
tabla(sens, caption = "Contraste principal con y sin los casos marcados")
Contraste principal con y sin los casos marcados
| B_DESARROLLO_PROD |
0.4329 |
0.0000 |
0.4410 |
0.0000 |
0.0081 |
Sí |
| C_LIDERAZGO |
0.0470 |
0.0000 |
0.0556 |
0.0000 |
0.0086 |
Sí |
| D_MERCADO_VENTAS |
-0.0058 |
0.3850 |
-0.0009 |
0.8831 |
0.0049 |
Sí |
| E_CONTABILIDAD |
-0.0145 |
0.1681 |
-0.0012 |
0.8998 |
0.0134 |
Sí |
| F_INNOVACION |
0.4956 |
0.0000 |
0.5022 |
0.0000 |
0.0066 |
Sí |
| General |
0.1910 |
0.0000 |
0.1994 |
0.0000 |
0.0083 |
Sí |
Si la columna Misma conclusión dice “Sí” en todas las filas,
el análisis es robusto a los atípicos y el resultado no descansa en un
grupo pequeño de empresas. Si alguna dice “No”, esa dimensión debe
reportarse con la advertencia explícita de que su resultado depende de
casos extremos.
Transiciones entre
etapas de madurez
El puntaje continuo responde “¿cuánto cambió?”. La etapa responde una
pregunta distinta y más directa para política: ¿cuántas empresas
cambiaron de categoría, y en qué dirección?
trans_tab <- table(Etapa_25 = panel$Etapa_25, Etapa_26 = panel$Etapa_26)
tabla(as.data.frame.matrix(trans_tab),
caption = "Matriz de transiciones: etapa en 2025 (filas) × etapa en 2026 (columnas)")
Matriz de transiciones: etapa en 2025 (filas) × etapa en 2026
(columnas)
| Ideación |
13 |
76 |
7 |
0 |
0 |
| Nacimiento |
22 |
1,198 |
895 |
22 |
0 |
| Crecimiento |
0 |
290 |
1,820 |
451 |
0 |
| Aceleración |
0 |
1 |
173 |
341 |
15 |
| Madurez |
0 |
0 |
2 |
7 |
0 |
T <- as.matrix(trans_tab); n_t <- sum(T)
mov <- tibble::tibble(
Situación = c("Permanece en la misma etapa", "Avanza de etapa", "Retrocede de etapa"),
Empresas = c(sum(diag(T)), sum(T[upper.tri(T)]), sum(T[lower.tri(T)])),
`%` = round(100 * c(sum(diag(T)), sum(T[upper.tri(T)]), sum(T[lower.tri(T)])) / n_t, 1)
)
tabla(mov, caption = "Movilidad entre etapas")
Movilidad entre etapas
| Permanece en la misma etapa |
3,372 |
63.2 |
| Avanza de etapa |
1,466 |
27.5 |
| Retrocede de etapa |
495 |
9.3 |
as.data.frame(trans_tab) %>%
rename(n = Freq) %>%
group_by(Etapa_25) %>% mutate(pct = 100 * n / sum(n)) %>% ungroup() %>%
ggplot(aes(Etapa_26, Etapa_25, fill = pct)) +
geom_tile(colour = "white", linewidth = 1) +
geom_text(aes(label = ifelse(n > 0, sprintf("%d\n%.0f%%", n, pct), "")),
size = 2.9, colour = "grey15") +
scale_fill_gradient(low = "white", high = mor_osc, name = "% de la fila") +
labs(title = "Transiciones entre etapas de madurez",
subtitle = "Porcentajes calculados sobre la etapa de origen (fila)",
x = "Etapa en 2026", y = "Etapa en 2025")

Prueba de simetría
(Bowker)
La matriz de transiciones es simétrica si el flujo de la etapa \(i\) a la \(j\) iguala al de \(j\) a \(i\); en ese caso hay movimiento pero
no hay cambio neto en la distribución de etapas. La
prueba de Bowker —la generalización de McNemar a \(k\) categorías— contrasta esa
hipótesis.
bowker <- function(T) {
k <- nrow(T); est <- 0; gl <- 0
for (i in 1:(k - 1)) for (j in (i + 1):k) {
s <- T[i, j] + T[j, i]
if (s > 0) { est <- est + (T[i, j] - T[j, i])^2 / s; gl <- gl + 1 }
}
list(estadistico = est, gl = gl, p = pchisq(est, gl, lower.tail = FALSE))
}
bw <- bowker(T)
tibble::tibble(Prueba = "Bowker (simetría de la matriz de transiciones)",
`χ²` = bw$estadistico, `gl` = bw$gl, p = bw$p) %>%
tabla(caption = "Contraste de simetría; los pares vacíos se excluyen y los grados de libertad se ajustan")
Contraste de simetría; los pares vacíos se excluyen y los
grados de libertad se ajustan
| Bowker (simetría de la matriz de transiciones) |
493.6 |
7 |
0 |
marg <- bind_rows(
as.data.frame(prop.table(table(panel$Etapa_25))) %>% mutate(Ola = "2025"),
as.data.frame(prop.table(table(panel$Etapa_26))) %>% mutate(Ola = "2026")
) %>% rename(Etapa = Var1, Proporción = Freq)
marg %>% pivot_wider(names_from = Ola, values_from = Proporción) %>%
mutate(across(c(`2025`, `2026`), ~ round(100 * .x, 1)),
`Cambio (pp)` = `2026` - `2025`) %>%
tabla(caption = "Distribución de etapas por ola (%) y cambio en puntos porcentuales")
Distribución de etapas por ola (%) y cambio en puntos
porcentuales
| Ideación |
1.8 |
0.7 |
-1.1 |
| Nacimiento |
40.1 |
29.3 |
-10.8 |
| Crecimiento |
48.0 |
54.3 |
6.3 |
| Aceleración |
9.9 |
15.4 |
5.5 |
| Madurez |
0.2 |
0.3 |
0.1 |
ggplot(marg, aes(Etapa, 100 * Proporción, fill = Ola)) +
geom_col(position = position_dodge(0.7), width = 0.65) +
scale_fill_manual(values = c("2025" = mor_cla, "2026" = mor_osc)) +
labs(title = "Composición del panel por etapa de madurez", x = NULL, y = "% de empresas")

Síntesis
veredicto <- contrastes %>%
left_join(convergencia %>% dplyr::select(Dimensión, Coinciden), by = "Dimensión") %>%
transmute(
Dimensión,
`Cambio medio`, `IC 95% inf`, `IC 95% sup`, dz,
`Significativo (Holm)` = ifelse(`p ajustado (Holm)` < 0.05, "Sí", "No"),
`Métodos coinciden` = Coinciden,
Veredicto = case_when(
`p ajustado (Holm)` >= 0.05 ~ "Sin evidencia de cambio",
abs(dz) < 0.2 ~ "Significativo pero trivial",
abs(dz) < 0.5 ~ "Cambio pequeño pero real",
TRUE ~ "Cambio sustantivo"
)
)
tabla(veredicto, caption = "Veredicto por dimensión")
Veredicto por dimensión
| B_DESARROLLO_PROD |
0.4329 |
0.4120 |
0.4539 |
0.5555 |
Sí |
Sí |
Cambio sustantivo |
| C_LIDERAZGO |
0.0470 |
0.0315 |
0.0625 |
0.0813 |
Sí |
Sí |
Significativo pero trivial |
| D_MERCADO_VENTAS |
-0.0058 |
-0.0187 |
0.0072 |
-0.0119 |
No |
No |
Sin evidencia de cambio |
| E_CONTABILIDAD |
-0.0145 |
-0.0352 |
0.0061 |
-0.0189 |
No |
Sí |
Sin evidencia de cambio |
| F_INNOVACION |
0.4956 |
0.4681 |
0.5231 |
0.4841 |
Sí |
Sí |
Cambio pequeño pero real |
| General |
0.1910 |
0.1794 |
0.2027 |
0.4411 |
Sí |
Sí |
Cambio pequeño pero real |
veredicto %>%
mutate(Dimensión = factor(Dimensión, levels = rev(dims))) %>%
ggplot(aes(abs(dz), Dimensión, fill = Veredicto)) +
geom_col(width = 0.6) +
geom_vline(xintercept = c(0.2, 0.5, 0.8), linetype = "dashed", colour = gris, linewidth = 0.35) +
scale_fill_manual(values = c("Sin evidencia de cambio" = "grey70",
"Significativo pero trivial" = mor_cla,
"Cambio pequeño pero real" = mor_med,
"Cambio sustantivo" = mor_osc)) +
labs(title = "Tamaño de efecto por dimensión",
subtitle = "Líneas punteadas: umbrales de Cohen (0.2 / 0.5 / 0.8)",
x = "|dz|", y = NULL) +
theme(legend.position = "bottom")

Cómo leer estos
resultados
- Distinguir significancia de relevancia. Con \(n\) = 5.333, la columna de valores \(p\) casi no discrimina; la columna
dz sí. Una dimensión marcada “significativo pero trivial”
no debe reportarse como una mejora del ecosistema.
- Mirar la convergencia. Las dimensiones donde los
cuatro procedimientos coinciden tienen una conclusión que no depende de
supuestos. Donde no coinciden, revisar si la discrepancia viene de la
media frente a la mediana (asimetría del cambio) o de los empates
(
E_CONTABILIDAD).
- Leer la función de desplazamiento antes de
concluir. Si el desplazamiento es uniforme, el enunciado
correcto es “toda la distribución se movió”; si es desigual, hay que
decir en qué tramo de la distribución ocurrió el cambio, porque eso
identifica a qué empresas llegó.
- Las transiciones son la cifra comunicable. “X % de
las empresas avanzó de etapa” se entiende fuera del ámbito técnico mucho
mejor que una diferencia de medias, y la prueba de Bowker dice si ese
movimiento tiene dirección neta o es solo ruido en ambos sentidos.
Dos límites que este
análisis no puede resolver
El instrumento cambió
entre las dos olas
aporte <- tibble::tibble(
Dimensión = dims5,
`Cambio medio` = vapply(dims5, function(v) mean(dif[[v]], na.rm = TRUE), numeric(1)),
`Aporte a General` = 0.2 * `Cambio medio`,
`% del cambio en General` = round(100 * `Aporte a General` / mean(dif$General, na.rm = TRUE), 1)
)
tabla(aporte, caption = "Descomposición del cambio en el puntaje General")
Descomposición del cambio en el puntaje General
| B_DESARROLLO_PROD |
0.4329 |
0.0866 |
45.3 |
| C_LIDERAZGO |
0.0470 |
0.0094 |
4.9 |
| D_MERCADO_VENTAS |
-0.0058 |
-0.0012 |
-0.6 |
| E_CONTABILIDAD |
-0.0145 |
-0.0029 |
-1.5 |
| F_INNOVACION |
0.4956 |
0.0991 |
51.9 |
El cambio agregado no está repartido: se concentra en
B_DESARROLLO_PROD y F_INNOVACION, que son
justamente las dimensiones donde la reconstrucción del puntaje vía la
correlativa DIME 2.0 → 1.0 pudo alterar la escala —el máximo de
B pasa de 6,501, fuera de rango, en 2025 a exactamente
5,000 en 2026—. Mientras no se verifique con quien construyó la
correlativa que el mapeo de preguntas de esas dos dimensiones es
equivalente entre versiones, el aumento del puntaje General no
puede atribuirse a las empresas. Las dimensiones
C, D y E, que la correlativa
parece no afectar, son la parte más defendible del resultado.