# Instalo paquetes
paquetes <- c("randomizr", "gtsummary", "dplyr", "ggplot2",
"knitr", "flextable", "forcats", "patchwork")
nuevos <- paquetes[!(paquetes %in% installed.packages()[, "Package"])]
if (length(nuevos)) install.packages(nuevos, repos = "https://cran.r-project.org")
knitr::opts_chunk$set(message = FALSE, warning = FALSE)
# Cargar librerias
library(randomizr) # Funciones de aleatorizacion
## Warning: package 'randomizr' was built under R version 4.5.3
library(gtsummary) # Tabla 1 profesional con pruebas estadísticas
library(dplyr) # Manipulacion de datos
##
## Adjuntando el paquete: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(ggplot2) # Visualizaciones
library(knitr) # Reportes dinamicos
library(flextable) # Tablas para exportacion a Word
##
## Adjuntando el paquete: 'flextable'
## The following object is masked from 'package:gtsummary':
##
## continuous_summary
library(forcats) # Manejo de factores
library(patchwork) # Combinar graficos en un solo panel
Nota: Este documento es elaborado en R Markdown, lo cual permite integrar en un solo archivo reproducible el código fuente, las salidas estadísticas, las visualizaciones y la interpretación narrativa, cumpliendo de manera unificada los requerimientos de presentación del script, la Tabla 1 y la redacción de resultados.
A continuación procedo a cargar la base de datos simulada proporcionada en la plataforma del curso. Esta base contiene 1,000 observaciones con las variables:
Edad, Sexo, Severidad y Mortalidad.
Considero que antes de aplicar cualquier tecnica de aleatorización, es fundamental que pueda explorar la estructura y distribución de los datos para identificar posibles desbalances que pudieran influir en la interpretación de los resultados.
# Leer la base de datos en formato CSV
data <- read.csv("BD_Aleatorizacion.csv", stringsAsFactors = FALSE)
# Verificar dimensiones
cat("Dimensiones de la base:", nrow(data), "filas x", ncol(data), "columnas\n")
## Dimensiones de la base: 1000 filas x 5 columnas
# Vista rapida de la estructura
str(data)
## 'data.frame': 1000 obs. of 5 variables:
## $ ID : int 223 665 879 667 937 399 457 181 541 551 ...
## $ Sexo : chr "Femenino" "Femenino" "Femenino" "Femenino" ...
## $ Edad : int 68 66 59 38 59 59 38 20 73 31 ...
## $ Severidad : chr "Severo" "Moderado" "Leve" "Moderado" ...
## $ Mortalidad: int 0 0 0 0 0 0 0 0 0 0 ...
Me parece importante convertir las variables categoricas a factores con niveles ordenados antes de proceder con la aleatorizacion.
En particular, la variable Severidad tiene un orden clinico natural (Leve < Moderado < Severo) que debe respetarse en los análisis y gráficos posteriores.
# Convierto variables a formatos adecuados
data <- data %>%
mutate(
ID = as.integer(ID),
Sexo = factor(Sexo, levels = c("Femenino", "Masculino")),
Edad = as.numeric(Edad),
Severidad = factor(Severidad,
levels = c("Leve", "Moderado", "Severo"),
ordered = TRUE),
Mortalidad = factor(Mortalidad,
levels = c(0, 1),
labels = c("Vivo", "Fallecido"))
)
# Verifico que no haya datos faltantes
cat("Datos faltantes por variable:\n")
## Datos faltantes por variable:
colSums(is.na(data))
## ID Sexo Edad Severidad Mortalidad
## 0 0 0 0 0
Exploracion de las distribuciones basales
Considero relevante examinar como se distribuyen las variables antes de la aleatorización, ya que esto me permite identificar desbalances que el método de aleatorización debería manejar adecuadamente.
# Distribución por sexo
cat("=== Distribucion por sexo ===\n")
## === Distribucion por sexo ===
table(data$Sexo)
##
## Femenino Masculino
## 931 69
# Distribución por severidad
cat("\n=== Distribucion por severidad ===\n")
##
## === Distribucion por severidad ===
table(data$Severidad)
##
## Leve Moderado Severo
## 317 365 318
# Distribución por mortalidad
cat("\n=== Distribucion por mortalidad ===\n")
##
## === Distribucion por mortalidad ===
table(data$Mortalidad)
##
## Vivo Fallecido
## 904 96
# Resumen de edad
cat("\n=== Resumen de edad ===\n")
##
## === Resumen de edad ===
summary(data$Edad)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 18.00 32.00 46.50 46.41 61.00 74.00
Gráficos de distribuciones basales
# Paleta de colores personalizada
col_sexo <- c("Femenino" = "#85B7EB", "Masculino" = "#AFA9EC")
col_sev <- c("Leve" = "#5DCAA5", "Moderado" = "#F0997B", "Severo" = "#ED93B1")
# Grafico 1: Distribución por sexo
p1 <- ggplot(data, aes(x = Sexo, fill = Sexo)) +
geom_bar(width = 0.5, alpha = 0.85) +
geom_text(stat = "count", aes(label = after_stat(count)),
vjust = -0.5, size = 4) +
scale_fill_manual(values = col_sexo) +
labs(title = "Distribución por sexo",
x = NULL, y = "Frecuencia") +
theme_minimal(base_size = 12) +
theme(legend.position = "none")
# Grafico 2: Distribución por severidad
p2 <- ggplot(data, aes(x = Severidad, fill = Severidad)) +
geom_bar(width = 0.5, alpha = 0.85) +
geom_text(stat = "count", aes(label = after_stat(count)),
vjust = -0.5, size = 4) +
scale_fill_manual(values = col_sev) +
labs(title = "Distribución por severidad",
x = NULL, y = "Frecuencia") +
theme_minimal(base_size = 12) +
theme(legend.position = "none")
# Grafico 3: Distribución de edad
p3 <- ggplot(data, aes(x = Edad)) +
geom_histogram(binwidth = 5, fill = "#85B7EB",
color = "white", alpha = 0.85) +
geom_vline(xintercept = mean(data$Edad),
linetype = "dashed", color = "#534AB7", linewidth = 0.6) +
labs(title = "Distribucion de edad",
subtitle = paste0("Media = ", round(mean(data$Edad), 1), " anios"),
x = "Edad (años)", y = "Frecuencia") +
theme_minimal(base_size = 12)
# Combino los tres gráficos con patchwork
(p1 | p2) / p3 +
plot_annotation(
title = "Caracteristicas basales de la poblacion (n = 1,000)",
theme = theme(plot.title = element_text(face = "bold", size = 14))
)
Al explorar las distribuciones basales, identifico varios hallazgos
relevantes para la aleatorización:
En primer lugar, me llama la atención el marcado desbalance por sexo, pues la base contiene 931 mujeres (93.1%) frente a solo 69 hombres (6.9%).
Considero que este desbalance es particularmente importante porque, con un metodo de aleatorizacion que no controle el equilibrio, existe el riesgo de que la mayoría de los hombres queden asignados a un solo brazo del estudio, lo cual comprometería la comparabilidad entre grupos.
En segundo lugar, la severidad se distribuye de manera relativamente equilibrada entre los tres niveles:
Leve (31.7%), Moderado (36.5%) y Severo (31.8%); lo cual me parece favorable para la aleatorización.
Finalmente, la edad muestra una distribucion bastante uniforme con un rango de 18 a 74 años y una media de 46.4 años. Estos hallazgos basales serán el punto de referencia para evaluar si la aleatorizacion por bloques logra generar grupos comparables.
Aleatorización por bloques
Fundamento del método seleccionado
La aleatorización por bloques, también denominada aleatorización por bloques permutados, es un método de asignación fija que garantiza el equilibrio periódico entre los grupos de tratamiento y control a lo largo del proceso de reclutamiento (Wang & Bakhai, 2006; Friedman et al., 2010), pues representa una ventaja frente a la alternativa más elemental, que es la aleatorización simple.
En la aleatorización simple, cada paciente se asigna al azar con igual probabilidad a Tratamiento o Control, sin considerar en absoluto las asignaciones previas; es decir, el proceso carece de memoria, y si bien esta independencia hace que el método sea fácil de implementar y completamente impredecible, también lo hace vulnerable al desbalance numérico entre los brazos, sobre todo cuando el tamaño muestral es pequeño.
Para dimensionar este riesgo de manera concreta, Friedman et al. (2010) calculan que al aleatorizar apenas 20 pacientes con probabilidad 1:1, la probabilidad de obtener un reparto 60/40 o más desigual es de aproximadamente el 50%; es decir, en uno de cada dos estudios pequeños terminaríamos con grupos numéricamente dispares, lo cual reduce el poder estadístico y compromete la credibilidad de los resultados.
La aleatorización por bloques surge precisamente como respuesta a esa limitación, pues su lógica es sencilla pero poderosa, ya que en lugar de dejar que el azar actúe libremente sobre toda la muestra, se divide el proceso de reclutamiento en segmentos de tamaño fijo “los bloques” y dentro de cada uno se garantiza que exactamente la mitad de los participantes quede en cada grupo.
De este modo, el desequilibrio máximo posible en cualquier momento del estudio no puede superar la mitad del tamaño del bloque (b/2), lo cual me parece una restricción estructural muy interesante, ya que no sacrifica la aleatoriedad de la asignación dentro de cada bloque, pero sí elimina la posibilidad de acumulaciones desproporcionadas.
Considero que este método resulta particularmente adecuado para esta base de 1,000 pacientes por varias razones, pues en primer lugar, el balance periódico protege contra el sesgo accidental que podría surgir si las características de los pacientes reclutados cambian durante el periodo de enrolamiento.
En segundo lugar, si el estudio debiera detenerse anticipadamente por razones de seguridad o eficacia, el equilibrio numérico entre los brazos estaría garantizado en todo momento.
Finalmente, como señalan Wang y Bakhai (2006), la única desventaja relevante de este método, es la predecibilidad del último paciente en cada bloque cuando no hay enmascaramiento, pero se mitiga utilizando tamaños de bloque variables.
Definición de parámetros y ejecución
Para esta implementación, selecciono un tamaño de bloque de 10 participantes, lo que genera exactamente 100 bloques para cubrir los 1,000 pacientes.
Elijo este tamaño porque me ofrece un equilibrio razonable entre impredecibilidad (con bloques de 2 la secuencia se me volvería trivial de descifrar) y balance frecuente (bloques demasiado grandes perderían la ventaja del método).
Dentro de cada bloque, 5 participantes se asignan al grupo Tratamiento y 5 al grupo Control, lo que garantiza un ratio 1:1 perfecto.
Fijo la semilla aleatoria en set.seed(2026) para
asegurar la reproducibilidad completa del ejercicio, de la siguiente
manera:
set.seed(2026)
bloques <- rep(1:100, each = 10)
data$Grupo <- block_ra(blocks = bloques,
conditions = c("Tratamiento", "Control"))
data$Grupo <- factor(data$Grupo, levels = c("Tratamiento", "Control"))
Verificación del balance global
Una vez ejecutada la aleatorización, el primer paso de validación consiste en confirmar que el número total de participantes en cada brazo es exactamente igual, pues este es el requisito mínimo que debe cumplir cualquier método de aleatorización por bloques bien implementado.
table(data$Grupo)
##
## Tratamiento Control
## 500 500
Verificación del balance dentro de cada bloque
Más allá del balance global, me parece fundamental verificar que la restricción se cumple dentro de cada bloque individual. Si algún bloque mostrara un desbalance, esto indicaría un error en la implementación.
La siguiente verificación la hago para confirmar que cada uno de los 100 bloques contiene exactamente 5 participantes por grupo.
tabla_bloques <- table(bloques, data$Grupo)
cat("Primeros 10 bloques (verificación):\n")
## Primeros 10 bloques (verificación):
tabla_bloques[1:10, ]
##
## bloques Tratamiento Control
## 1 5 5
## 2 5 5
## 3 5 5
## 4 5 5
## 5 5 5
## 6 5 5
## 7 5 5
## 8 5 5
## 9 5 5
## 10 5 5
cat("\nRango de asignaciones por bloque:\n")
##
## Rango de asignaciones por bloque:
cat("Tratamiento - Min:", min(tabla_bloques[, "Tratamiento"]),
"Max:", max(tabla_bloques[, "Tratamiento"]), "\n")
## Tratamiento - Min: 5 Max: 5
cat("Control - Min:", min(tabla_bloques[, "Control"]),
"Max:", max(tabla_bloques[, "Control"]), "\n")
## Control - Min: 5 Max: 5
Visualización de la asignación
Para complementar la verificación numérica, voy a construir dos gráficos que me permiten apreciar visualmente el resultado de la aleatorización.
El primero muestra la distribución global entre los brazos del estudio; el segundo desglosa la asignación dentro de los primeros 10 bloques, permitiendo de esta forma verificar que el balance 5:5 se mantiene de manera consistente.
col_grupo <- c("Tratamiento" = "#5B8DB8", "Control" = "#E8875B")
g1 <- ggplot(data, aes(x = Grupo, fill = Grupo)) +
geom_bar(width = 0.5, alpha = 0.85) +
geom_text(stat = "count", aes(label = after_stat(count)),
vjust = -0.5, size = 5, fontface = "bold") +
scale_fill_manual(values = col_grupo) +
labs(title = "Asignación global por grupo",
subtitle = "Aleatorización por bloques (bloques de 10, ratio 1:1)",
x = NULL, y = "Número de participantes") +
theme_minimal(base_size = 12) +
theme(legend.position = "none") +
ylim(0, 580)
data_bloques10 <- data %>%
mutate(Bloque = bloques) %>%
filter(Bloque <= 10)
g2 <- ggplot(data_bloques10, aes(x = factor(Bloque), fill = Grupo)) +
geom_bar(position = "dodge", width = 0.7, alpha = 0.85) +
scale_fill_manual(values = col_grupo) +
labs(title = "Balance dentro de los primeros 10 bloques",
subtitle = "Cada bloque contiene exactamente 5 Tratamiento y 5 Control",
x = "Bloque", y = "Participantes", fill = "Grupo") +
theme_minimal(base_size = 12) +
theme(legend.position = "bottom")
g1 | g2
Justificación de las pruebas estadísticas
La Tabla 1 de un ensayo clínico tiene un propósito muy preciso, como es demostrar que la aleatorización logró generar grupos comparables al inicio del estudio (Friedman et al., 2010).
Para evaluar la homogeneidad entre los grupos de Tratamiento y Control, seleccionaré las pruebas estadísticas según la naturaleza de cada variable:
Edad (variable continua): utilizaré la prueba t de Student para muestras independientes, pues con n = 500 por grupo, por el teorema central del límite, la media muestral tiende a distribuirse normalmente, lo cual considero que hace apropiada esta prueba.
Sexo (variable categórica dicotómica): utilizaré la prueba Chi-cuadrado de Pearson, ya que evalúa si la distribución de hombres y mujeres difiere significativamente entre los brazos.
Severidad (variable categórica ordinal con tres niveles): también aplicaré Chi-cuadrado de Pearson, dado que me interesa evaluar si la distribución de frecuencias entre los niveles Leve, Moderado y Severo es homogénea entre grupos.
Un aspecto que considero relevante aclarar tiene que ver con la interpretación de los valores p en este contexto particular, pues a diferencia de lo que ocurre en un estudio observacional, donde un valor p significativo en la Tabla 1 revelaría un desequilibrio preocupante entre los grupos, en un ensayo aleatorizado la Tabla 1 no busca descubrir diferencias sino precisamente confirmar su ausencia.
Por lo cual, al construir esta tabla después de la aleatorización, mi expectativa es encontrar valores p elevados y no significativos en todas las variables, pues ello indicaría que el método de asignación por bloques logró su cometido, al generar grupos comparables al inicio del estudio.
Si alguna variable arrojara un p < 0.05, no necesariamente implicaría un fallo del método, ya que por definición el 5% de las comparaciones pueden resultar significativas por azar; sin embargo, me obligaría a examinar con mayor detenimiento si ese desequilibrio podría actuar como confusor en los análisis posteriores.
tabla1 <- data %>%
select(Grupo, Edad, Sexo, Severidad) %>%
tbl_summary(
by = Grupo,
statistic = list(
all_continuous() ~ "{mean} ({sd})",
all_categorical() ~ "{n} ({p}%)"
),
label = list(
Edad ~ "Edad (años)",
Sexo ~ "Sexo",
Severidad ~ "Severidad clínica"
),
digits = list(
all_continuous() ~ 1,
all_categorical() ~ c(0, 1)
)
) %>%
add_p(
test = list(
all_continuous() ~ "t.test",
all_categorical() ~ "chisq.test"
)
) %>%
add_overall() %>%
modify_header(label ~ "**Variable**") %>%
modify_spanning_header(c("stat_1", "stat_2") ~ "**Grupo de asignación**") %>%
bold_labels()
tabla1
| Variable | Overall N = 1,0001 |
Grupo de asignación
|
p-value2 | |
|---|---|---|---|---|
| Tratamiento N = 5001 |
Control N = 5001 |
|||
| Edad (años) | 46.4 (16.5) | 47.0 (16.5) | 45.8 (16.5) | 0.3 |
| Sexo | >0.9 | |||
| Femenino | 931 (93.1%) | 466 (93.2%) | 465 (93.0%) | |
| Masculino | 69 (6.9%) | 34 (6.8%) | 35 (7.0%) | |
| Severidad clínica | 0.2 | |||
| Leve | 317 (31.7%) | 149 (29.8%) | 168 (33.6%) | |
| Moderado | 365 (36.5%) | 195 (39.0%) | 170 (34.0%) | |
| Severo | 318 (31.8%) | 156 (31.2%) | 162 (32.4%) | |
| 1 Mean (SD); n (%) | ||||
| 2 Welch Two Sample t-test; Pearson’s Chi-squared test | ||||
Al examinar la Tabla 1, confirmo que la aleatorización por bloques cumplió su objetivo de generar grupos comparables al inicio del estudio.
Los resultados los interpreto variable por variable:
En cuanto a la edad, la media en el grupo Tratamiento es de 47.0 años (DE = 16.5) y en el grupo Control de 45.8 años (DE = 16.5), con un valor p = 0.3. Esta diferencia de apenas 1.2 años no solo carece de significancia estadística, sino que clínicamente resulta irrelevante; ambos grupos parten de una línea base etaria prácticamente idéntica, lo que me permite descartar que la edad actúe como variable de confusión en análisis posteriores.
Respecto al sexo, la distribución es notablemente simétrica, un 93.2% de mujeres en Tratamiento frente a 93.0% en Control (p > 0.9), por lo cual esto me parece particularmente revelador que, a pesar del marcado desbalance basal que identifiqué en la exploración, consistente en 931 mujeres frente a solo 69 hombres, la aleatorización entonces ha logrado repartir los 69 hombres de manera casi perfecta entre los brazos (34 vs. 35).
Un valor p superior a 0.9 indica que la distribución observada es prácticamente indistinguible de lo que esperaria por azar puro, lo cual valida la eficacia del método incluso ante distribuciones basales muy asimétricas.
En relación con la severidad clínica, observo diferencias porcentuales pequeñas entre los grupos, por ejemplo, el nivel Leve representa el 29.8% en Tratamiento y el 33.6% en Control, mientras que Moderado muestra un patrón inverso (39.0% vs. 34.0%). Sin embargo, el valor p = 0.2 me confirma que estas fluctuaciones se encuentran dentro del rango esperado por variabilidad aleatoria y no constituyen un desequilibrio sistemático.
Considero que este hallazgo es especialmente relevante dado que la severidad podría actuar como confusora de la relación tratamiento-mortalidad; su distribución homogénea entre los brazos fortalece la validez interna del diseño.
En síntesis, creo que las tres variables basales evaluadas arrojan valores p no significativos, lo que me permite concluir que los grupos de Tratamiento y Control son comparables al inicio del estudio y que la aleatorización por bloques funcionó adecuadamente.
Para tener una perspectiva visual complementaria a la Tabla 1, construiré tres gráficosa continuación que comparen la distribución de cada variable basal entre los grupos de Tratamiento y Control.
c1 <- ggplot(data, aes(x = Grupo, y = Edad, fill = Grupo)) +
geom_boxplot(width = 0.5, alpha = 0.8, outlier.shape = 21) +
stat_summary(fun = mean, geom = "point", shape = 18,
size = 3, color = "#2C3E50") +
scale_fill_manual(values = col_grupo) +
labs(title = "Distribución de edad por grupo",
subtitle = "Rombo = media aritmética",
x = NULL, y = "Edad (años)") +
theme_minimal(base_size = 12) +
theme(legend.position = "none")
c2 <- data %>%
count(Grupo, Sexo) %>%
group_by(Grupo) %>%
mutate(prop = n / sum(n) * 100) %>%
ggplot(aes(x = Grupo, y = prop, fill = Sexo)) +
geom_col(width = 0.5, alpha = 0.85, position = "stack") +
geom_text(aes(label = paste0(round(prop, 1), "%")),
position = position_stack(vjust = 0.5), size = 3.5) +
scale_fill_manual(values = col_sexo) +
labs(title = "Distribución de sexo por grupo",
subtitle = "Proporciones dentro de cada brazo",
x = NULL, y = "Porcentaje (%)", fill = "Sexo") +
theme_minimal(base_size = 12) +
theme(legend.position = "bottom")
c3 <- data %>%
count(Grupo, Severidad) %>%
group_by(Grupo) %>%
mutate(prop = n / sum(n) * 100) %>%
ggplot(aes(x = Grupo, y = prop, fill = Severidad)) +
geom_col(width = 0.5, alpha = 0.85, position = "dodge") +
geom_text(aes(label = paste0(round(prop, 1), "%")),
position = position_dodge(width = 0.5), vjust = -0.5, size = 3.2) +
scale_fill_manual(values = col_sev) +
labs(title = "Distribución de severidad por grupo",
subtitle = "Comparación entre niveles clínicos",
x = NULL, y = "Porcentaje (%)", fill = "Severidad") +
theme_minimal(base_size = 12) +
theme(legend.position = "bottom") +
ylim(0, 45)
(c1 | c2) / c3 +
plot_annotation(
title = "Comparabilidad de características basales entre grupos (post-aleatorización)",
theme = theme(plot.title = element_text(face = "bold", size = 14))
)
Al observar el panel de gráficos junto con los resultados de la Tabla 1, puedo confirmar que la aleatorización por bloques logró su propósito fundamental, al generar grupos comparables al inicio del estudio.
En Edad, tenemos que los boxplots en azul (Tratamiento) y naranja (Control) presentan una superposición casi perfecta, pues Las medianas que están representadas por las líneas horizontales centrales, se ubican alrededor de los 47 y 46 años respectivamente, mientras que los rombos (medias aritméticas) coinciden visualmente en ambas cajas.
La dispersión intercuartílica, delimitada por los bordes superior e inferior de cada caja, abarca un rango similar en ambos grupos (aproximadamente de 32 a 61 años), donde el valor p = 0.3 de la Tabla 1 confirma que no existe diferencia significativa.
En Sexo, las barras apiladas revelan una distribución prácticamente idéntica entre brazos, con 93.2% de mujeres (azul claro) en Tratamiento frente a 93.0% en Control, con la franja de hombres (lila) apenas visible en la base de cada barra (6.8% vs. 7.0%).
Me resulta notable que los 69 hombres de la muestra, que son un grupo minoritario que representaba un riesgo de desbalance, finalmente quedaron repartidos 34 y 35, de manera casi exacta.
El valor p > 0.9 confirma que esta distribución es indistinguible del azar, tal como predicen Friedman et al. (2010) para muestras grandes donde la ley de los grandes números opera a favor del balance.
En severidad clínica, aunque el gráfico de barras agrupadas muestra pequeñas fluctuaciones entre los niveles, por ejemplo, Leve alcanza 29.8% en Tratamiento (verde) frente a 33.6% en Control, y Moderado presenta el patrón inverso con 39.0% vs. 34.0% (salmón), el valor p = 0.2 confirma que estas diferencias caen dentro del rango esperado por variabilidad aleatoria.
Considero este hallazgo especialmente relevante dado que la severidad podría confundir la relación tratamiento-mortalidad, como advierten Wang y Bakhai (2006) al señalar que los factores pronósticos deben distribuirse equitativamente para validar la inferencia causal.
En síntesis, tanto los gráficos como los valores p me permiten concluir que los grupos son comparables en sus características basales, validando el supuesto de intercambiabilidad que sustenta todo ensayo clínico aleatorizado (Friedman et al., 2010).
La principal ventaja que identifico en la aleatorización por bloques es su capacidad de garantizar el equilibrio numérico entre los grupos en todo momento del estudio, pues a diferencia de la aleatorización simple, donde el desbalance acumulado puede crecer sin control, especialmente en muestras pequeñas, el método por bloques impone un “reinicio” periódico cada b participantes, siendo esto valioso en ensayos donde el reclutamiento es prolongado o donde existe la posibilidad de una terminación anticipada, porque en cualquier punto de corte los brazos contarán con un número prácticamente igual de participantes (Wang & Bakhai, 2006).
Además, como señala Friedman et al. (2010), este balance periódico facilita la interpretación de análisis interinos sin las distorsiones que generaría un desequilibrio numérico importante.
Reconozco una limitación importante, consistente en la predecibilidad parcial de la secuencia de asignación que sucede cuando el tamaño de bloque es conocido y el estudio no es doble ciego, pues si un investigador identifica que los bloques son de tamaño 10 y ha observado las asignaciones previas dentro del bloque actual, puede anticipar las últimas asignaciones, asi como lo afirma Friedman et al. (2010) que documenta que incluso sin conocer formalmente el tamaño del bloque, el personal del estudio puede deducirlo con algo de ingenio, lo cual podría introducir sesgo de selección.
La solución recomendada, según los autores, es utilizar tamaños de bloque variables seleccionados aleatoriamente, para mitigar este problema, aunque añade complejidad logística.
En este ejercicio, al trabajar con una base simulada donde no existe riesgo real de sesgo de selección, esta desventaja es teórica; sin embargo, en un ensayo clínico real constituiría una consideración metodológica relevante que debería abordarse en el protocolo.
Friedman, L. M., Furberg, C. D., & DeMets, D. L. (2010). Fundamentals of Clinical Trials (4th ed.). Springer. Capítulo 6: The Randomization Process, pp. 97–105.
Wang, D., & Bakhai, A. (2006). Randomization. In A. Bakhai & D. Wang (Eds.), Clinical Trials: A Practical Guide to Design, Analysis, and Reporting (pp. 65–73). Remedica.