{r setup, include=FALSE} knitr::opts_chunk$set(echo = TRUE)

iris.df <- data.frame(iris)
sample.index <- sample(1:nrow(iris.df), nrow(iris) * 0.75, replace = FALSE)
head(iris[sample.index, ])
summary(iris)

Este fragmento de código hace una muestra aleatoria simple del conjunto de datos de iris generando primero los índices mediante los cuales necesita subconjuntos de los datos de iris. En este caso, seleccionamos al azar cinco filas de los datos sin reemplazo. Replacement es una opción que si se tiene activa, va a permitir que al extraer una fila de datos, tendrá la opción de extraerla nuevamente. De forma predeterminada, esta opción está desactivada en la función sample() en R, como es el caso de la mayoría de las funciones de muestreo que se ven en el mundo de la programación.

Veamos cómo hacer un muestreo estratificado en R. En contraste a una muestra aleatoria simple, el muestreo estratificado se puede realizar sobre diferentes características en el conjunto de datos. Ampliemos esto observando las distribuciones de datos en el conjunto de datos iris:

summary(iris[sample.index, ])

Este fragmento de código hace una muestra aleatoria simple del conjunto de datos de iris generando primero los índices mediante los cuales necesita subconjuntos de los datos de iris. En este caso, seleccionamos al azar cinco filas de los datos sin reemplazo. Replacement es una opción que si se tiene activa, va a permitir que al extraer una fila de datos, tendrá la opción de extraerla nuevamente. De forma predeterminada, esta opción está desactivada en la función sample() en R, como es el caso de la mayoría de las funciones de muestreo que se ven en el mundo de la programación.

Veamos cómo hacer un muestreo estratificado en R. En contraste a una muestra aleatoria simple, el muestreo estratificado se puede realizar sobre diferentes características en el conjunto de datos. Ampliemos esto observando las distribuciones de datos en el conjunto de datos iris:

library('MASS')
library(splitstackshape)
summary(stratified(iris.df, "Sepal.Length", 0.7)

Aquí puede ver la población de los datos. Pretendemos obtener una muestra que tenga aproximadamente la misma distribución de valores para cualquiera de estas características. Note que algunas de esas columnas varían en un grado más alto que otras. En este caso, Petal.Length tiene la mayor cantidad de variación, seguido por Sepal.Length. Tenga esto en cuenta para el ejercicio de muestreo estratificado, por ahora hagamos una muestra aleatoria simple solo con los valores de Sepal.Length:

summary(iris[sample.index, ])

Este ejemplo toma una muestra del 75% de los datos originales, y se puede ver que las distribuciones están bastante cerca de los valores de la población principal. Probemos ahora el muestreo estratificado. Para esto, necesita el paquete splitstackshape y la función stratified() así:

library('MASS')
library(splitstackshape)
summary(stratified(iris.df, "Sepal.Length", 0.7))

La muestra estratificada tiene los mismos valores aproximadamente. Realizamos un muestreo estratificado de los datos de iris utilizando la función estratified(), centrándonos específicamente en los estratos de Sepal.Length. Luego, el código solicita una muestra del 70%.

Sin embargo, con el muestreo estratificado, puede especificar sobre qué estrato particular desea hacer el muestreo. Si está muestreando muchos estratos, generalmente querrá comenzar con las características que varían menos y luego avanzar con las que más varían. Las características con la variación más baja en el conjunto de datos de iris son Sepal.Width y Petal.Width, así que comencemos con esas:

summary(stratified(iris, c("Sepal.Width", "Petal.Width"), 0.7))

Puede ver en el resultado que el muestreo estratificado con múltiples grupos todavía tiene una buena representación de los datos de población (es decir, el conjunto de datos de iris completo) con el que comenzó. Las medias y las variaciones parecen bastante apropiadas para una muestra.

Para el muestreo sistemático, puede escribir una función simple que seleccione cada enésima fila secuencialmente dado un número de inicialización aleatorio:

sys.sample = function(N, n) {
k = ceiling(N/n)
r = sample(1:k, 1)
sys.samp = seq(r, r + k * (n - 1), k)
}
systematic.index <- sys.sample(nrow(iris), nrow(iris) * 0.75)
summary(iris[systematic.index, ])

Este fragmento de código define la función de muestreo sistemático y luego la ejecuta en los datos de iris. Para este ejemplo, ejecutamos dando el número de filas para el cual podemos obtener índices específicos, pero los resultados se ven bastante similares a lo que se han visto hasta ahora.

Función para la determinación del tamaño muestral en muestreo aleatorio estratificado.

Para comprobar la ventaja de hacer muestreo estratificado, simulamos una población con cinco estratos, bajo el supuesto de que cada estrato tiene un tamaño distinto y distintos valores medios y varianzas.

nis=c(1000,2000,5000,8000,10000)
mu=c(25,35,50,10,20)
sigma=c(4,6,8,2,3)
#mu=c(25,25,25,25,25)
#sigma=c(8,8,8,8,8)
estrato=list(
e1=rnorm(nis[1],mu[1],sigma[1]),
e2=rnorm(nis[2],mu[2],sigma[2]),
e3=rnorm(nis[3],mu[3],sigma[3]),
e4=rnorm(nis[4],mu[4],sigma[4]),
e5=rnorm(nis[5],mu[5],sigma[5]))
poblacion=unlist(estrato)

Mostramos el tamaño de la población, así como su media y desviación típica:

N=sum(nis)
mu.pob=mean(poblacion)
sigma.pob=sd(poblacion)
N
mu.pob
sigma.pob

Ejemplo: Tamaño muestral con muestreo aleatorio simple

Buscamos en primer lugar el tamaño óptimo para estimar μ con una precisión de 0.5 unidades y confianza 0.95 si se lleva a cabo un muestreo aleatorio simple.

La siguiente función permite calcular el tamaño de muestra necesario si se lleva a cabo un muestreo aleatorio simple:

tam.muestra=function(alfa,epsilon,s,N=Inf)
  {
    za2=qnorm(1-alfa/2)
    if (N==Inf) n=(s*za2/epsilon)^2
    else n=N*((za2*s)^2)/((N-1)*epsilon^2+(za2*s)^2)
    return(ceiling(n))
  }

Utilizaremos esta función para determinar el tamaño de muestra para estimar la media de la población anterior mediante muestreo aleatorio simple sin tener en cuenta la estratificación presente en la población.

Primero se extrae una pequeña muestra para estimar sigma (que no se conoce):

n.piloto=10
muestra.piloto=sample(poblacion, size=n.piloto, replace=F)
s=sd(muestra.piloto)
muestra.piloto
s

Con ese valor piloto determinamos el tamaño de muestra requerido para un muestreo aleatorio simple:

alfa=0.05
epsilon=0.5
n.pobfin=tam.muestra(alfa,epsilon,s,N=N)
n.pobinf=tam.muestra(alfa,epsilon,s)
n.pobfin
n.pobinf

Se saca una muestra de ese tamaño y se estima la media:

n=n.pobfin
muestra=sample(poblacion, size=n, replace=T)
mu.est=mean(muestra)
za2=qnorm(1-alfa/2)
errtip=(sd(muestra)/sqrt(n))*sqrt(1-n/N)
intervalo.mu=mu.est+c(-1,1)*za2*errtip

Se muestran el tamaño muestral utilizado, y la media y el intervalo de confianza obtenidos:

n
mu.est
intervalo.mu

Iteramos este proceso nsim veces y contamos cuántos intervalos contienen a la media

nsim=10000
nc=0
fc=sqrt(1-n/N)
for (i in 1:nsim)
  {
    muestra=sample(poblacion, size=n)
    mu.est=mean(muestra)
    intervalo.mu=mu.est+c(-1,1)*za2*(sd(muestra)/sqrt(n))*fc
    if ((mu.pob>=intervalo.mu[1])&(mu.pob<=intervalo.mu[2])) nc=nc+1
  }
nc
nc/nsim

sí pues, podemos confirmar que el muestreo aleatorio simple consigue estimar la media de la población con la confianza (0.95) y precisión (0.5) requeridas. Ahora bien, ello ha requerido el esfuerzo de tomar una muestra de tamaño

Ejemplo: Tamaño muestral con muestreo aleatorio estratificado

Repetimos el ejercicio anterior, pero ahora con muestreo estratificado.

Para ello se requiere una estimación piloto de la varianza en cada estrato:

s2=rep(0,5)
for (j in 1:5)
  {
    n.piloto=10
    muestra.piloto=sample(estrato[[j]], size=n.piloto, replace=F)
    s2[j]=var(muestra.piloto)
}
s2

Para calcular el tamaño de muestra en cada estrato, en primer lugar construimos una función para ello:

  • La función recibe como argumentos los valores del error máximo a cometer, la confianza, las ϕ, las si, el tipo de afijación a realizar (1: uniforme, 2:proporcional, 3:óptima) y el tamaño N de la población.

  • Como resultado, la función devuelve el tamaño muestral en cada estrato.

nMuestreoEstratificado=function(epsilon,confianza,phi,s,afijacion=3,N=inf){
  K=length(phi)  # Número de estratos
  alfa=1-confianza
  za=qnorm(1-alfa/2)
  w=if (afijacion==1) rep(1/K,K) else if (afijacion==2) phi else phi*s/sum(phi*s)
  if (N!=Inf) n=sum(phi^2*s^2/w)/((epsilon/za)^2+(1/N)*sum(phi*s^2))
  else n=(za/epsilon)^2*sum(phi^2*s^2/w)
  ni=ceiling(n*w)
  return(ni)
}

Aplicamos ahora nuestra función para el cálculo del tamaño muestral en cada estrato del ejemplo anterior.

 Utilizando afijación uniforme:

niUnif=nMuestreoEstratificado(epsilon=0.5,confianza=0.95,phi=nis/N,s=sqrt(s2),afijacion=1,N=N)
niUnif
sum(niUnif)

Utilizando afijación proporcional:

niProp=nMuestreoEstratificado(epsilon=0.5,confianza=0.95,p=nis/N,s=sqrt(s2),afijacion=2,N=N)
niProp
sum(niProp)

Utilizando afijación óptima:

niOpt=nMuestreoEstratificado(epsilon=0.5,confianza=0.95,p=nis/N,s=sqrt(s2),afijacion=3,N=N)
niOpt
sum(niOpt)