set.seed() va primero
Las extracciones aleatorias que cambian en cada ejecución son inútiles para enseñar, evaluar, depurar o hacer ciencia - si tu simulación dice 0.146 hoy y 0.153 mañana, ¿qué número va en el informe? set.seed() fija el punto de partida del generador, haciendo exactamente repetible todo el flujo de "aleatoriedad" que sigue:
La misma semilla, extracciones idénticas, siempre, en cualquier máquina. Los números son pseudo-aleatorios: una secuencia determinista diseñada para superar todos los tests estadísticos de aleatoriedad, con la semilla eligiendo en qué punto de la secuencia empiezas. El valor de la semilla en sí no significa nada - 42, 7, 20260807 - elige cualquiera; solo anótalo. El hábito que hay que construir: un set.seed() al principio de cualquier script que use aleatoriedad. (Ten en cuenta que consumir extracciones avanza el estado, así que el orden de las llamadas también importa para la reproducibilidad.)
El sistema d/p/q/r: una tabla descifra toda la librería
R nombra cada función de distribución como prefijo + familia, y una vez que ves la cuadrícula puedes leer toda la librería estadística:
| Prefijo | Pregunta que responde | Ejemplo con la normal |
|---|---|---|
r | Dame extracciones aleatorias | rnorm(5) |
d | Densidad: ¿qué altura tiene la curva en x? | dnorm(0) |
p | Probabilidad: ¿P(X ≤ x)? | pnorm(1.96) |
q | Cuantil: ¿qué x está en este percentil? | qnorm(0.975) |
p y q son inversas, y son la pareja que conociste en intervalos de confianza como qt(0.975, df):
Cambia el nombre de la familia y todo se traslada: runif/dunif/punif/qunif, rbinom/..., rpois/..., rt/..., rexp/.... Aprende cuatro prefijos y obtén docenas de distribuciones.
rnorm(): extracciones normales
rnorm(n, mean, sd) extrae de una campana de Gauss - el caballo de batalla para simular datos de tipo medición:
La media y la sd muestrales caen cerca - no encima - de 100 y 15: esa brecha es el ruido muestral, que se reduce conforme crece n. La última línea es un truco que vale la pena robar: mean() de un vector lógico es la proporción de TRUEs, y la fracción por encima de 130 sale cerca del valor teórico 1 - pnorm(130, 100, 15) ≈ 2.3%. Los valores por defecto son mean = 0, sd = 1 (la normal estándar). Un histograma de iq muestra la campana familiar.
runif(), rbinom(), rpois()
Tres familias más cubren la mayoría de las necesidades de simulación:
runif() reparte las extracciones uniformemente en un rango ("uniform", no "run if" - todo el mundo lo lee mal una vez). rbinom(n, size, prob) simula n experimentos de size intentos cada uno, devolviendo el recuento de éxitos de cada uno - así que cada valor de arriba son caras en 10 lanzamientos. rpois(n, lambda) genera recuentos de eventos que ocurren de forma independiente a una tasa media conocida: tickets de soporte por hora, erratas por página.
sample(): muestrear y barajar
Mientras que las funciones r* inventan valores a partir de una distribución, sample() extrae de valores que ya tienes:
El argumento replace es toda la historia: FALSE (por defecto) reparte cartas - cada valor puede aparecer una vez, y pedir más de los que tienes es un error; TRUE lanza dados - cada extracción se reinicia. Muestrear con reemplazo de tus propios datos es el motor del bootstrapping. Llamado solo con un vector, sample(x) devuelve una permutación aleatoria - el modismo para barajar.
Muestrear filas de un data frame usa sample() dentro de la indexación de filas:
sample(nrow(mtcars), 5) elige 5 números de fila al azar; la indexación extrae esas filas. Esta es la jugada estándar para revisar por encima un dataset grande o dividir conjuntos de entrenamiento y prueba.
Una mini simulación de Monte Carlo
Aquí está la recompensa de todo el kit. Pregunta: un proceso produce mediciones distribuidas N(100, 15); promedias 10 de ellas - ¿cuál es la probabilidad de que ese promedio supere 105? En lugar de derivar la respuesta, simúlala - haz el experimento 10,000 veces y cuenta:
La simulación cae a unas pocas milésimas del valor exacto (alrededor de 0.146). Eso es Monte Carlo en una frase: escribe un ensayo como una función, replícalo miles de veces con replicate(), y toma la mean() de los éxitos. La respuesta exacta existía aquí porque el planteamiento era de libro de texto - en cuanto la pregunta se complica (distribuciones raras, el máximo de extracciones correlacionadas, un juego basado en reglas), la vía analítica se cierra y la receta de simulación sigue funcionando sin cambios. Fíjate en el 15 / sqrt(10) de la comprobación: las medias oscilan menos que las extracciones individuales - la misma ley de la raíz cuadrada que gobierna las anchuras de los intervalos de confianza.
Calidad de simulación, no de secretos
Un límite que hay que respetar: el generador por defecto de R (Mersenne Twister) está construido para calidad estadística y velocidad, no para secretismo. Su salida es determinista dada la semilla y su estado interno puede reconstruirse a partir de la salida observada - defectos fatales para contraseñas, tokens o cualquier cosa cercana a la seguridad. Para simulación, bootstrapping y enseñanza es excelente; para criptografía, usa una librería específica (por ejemplo, el paquete openssl), nunca sample() ni runif().
Lo que te llevas
- Un
set.seed()al principio hace reproducible cada resultado "aleatorio" - misma semilla, mismas extracciones. - Los prefijos d/p/q/r descifran toda la librería de distribuciones: extracción aleatoria, densidad, probabilidad acumulada, cuantil.
rnorm(n, mean, sd),runif(n, min, max),rbinom(n, size, prob),rpois(n, lambda)cubren la mayoría de las necesidades de simulación.sample()extrae de tus propios valores -replace = TRUEpara dados, el valor por defecto para cartas, sinsizepara barajar;df[sample(nrow(df), k), ]muestrea filas.- Monte Carlo = función de un ensayo +
replicate()+mean()- la receta que responde preguntas de probabilidad que las matemáticas no alcanzan cómodamente. - El RNG de R es para simulación, no para criptografía.
A continuación: depuración - qué significan realmente los mensajes de error de R y cómo leer un traceback.
Preguntas frecuentes
¿Qué hace set.seed() en R?
Fija el punto de partida del generador de números aleatorios de R, de modo que las extracciones "aleatorias" que siguen salen idénticas en cada ejecución. Llámalo una vez al principio de cualquier script que use aleatoriedad - set.seed(42) - y tu simulación se vuelve reproducible: colegas, evaluadores y tu yo del futuro ven los mismos números.
¿Cómo se generan números aleatorios en R?
Elige la distribución: rnorm(n, mean, sd) para extracciones normales, runif(n, min, max) para uniformes, rbinom(n, size, prob) para recuentos de éxitos, rpois(n, lambda) para recuentos de eventos. Para muestrear valores existentes, usa sample(x, size).
¿Cuál es la diferencia entre rnorm, dnorm, pnorm y qnorm?
Una distribución, cuatro prefijos: r extrae valores aleatorios, d da la altura de la curva de densidad, p da la probabilidad acumulada P(X ≤ x), y q es su inversa - el valor en un percentil dado. Los mismos cuatro prefijos funcionan para todas las distribuciones que R conoce: runif/dunif/punif/qunif, rbinom/dbinom/pbinom/qbinom, etcétera.
¿Cómo se toma una muestra aleatoria de filas de un data frame en R?
Indexa las filas con sample(): df[sample(nrow(df), 5), ] elige 5 filas sin reemplazo. Añade replace = TRUE para muestrear con reemplazo (la jugada detrás del bootstrapping).