resueltos - muestreo por conglomerados con probabilidades proporcionales al tamaño
Muestreo aleatorio estratificado del marco de datos (4)
A menos que haya entendido mal la pregunta, esto es ridículamente fácil de hacer con funciones simples.
Paso 1: Crea un indicador de estrato usando la función de interaction
.
Paso 2: Use tapply
en una secuencia de indicadores de fila para identificar los índices de la muestra aleatoria.
Paso 3: Subcontrata los datos con esos índices.
Usando el ejemplo de datos de @Thomas:
set.seed(1)
n <- 1e4
d <- data.frame(age = sample(1:5,n,TRUE),
lc = rbinom(n,1,.5),
ants = rbinom(n,1,.7))
## stratum indicator
d$group <- interaction(d[, c(''age'', ''lc'')])
## sample selection
indices <- tapply(1:nrow(d), d$group, sample, 30)
## obtain subsample
subsampd <- d[unlist(indices, use.names = FALSE), ]
Verificar la estratificación apropiada.
> table(subsampd$group)
1.0 2.0 3.0 4.0 5.0 1.1 2.1 3.1 4.1 5.1
30 30 30 30 30 30 30 30 30 30
Tengo un marco de datos en el formato:
head(subset)
# ants 0 1 1 0 1
# age 1 2 2 1 3
# lc 1 1 0 1 0
Necesito crear un nuevo marco de datos con muestras aleatorias de acuerdo con la edad y el lc. Por ejemplo, quiero 30 muestras de la edad: 1 y lc: 1, 30 muestras de la edad: 1 y lc: 0 etc.
Me fijé en el método de muestreo aleatorio como;
newdata <- function(subset, age, 30)
Pero no es el código que quiero.
Aquí hay algunos datos:
set.seed(1)
n <- 1e4
d <- data.frame(age = sample(1:5,n,TRUE),
lc = rbinom(n,1,.5),
ants = rbinom(n,1,.7))
Desea una estrategia de dividir-aplicar-combinar, en la que split
su data.frame ( d
en este ejemplo), muestras de filas / observaciones de cada submuestra y luego las combina y luego las une de nuevo con rbind
. Así es como funciona:
sp <- split(d, list(d$age, d$lc))
samples <- lapply(sp, function(x) x[sample(1:nrow(x), 30, FALSE),])
out <- do.call(rbind, samples)
El resultado:
> str(out)
''data.frame'': 300 obs. of 3 variables:
$ age : int 1 1 1 1 1 1 1 1 1 1 ...
$ lc : int 0 0 0 0 0 0 0 0 0 0 ...
$ ants: int 1 1 0 1 1 1 1 1 1 1 ...
> head(out)
age lc ants
1.0.2242 1 0 1
1.0.4417 1 0 1
1.0.389 1 0 0
1.0.4578 1 0 1
1.0.8170 1 0 1
1.0.5606 1 0 1
Ver la función strata
del paquete de sampling . La función selecciona muestreo aleatorio simple estratificado y da una muestra como resultado. Se agregan dos columnas adicionales: probabilidades de inclusión ( Prob
) e indicador de estratos ( Stratum
). Vea el ejemplo.
require(data.table)
require(sampling)
set.seed(1)
n <- 1e4
d <- data.table(age = sample(1:5, n, T),
lc = rbinom(n, 1 , .5),
ants = rbinom(n, 1, .7))
# Sort
setkey(d, age, lc)
# Population size by strata
d[, .N, keyby = list(age, lc)]
# age lc N
# 1: 1 0 1010
# 2: 1 1 1002
# 3: 2 0 993
# 4: 2 1 1026
# 5: 3 0 1021
# 6: 3 1 982
# 7: 4 0 958
# 8: 4 1 940
# 9: 5 0 1012
# 10: 5 1 1056
# Select sample
set.seed(2)
s <- data.table(strata(d, c("age", "lc"), rep(30, 10), "srswor"))
# Sample size by strata
s[, .N, keyby = list(age, lc)]
# age lc N
# 1: 1 0 30
# 2: 1 1 30
# 3: 2 0 30
# 4: 2 1 30
# 5: 3 0 30
# 6: 3 1 30
# 7: 4 0 30
# 8: 4 1 30
# 9: 5 0 30
# 10: 5 1 30
Yo sugeriría usar stratified
de mi paquete "splitstackshape", o sample_n
del paquete "dplyr":
## Sample data
set.seed(1)
n <- 1e4
d <- data.table(age = sample(1:5, n, T),
lc = rbinom(n, 1 , .5),
ants = rbinom(n, 1, .7))
# table(d$age, d$lc)
Para stratified
, básicamente especifica el conjunto de datos, las columnas de estratificación y un entero que representa el tamaño que desea de cada grupo O un decimal que representa la fracción que desea devolver (por ejemplo, .1 representa el 10% de cada grupo).
library(splitstackshape)
set.seed(1)
out <- stratified(d, c("age", "lc"), 30)
head(out)
# age lc ants
# 1: 1 0 1
# 2: 1 0 0
# 3: 1 0 1
# 4: 1 0 1
# 5: 1 0 0
# 6: 1 0 1
table(out$age, out$lc)
#
# 0 1
# 1 30 30
# 2 30 30
# 3 30 30
# 4 30 30
# 5 30 30
Para sample_n
, primero crea una tabla agrupada (usando group_by
) y luego especifica el número de observaciones que desea. Si en su lugar deseaba un muestreo proporcional, debe usar sample_frac
.
library(dplyr)
set.seed(1)
out2 <- d %>%
group_by(age, lc) %>%
sample_n(30)
# table(out2$age, out2$lc)