Distribución uniforme continua en R
La distribución uniforme es una distribución continua donde todos los intervalos de la misma longitud en el rango de la distribución acumulan la misma probabilidad. En este tutorial explicaremos cómo usar las funciones dunif, punif, qunif y runif para calcular la densidad, distribución acumulada, los cuantiles y generar observaciones aleatorias, respectivamente, de una distribución uniforme en R.
La distribución uniforme
Sea \(X \sim U(a, b)\), es decir, una variable aleatoria con distribución uniforme en el intervalo \((a, b)\), con \(a, b \in \mathbb{R}, a < b\):
- La función de densidad de probabilidad (o PDF, por sus siglas en inglés) de \(x\) es \(f(x) = \frac{1}{b - a}\) si \(x \in (a, b)\) y \(0\) en otro caso.
- La función de distribución acumulada (CDF) es \(F(x) = P(X \leq x) = \frac{x-a}{b-a}\).
- La función cuantil es \(Q(p) = F^{-1}(p)\).
- La esperanza y la varianza de \(X\) son \(E(X) = \frac{a + b}{2}\) y \(Var(X) = \frac{(b-a)^2}{12}\), respectivamente.
Las diferentes funciones de la distribución uniforme se pueden calcular en R para cualquier valor de \(x\). Estas funciones son: dunif
, para la función de densidad, punif
, para la distribución acumulada y qunif
, para la función cuantil. Además, la función runif
permite obtener \(n\) observaciones aleatorias de una distribución uniforme. Estas funciones se describen a continuación:
Función | Descripción |
---|---|
dunif |
Densidad uniforme continua (Función de densidad de probabilidad) |
punif |
Distribución uniforme continua (Función de distribución) |
qunif |
Función cuantil de la distribución uniforme |
runif |
Generación de números peudoaleatorios de la distribución uniforme continua |
Por defecto, estas funciones consideran la distribución uniforme en el intervalo (0, 1), también conocida como distribución uniforme estándar.
La función dunif
Para calcular la función de densidad uniforme en R en el intervalo \((a, b)\) para cualquier valor de \(x\) se puede utilizar la función dunif
, que tiene la siguiente sintaxis:
dunif(x, # Valores del eje X (rejilla de valores)
min = 0, # Límite inferior de la distribución (a)
max = 1, # Límite superior de la distribución (b)
log = FALSE) # Si TRUE, las probabilidades se devuelven como log
Considera que quieras calcular la función de densidad de probabilidad uniforme en el intervalo \((1, 3)\) para una rejilla de valores. Con tal propósito puedes escribir:
x <- 0:4 # Rejilla
dunif(x, min = 1, max = 3)
0.0 0.5 0.5 0.5 0.0
Dibujar la función de densidad uniforme en R
Puedes crear un gráfico de la función de densidad de probabilidad e una distribución uniforme con la siguiente función:
# x: rejilla de valores del eje X (opcional)
# min: límite inferior de la distribución (a)
# max: límite superior de la distribución (b)
# lwd: ancho de los segmentos del gráfico
# col: color de los segmentos y de los puntos del gráfico
# ...: argumentos adicionales a ser pasados a la función plot
plotunif <- function(x, min = 0, max = 1, lwd = 1, col = 1, ...) {
# Rejilla de valores del eje X
if (missing(x)) {
x <- seq(min - 0.5, max + 0.5, 0.01)
}
if(max < min) {
stop("'min' must be lower than 'max'")
}
plot(x, dunif(x, min = min, max = max),
xlim = c(min - 0.25, max + 0.25), type = "l",
lty = 0, ylab = "f(x)", ...)
segments(min, 1/(max - min), max, 1/(max - min), col = col, lwd = lwd)
segments(min - 2, 0, min, 0, lwd = lwd, col = col)
segments(max, 0, max + 2, 0, lwd = lwd, col = col)
points(min, 1/(max - min), pch = 19, col = col)
points(max, 1/(max - min), pch = 19, col = col)
segments(min, 0, min, 1/(max - min), lty = 2, col = col, lwd = lwd)
segments(max, 0, max, 1/(max - min), lty = 2, col = col, lwd = lwd)
points(0, min, pch = 21, col = col, bg = "white")
points(max, min, pch = 21, col = col, bg = "white")
}
Como ejemplo, si quieres dibujar la función de densidad uniforme estándar en color azul puedes escribir:
plotunif(min = 0, max = 1, lwd = 2, col = 4, main = "PDF uniforme")
La función punif
En R, puedes hacer uso de la función punif
para calcular la función de distribución acumulada uniforme, esto es, la probabilidad de que una variable \(X\) tome valores menores o iguales a \(x\). Esta función tiene la siguiente sintaxis:
punif(q, # Vector de cuantiles
min = 0, # Límite inferior de la distribución (a)
max = 0, # Límite superior de la distribución (b)
lower.tail = TRUE, # Si TRUE, las probabilidades son P(X <= x), o P(X > x) en otro caso
log.p = FALSE) # Si TRUE, las probabilidades se devuelven como log
Como ejemplo, si quieres calcular la probabilidad de que una variable en el intervalo \((0, 1)\) tome valores menores o iguales que 0.6 es:
punif(0.6) # 0.6
Ejemplo con la función punif
Veamos un caso en mayor detalle. Considera que \(X\) es el tiempo (en minutos) que una persona tiene que esperar para tomar un vuelo. Si un vuelo despega cada hora \(X \sim U(0, 60)\). Tomando lo anterior en cuenta:
- La probabilidad de esperar menos de 15 minutos es \(P(X < 15) = P(X <= 15)\):
punif(15, min = 0, max = 60) # 0.25 o 25%
1 - punif(15, min = 0, max = 60, lower.tail = FALSE) # Equivalente
Hemos desarrollado la siguiente función para sombrear el área en un intervalo de la función de densidad de probabilidad uniforme con una sola línea de código:
# min: límite inferior de la distribución (a)
# max: límite superior de la distribución (b)
# lb: límite inferior del área
# ub: límite superior del área
# col: color de las líneas y puntos
# acolor: color del área
# ...: argumentos adicionales a ser pasados a la función plot
unif_area <- function(min = 0, max = 1, lb, ub, col = 1,
acolor = "lightgray", ...) {
x <- seq(min - 0.25 * max, max + 0.25 * max, 0.001)
if (missing(lb)) {
lb <- min(x)
}
if (missing(ub)) {
ub <- max(x)
}
if(max < min) {
stop("'min' must be lower than 'max'")
}
x2 <- seq(lb, ub, length = 1000)
plot(x, dunif(x, min = min, max = max),
xlim = c(min - 0.25 * max, max + 0.25 * max), type = "l",
ylab = "f(x)", lty = 0, ...)
y <- dunif(x2, min = min, max = max)
polygon(c(lb, x2, ub), c(0, y, 0), col = acolor, lty = 0)
segments(min, 1/(max - min), max, 1/(max - min), lwd = 2, col = col)
segments(min - 2 * max, 0, min, 0, lwd = 2, col = col)
segments(max, 0, max + 2 * max, 0, lwd = 2, col = col)
points(min, 1/(max - min), pch = 19, col = col)
points(max, 1/(max - min), pch = 19, col = col)
segments(min, 0, min, 1/(max - min), lty = 2, col = col, lwd = 2)
segments(max, 0, max, 1/(max - min), lty = 2, col = col, lwd = 2)
points(0, min, pch = 21, col = col, bg = "white")
points(max, min, pch = 21, col = col, bg = "white")
}
A modo ilustrativo, si quieres dibujar el área entre 0 y 0.5 de una distribución uniforme en el intervalo \((0, 1)\), que se puede calcular con punif(0.5)
puedes escribir:
unif_area(min = 0, max = 1, lb = 0, ub = 0.5,
main = "punif(0.5)", acolor = "white")
La probabilidad calculada (0.25) corresponde al área:
unif_area(min = 0, max = 60, lb = 0, ub = 15)
text(8, 0.008, "25%", srt = 90, cex = 1.2)
- La probabilidad de esperar más de 45 minutos por el vuelo es \(P(X > 45) = 1 - P(X \leq 45)\):
punif(45, min = 0, max = 60, lower.tail = FALSE) # 0.25 o 25%
1 - punif(45, min = 0, max = 60) # Equivalente
Que corresponde a:
unif_area(min = 0, max = 60, lb = 45, ub = 60)
text(51, 0.008, "25%", srt = 90, cex = 1.2)
- La probabilidad de esperar entre 20 y 30 minutos a tomar el avión es \(P(X <= 30) - P(X <= 20)\):
punif(30, min = 0, max = 60) - punif(20, min = 0, max = 60) # 0.167 o 16.7%
La probabilidad calculada se puede representar con el siguiente gráfico:
unif_area(min = 0, max = 60, lb = 20, ub = 30)
text(24, 0.008, "16.7%", srt = 90, cex = 1.2)
Como la distribución uniforme es continua \(P(X = x) = 0\), entonces \(P(X \geq x) = P(X > x)\) y \(P(X \leq x) = P(X < x)\).
Dibujar la función de distribución
acumulada en R
También puedes crear el gráfico de la función de distribución acumulada de la distribución uniforme en R. Para ello tienes que escribir lo siguiente:
# Rejilla de valores del eje X
x <- seq(-0.5, 1.5, 0.01)
# Distribución uniforme entre 0 y 1
plot(x, punif(x, min = 0, max = 0), type = "l", main = "CDF uniforme",
ylab = "F(x)", lwd = 2, col = "red")
# Equivalente a:
plot(punif, -0.5, 1.5, type = "l", main = "CDF uniforme",
ylab = "F(x)", lwd = 2, col = "red")
La función qunif
En R, puedes calcular el cuantil correspondiente para una probabilidad (p) de una distribución uniforme con la función qunif
, que tiene la siguiente sintaxis:
qunif(p, # Vector de probabilidades
min = 0, # Límite inferior de la distribución (a)
max = 1, # Límite superior de la distribución (b)
lower.tail = TRUE, # Si TRUE, las probabilidades son P(X <= x), o P(X > x) en otro caso
log.p = FALSE) # Si TRUE, las probabilidades se devuelven como log
En caso de que quieres calcular el cuantil para la probabilidad 0.5 de una distribución en el intervalo \((0, 60)\) puedes escribir:
qunif(0.5, min = 0, max = 60) # 30
unif_area(min = 0, max = 60, lb = 0, ub = 30)
text(15, 0.008, "50%", srt = 90, cex = 1.2)
arrows(38, 0.005, 31, 0.0005, length = 0.15)
text(44, 0.006, "qunif(0.5)")
Gráfico de la función cuantil uniforme
Es posible crear el gráfico de la función cuantil uniforme en R. Para ello puedes escribir lo siguiente para dibujar la función en el intervalo \((0, 1)\):
plot(qunif, punif(0), punif(1), lwd = 2,
main = "Función cuantil uniforme",
xlab = "p", ylab = "Q(p)")
segments(0, 0.5, punif(0.5), 0.5, lty = 2, lwd = 2)
segments(punif(0.5), 0, punif(0.5), qunif(0.5), lty = 2, lwd = 2)
Recuerda que punif(0.5) = 0.5
y qunif(0.5) = 0.5
.
La función runif
La función runif
permite obtener \(n\) observaciones aleatorias de una distribución uniforme. Los argumentos de la función se describen a continuación:
runif(n # Número de observaciones a ser generadas
min = 0, # Límite inferior de la distribución (a)
max = 0) # Límite superior de la distribución (b)
Como ejemplo, puedes obtener diez observaciones de una distribución uniforme en el intervalo\((-1, 1)\) escribiendo:
runif(n = 10, min = -1, max = 1)
-0.20757312 -0.46819001 -0.80643735 -0.92675885 0.80520074
0.39716130 -0.39939392 0.78837145 0.28130687 0.09807602
Sin embargo, cada vez que ejecutes el código anterior obtendrás diez números distintos. Si quieres que la salida sea reproducible puedes fijar una semilla con la función set.seed
.
set.seed(1)
runif(n = 10, min = -1, max = 1)
-0.4689827 -0.2557522 0.1457067 0.8164156 -0.5966361
0.7967794 0.8893505 0.3215956 0.2582281 -0.8764275
Observa que a medida que se incrementa el número de observaciones generadas, el histograma de dichas observaciones se aproxima a la función de densidad uniforme real:
# Una fila, tres columnas
par(mfrow = c(1, 3))
x <- seq(-0.5, 1.5, 0.01)
set.seed(1)
# n = 10
hist(runif(10), main = "n = 100", xlim = c(-0.2, 1.25),
xlab = "", prob = TRUE)
lines(x, dunif(x), col = "red", lwd = 2)
# n = 1000
hist(runif(1000), main = "n = 10000", xlim = c(-0.2, 1.25),
xlab = "", prob = TRUE)
lines(x, dunif(x), col = "red", lwd = 2)
# n = 100000
hist(runif(100000), main = "n = 1000000", xlim = c(-0.2, 1.25),
xlab = "", prob = TRUE)
lines(x, dunif(x), col = "red", lwd = 2)
# Volvemos a una fila y una columna
par(mfrow = c(1, 1))