Bienvenido. Vamos a replicar en R lo que hicieron en Python con
scipy.stats. La buena noticia es que R tiene un sistema
mucho más elegante y unificado para trabajar con
distribuciones: el sistema de prefijos.
En R, cada distribución tiene 4 funciones asociadas,
identificadas por una letra inicial. Es un patrón que memorizas una vez
y aplica a todas las distribuciones (norm,
gamma, pois, binom,
lnorm, exp, weibull, etc.).
| Prefijo | Nombre | Equivalente en scipy.stats |
Qué hace |
|---|---|---|---|
d |
density / distribución | pdf (continuas) o pmf (discretas) |
Devuelve la función de densidad (o masa) en un punto
x |
p |
probabilidad acumulada | cdf |
Devuelve \(P(X \le x)\) |
q |
quantil | ppf |
Dado \(p \in (0,1)\), devuelve \(x\) tal que \(P(X\le x)=p\) |
r |
random | rvs |
Genera valores aleatorios de la distribución |
norm, gamma y
pois# ---------- NORMAL ----------
dnorm(x = 0, mean = 0, sd = 1) # densidad en x = 0 → 0.3989
pnorm(q = 1.96, mean = 0, sd = 1) # P(X ≤ 1.96) → 0.975
qnorm(p = 0.95, mean = 0, sd = 1) # cuantil 0.95 → 1.6449
rnorm(n = 10, mean = 0, sd = 1) # 10 valores aleatorios
# ---------- GAMMA ----------
dgamma(x = 100, shape = 4, rate = 0.05) # pdf en x = 100
pgamma(q = 100, shape = 4, rate = 0.05) # P(X ≤ 100)
qgamma(p = 0.90, shape = 4, rate = 0.05) # cuantil 0.90
rgamma(n = 1000, shape = 4, rate = 0.05) # 1000 simulaciones
# ---------- POISSON ----------
dpois(x = 3, lambda = 2.5) # P(X = 3) → pmf (¡no pdf!)
ppois(q = 3, lambda = 2.5) # P(X ≤ 3) → cdf
qpois(p = 0.90, lambda = 2.5) # cuantil 0.90
rpois(n = 100, lambda = 2.5) # 100 conteos simulados
Ojo hidrólogo: en
gammapuedes parametrizar porrate(tasa \(\beta\)) o porscale(= \(1/\beta\)). Es la fuente #1 de errores. Verifica siempre con la media: \(\mu = \text{shape}/\text{rate}\).
ggplot2::stat_functionSupongamos que estamos modelando precipitación mensual (mm) con una Gamma de forma \(k=4\) y tasa \(\beta=0.05\) (media = 80 mm).
# ============================================================
# Simulación Gamma + curva teórica con ggplot2
# ============================================================
library(ggplot2)
# --- 1. Parámetros de la distribución Gamma ---
shape_k <- 4
rate_b <- 0.05 # media = 4/0.05 = 80 mm
# --- 2. Simulación (equivalente a .rvs en scipy) ---
set.seed(2024) # reproducibilidad
n_sim <- 5000
sims <- rgamma(n = n_sim, shape = shape_k, rate = rate_b)
# --- 3. Histograma + curva teórica ---
ggplot(data.frame(x = sims), aes(x = x)) +
geom_histogram(aes(y = after_stat(density)),
bins = 40, fill = "steelblue",
color = "white", alpha = 0.6) +
stat_function(
fun = dgamma, # función a graficar
args = list(shape = shape_k, rate = rate_b),
color = "firebrick", linewidth = 1.2
) +
labs(
title = "Distribución Gamma simulada vs. curva teórica",
subtitle = sprintf("shape = %.1f, rate = %.2f (media = %.1f mm)",
shape_k, rate_b, shape_k / rate_b),
x = "Precipitación mensual (mm)",
y = "Densidad"
) +
theme_minimal(base_size = 13)
stat_function?stat_function no necesita datos:
evalúa la función fun sobre el rango del eje x y la
dibuja.aes(y = after_stat(density)) en el
histograma: sin esto, el eje y sería conteo y la curva
teórica (densidad) no coincidiría en escala.Alternativa 100% base R (equivalente):
hist(sims, breaks = 40, freq = FALSE,
col = "steelblue", border = "white",
main = "Gamma: simulación vs teoría",
xlab = "Precipitación (mm)")
curve(dgamma(x, shape = shape_k, rate = rate_b),
add = TRUE, col = "firebrick", lwd = 2)
Con la misma Gamma (\(k=4\), \(\beta=0.05\)):
# --- P(X ≤ 100) → equivale a scipy.stats.gamma.cdf(100, ...) ---
p_leq_100 <- pgamma(q = 100, shape = shape_k, rate = rate_b)
p_leq_100
#> [1] 0.5665299
# Interpretación hidrológica:
# "Hay ~56.65% de probabilidad de que la precipitación mensual
# no supere los 100 mm."
# --- Cuantil 0.90 → equivale a scipy.stats.gamma.ppf(0.90, ...) ---
x_90 <- qgamma(p = 0.90, shape = shape_k, rate = rate_b)
x_90
#> [1] 120.6787
# Interpretación:
# "El evento de precipitación mensual asociado a un período de
# retorno de 10 años (no excedencia 0.90) es ~120.7 mm."
# Nota: T = 1 / (1 - F) = 1 / 0.10 = 10 años.
# Si pgamma es correcto, qgamma debe invertirlo:
qgamma(pgamma(100, shape_k, rate_b), shape_k, rate_b)
#> [1] 100
# Y el cuantil 0.90 evaluado en la cdf debe dar 0.90:
pgamma(x_90, shape_k, rate_b)
#> [1] 0.9
Esta propiedad de inversa mutua entre
p* y q* es la que te permite, en hidrología,
pasar de probabilidad → magnitud del evento (diseño) y de magnitud →
probabilidad (riesgo).
| Acción | scipy.stats (Python) |
R |
|---|---|---|
| Densidad / masa | gamma.pdf(x, a, scale) /
poisson.pmf(k, mu) |
dgamma(x, shape, rate) /
dpois(k, lambda) |
| Acumulada | gamma.cdf(x, a, scale) |
pgamma(x, shape, rate) |
| Cuantil | gamma.ppf(p, a, scale) |
qgamma(p, shape, rate) |
| Simulación | gamma.rvs(a, scale, size=n) |
rgamma(n, shape, rate) |
ggplot2 el
diagrama de barras de frecuencias relativas frente a
dpois.ppois y qpois.pnorm/qnorm.Pista: para Poisson usa geom_col sobre
una tabla de frecuencias, no geom_histogram (es
discreta).