Es una herramienta para determinar si los datos de tu muestra provienen de una población normal o no. La idea es representar los cuantiles de tu muestra frente a los cuantiles de una variable aleatoria normal. En la medida en que coincidan unos y otros, tendremos pocas razones para dudar de la normalidad de los datos.
Para ver un ejemplo, considera las longitudes de los caparazones de los cangrejos de la tablas crabs
:
library(MASS)
muestra = crabs$CL
aunque no es imprescindible, podemos estandarizar la muestra restando su media y diviendo entre su desviación típica muestral.
muestraStd = (muestra - mean(muestra))/sd(muestra)
La media de la variable transformada es 0 y la varianza 1.
Ahora se calculan los cuantiles de la muestra estandarizada y los de una normal con media 0 y desviación típica 1. Antes de calcularlos todos, vamos a trabajar con los deciles: en concreto, los deciles de una normal N(0,1):
(x = qnorm(c(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9),
mean = 0, sd = 1))
## [1] -1.2815516 -0.8416212 -0.5244005 -0.2533471 0.0000000 0.2533471
## [7] 0.5244005 0.8416212 1.2815516
y ahora los de la muestra estandarizada
(y = quantile(x = muestraStd, probs = seq(from = 0.1, to = 0.9, length.out = 9),
mean = 0, sd = 1))
## 10% 20% 30% 40% 50%
## -1.3492798006 -0.8576365439 -0.5710787600 -0.2817115861 -0.0007725823
## 60% 70% 80% 90%
## 0.3054509319 0.5793664606 0.9150885702 1.3210454307
Fíjate en que hemos usado la función seq
para no tener que escribir de uno en uno los deciles. Esto es más útil cuanto mayor sea el número de cuantiles a calcular (imagina teclear todos los centiles). Se representan los deciles teóricos frente a los de la muestra: las coordenadas de los puntos son
plot(x, y)
abline(a = 0, b = 1, lwd = 2, col = "red")
junto con la recta \(y = x\)
De manera análoga, se calculan ahora tantos cuantiles como elementos tiene la muestra, para la normal N(0,1)
x = qnorm(seq(from = 0, to = 1, length.out = length(muestraStd)+1),
mean = 0, sd = 1)
y para la muestra
y = quantile(x = muestraStd, probs = seq(from = 0, to = 1, length.out = length(muestraStd)+1),
mean = 0, sd = 1)
y se representan los cuantiles teóricos frente a los de la muestra
plot(x, y)
abline(a = 0, b = 1, lwd = 2, col = "red")
junto con la recta \(y = x\)
Copia, pega y ejecuta este cóodigo en un script de R varias veces. En la fila de arriba las muestras (200 elementos) son normales y en la de abajo no. Si la muesra es grande, consigue capturar la estructura (distribución) de la población de la que se toma
par(mfrow = c(2,3))
muestra = rnorm(200)
hist(muestra, main = "Muestra normal", cex.main = .8)
boxplot(muestra, main = "Muestra normal", cex.main = .8)
qqnorm(muestra, main = "Muestra normal", cex.main = .8)
qqline(muestra)
muestra2 = rexp(200, rate = .4)
hist(muestra2, main = "Muestra NO normal", cex.main = .8)
boxplot(muestra2, main = "Muestra NO normal", cex.main = .8)
qqnorm(muestra2, main = "Muestra NO normal", cex.main = .8)
qqline(muestra2)
par(mfrow = c(1,1))
Comprueba ahora que para muestras pequeñas, aunque los datos provengan de una población normal puede ser difícil detectarlo con boxplots, histogramas o qqplots. Copia este código en un script de R y ejecutala varias veces
par(mfrow = c(2,3))
muestra = rnorm(15)
hist(muestra, main = "Muestra normal", cex.main = .8)
boxplot(muestra, main = "Muestra normal", cex.main = .8)
qqnorm(muestra, main = "Muestra normal", cex.main = .8)
qqline(muestra)
muestra2 = rnorm(20)
hist(muestra2, main = "Muestra normal", cex.main = .8)
boxplot(muestra2, main = "Muestra normal", cex.main = .8)
qqnorm(muestra2, main = "Muestra normal", cex.main = .8)
qqline(muestra2)
par(mfrow = c(1,1))