[R-es] Marascuilo
Carlos Ortega
co| @end|ng |rom qu@||tyexce||ence@e@
Jue Dic 4 09:22:46 CET 2025
Hola,
He preguntado a varias IAs y todas me han dado de primeras referencias
equivocadas (salvo Gemini 3), que de primeras me ha dicho que no está en R
de primeras.
Y tras indicar este problema, todas me han ofrecido implementaciones
directas...
(Emilio, a ver qué te dicen tus alumnos... :-) ).
Gracias,
Carlos Ortega
www.qualityexcellence.es
*_________ Gemini 3 _____________*
marascuilo_test <- function(counts, totals, alpha = 0.05) {
# Calcular proporciones
props <- counts / totals
n_groups <- length(props)
# Valor crítico de Chi-cuadrado
chi_crit <- sqrt(qchisq(1 - alpha, df = n_groups - 1))
# Crear combinaciones de pares
pairs <- combn(1:n_groups, 2)
results <- data.frame()
for(i in 1:ncol(pairs)) {
g1 <- pairs[1, i]
g2 <- pairs[2, i]
# Diferencia absoluta observada
diff_obs <- abs(props[g1] - props[g2])
# Rango crítico de Marascuilo
# Fórmula: sqrt(chi_sq) * sqrt( p1(1-p1)/n1 + p2(1-p2)/n2 )
se <- sqrt((props[g1] * (1 - props[g1]) / totals[g1]) +
(props[g2] * (1 - props[g2]) / totals[g2]))
critical_val <- chi_crit * se
# ¿Es significativa la diferencia?
sig <- diff_obs > critical_val
results <- rbind(results, data.frame(
Par = paste0("Grupo ", g1, " vs ", g2),
Diferencia = round(diff_obs, 4),
Valor_Critico = round(critical_val, 4),
Significativo = sig
))
}
return(results)
}
# --- EJEMPLO DE USO ---
# Supongamos:
# Grupo 1: 30 éxitos de 100
# Grupo 2: 45 éxitos de 100
# Grupo 3: 20 éxitos de 100
exitos <- c(30, 45, 20)
total_muestras <- c(100, 100, 100)
print(marascuilo_test(exitos, total_muestras))
*____________ chtatGPT 5.1 ____________*
# marascuilo_test:
# Aplica el procedimiento de Marascuilo a una tabla de contingencia
# - 'tabla': data.frame o matrix con frecuencias.
# Las columnas son los grupos a comparar.
# La PRIMERA fila se considera la categoría de "éxito".
# - 'conf.level': nivel de confianza (por defecto 0.95)
marascuilo_test <- function(tabla, conf.level = 0.95) {
tabla <- as.matrix(tabla)
if (nrow(tabla) < 2) {
stop("La tabla debe tener al menos 2 filas (éxito / no éxito, por
ejemplo).")
}
k <- ncol(tabla)
grupos <- colnames(tabla)
if (is.null(grupos)) grupos <- paste0("G", seq_len(k))
# Totales por grupo y proporciones de la primera fila (p_i)
n <- colSums(tabla)
p <- tabla[1, ] / n
# Constante chi-cuadrado
df <- (nrow(tabla) - 1) * (ncol(tabla) - 1)
chi_const <- sqrt(qchisq(conf.level, df = df))
# Todas las combinaciones de pares
comb <- t(combn(seq_len(k), 2))
res <- data.frame(
grupo1 = character(0),
grupo2 = character(0),
p1 = numeric(0),
p2 = numeric(0),
diff = numeric(0),
crit_range = numeric(0),
significativo = logical(0),
stringsAsFactors = FALSE
)
for (r in seq_len(nrow(comb))) {
i <- comb[r, 1]
j <- comb[r, 2]
diff_ij <- abs(p[i] - p[j])
crit_ij <- chi_const * sqrt(
p[i] * (1 - p[i]) / n[i] +
p[j] * (1 - p[j]) / n[j]
)
res <- rbind(
res,
data.frame(
grupo1 = grupos[i],
grupo2 = grupos[j],
p1 = p[i],
p2 = p[j],
diff = diff_ij,
crit_range = crit_ij,
significativo = diff_ij > crit_ij,
stringsAsFactors = FALSE
)
)
}
# Ordenar por (diff - crit_range), de más “evidente” a menos
res$exceso_diff <- res$diff - res$crit_range
res[order(-res$exceso_diff), ]
}
#Ejemplo__________
tabla <- matrix(c(
30, 50, 20, # Y (éxito)
70, 50, 80 # N (no éxito)
), nrow = 2, byrow = TRUE)
rownames(tabla) <- c("Y", "N")
colnames(tabla) <- c("A", "B", "C")
tabla
# Primero el chi-cuadrado global (opcional)
chisq.test(tabla, correct = FALSE)
# Luego Marascuilo
marascuilo_test(tabla, conf.level = 0.95)
*______________ Sonnet 4.5 ______________*
marascuilo_test <- function(x, n, alpha = 0.05) {
# x: vector de éxitos
# n: vector de tamaños de muestra
k <- length(x)
p <- x / n
nombres <- names(x)
if(is.null(nombres)) nombres <- paste0("Grupo", 1:k)
# Valor crítico de chi-cuadrado
chi_crit <- qchisq(1 - alpha, k - 1)
# Crear matriz de comparaciones
comparaciones <- data.frame()
for(i in 1:(k-1)) {
for(j in (i+1):k) {
dif_abs <- abs(p[i] - p[j])
valor_critico <- sqrt(chi_crit * (p[i]*(1-p[i])/n[i] +
p[j]*(1-p[j])/n[j]))
significativo <- dif_abs > valor_critico
comparaciones <- rbind(comparaciones,
data.frame(
Comparacion = paste(nombres[i], "vs",
nombres[j]),
Diferencia = dif_abs,
Valor_Critico = valor_critico,
Significativo = ifelse(significativo, "Sí",
"No")
))
}
}
return(list(
proporciones = setNames(p, nombres),
comparaciones = comparaciones,
alpha = alpha
))
}
# Ejemplo de uso
exitos <- c(45, 38, 51)
totales <- c(100, 100, 100)
names(exitos) <- c("Tratamiento A", "Tratamiento B", "Tratamiento C")
resultado <- marascuilo_test(exitos, totales, alpha = 0.05)
print(resultado$proporciones)
print(resultado$comparaciones)
*__________________ Grok 4.1 ________________*
marascuilo_test <- function(tabla, alpha = 0.05, p.adjust = "fdr") {
if (ncol(tabla) != 2) stop("La tabla debe ser r x 2 (grupos x
éxito/fracaso)")
n <- rowSums(tabla) # Totales por grupo
p <- tabla[, 1] / n # Proporciones
nombres <- rownames(tabla)
k <- length(p)
# Todos los pares
combinaciones <- combn(k, 2)
num_pares <- ncol(combinaciones)
# Diferencias absolutas
diff <- abs(p[combinaciones[1, ]] - p[combinaciones[2, ]])
# Valores críticos de Marascuilo
chi_crit <- qchisq(1 - alpha, df = k - 1)
crit <- sqrt(chi_crit) * sqrt(
(p[combinaciones[1, ]] * (1 - p[combinaciones[1, ]])) /
n[combinaciones[1, ]] +
(p[combinaciones[2, ]] * (1 - p[combinaciones[2, ]])) /
n[combinaciones[2, ]]
)
# p-valores aproximados (usando aproximación normal para referencia)
se <- sqrt(
(p[combinaciones[1, ]] * (1 - p[combinaciones[1, ]])) /
n[combinaciones[1, ]] +
(p[combinaciones[2, ]] * (1 - p[combinaciones[2, ]])) /
n[combinaciones[2, ]]
)
z <- diff / se
p.valor <- 2 * (1 - pnorm(z))
# Ajuste de p-valores
p.adj <- p.adjust(p.valor, method = p.adjust)
# Data frame de resultados
resultados <- data.frame(
Grupo1 = nombres[combinaciones[1, ]],
Grupo2 = nombres[combinaciones[2, ]],
p1 = p[combinaciones[1, ]],
p2 = p[combinaciones[2, ]],
Diferencia = diff,
Valor_Critico = crit,
p.valor = p.valor,
p.ajustado = p.adj,
Significativo = ifelse(diff > crit, "*** (basado en crit)",
ifelse(p.adj < 0.05, "* (basado en p.adj)", " "))
)
print(resultados)
cat("\nNotas:\n- *** si diferencia > valor crítico (método Marascuilo
exacto)\n- * si p.ajustado < 0.05\n")
cat("Método de ajuste p: ", p.adjust, "\n")
cat("Asume muestras grandes (n*p y n*(1-p) > 5 por celda).\n")
}
# Ejemplo de uso
marascuilo_test(datos, alpha = 0.05, p.adjust = "fdr")
___________________________________________________
El jue, 4 dic 2025 a las 8:21, Emilio L. Cano (<emilopezcano using gmail.com>)
escribió:
> Hola,
>
> Pues no he encontrado nada, es una buena oportunidad para desarrollar un
> paquete para este test y su análisis. Acabo de proponerlo como proyecto de
> TFG a mis estudiantes :)
>
> Saludos,
> Emilio
>
>
>
>
> > El 4 dic 2025, a las 6:20, Amable Moreno <morenoamable6 using gmail.com>
> escribió:
> >
> > Estimados colegas
> > Quisiera saber si hay alguna librería para aplicar el test de
> Marascuilo
> > Desde ya muchas gracias
> >
> > [[alternative HTML version deleted]]
> >
> > _______________________________________________
> > R-help-es mailing list
> > R-help-es using r-project.org
> > https://stat.ethz.ch/mailman/listinfo/r-help-es
>
> _______________________________________________
> R-help-es mailing list
> R-help-es using r-project.org
> https://stat.ethz.ch/mailman/listinfo/r-help-es
>
--
Saludos,
Carlos Ortega
www.qualityexcellence.es
[[alternative HTML version deleted]]
Más información sobre la lista de distribución R-help-es