Tengo el siguiente marco de datos con 1,000 filas; 10 ciudades, cada una con 100 filas y me gustaría seleccionar aleatoriamente 10 nombres por año en la ciudad y el seleccionado si los 10 nombres de muestra deben provenir de al menos uno de los años en la ciudad, es decir, los 10 nombres para la ciudad 1 no deben aparecer desde 1996, por ejemplo.

       City Year   name   
1       1   1996   b
2       1   1996   c
3       1   1997   d
4       1   1997   e 
...
101     2   1996   f
102     2   1996   g
103     2   1997   h
104     2   1997   i

Datos de muestra final deseados

       City Year   name   
1       1   1996   b
2       1   1998   c
3       1   2001   d
...
11      2   1997   g
12      2   1999   h
13      2   2005   b
...
21      3   1998   a
22      3   2010   c
23      3   2005   d

Data de muestra

df1 <- data.frame(City = rep(1:10, each = 100), 
                  Year = rep(1996:2015, each = 5), 
                  name = rep(letters[1:25], 40))

No selecciono aleatoriamente los 10 nombres de muestra por año (sin repetir años, a menos que el número de años en una ciudad sea inferior a 10) para las 10 ciudades, ¿cómo puedo repasar esto?

La muestra final debe tener 10 nombres de cada ciudad y los años no deben repetirse a menos que sean menos de 10 en esa ciudad.

Gracias.

1
Samuel Onyango 1 sep. 2020 a las 13:56

1 respuesta

La mejor respuesta

Primero agrupe por City y use sample_n para muestrear un sub-marco de datos.
Luego, agrupe por City y Year, y sample de name un elemento por grupo. No olvide configurar la semilla RNG para que el resultado sea reproducible.

library(dplyr)

set.seed(2020)

df1 %>%
  group_by(City) %>%
  sample_n(min(n(), 10)) %>%
  ungroup() %>%
  group_by(City, Year) %>%
  summarise(name = sample(name, 1))
#`summarise()` regrouping output by 'City' (override with `.groups` argument)
## A tibble: 4 x 3
## Groups:   City [2]
#   City  Year name 
#  <int> <int> <chr>
#1     1  1996 b    
#2     1  1997 e    
#3     2  1996 f    
#4     2  1997 h  

Datos

df1 <- read.table(text = "
       City Year   name   
1       1   1996   b
2       1   1996   c
3       1   1997   d
4       1   1997   e 
101     2   1996   f
102     2   1996   g
103     2   1997   h
104     2   1997   i
", header = TRUE)

Editar

En lugar de reinventar la rueda, use el paquete sampling, función strata para obtener un índice en el conjunto de datos y luego filter sus filas correspondientes.

library(dplyr)
library(sampling)

set.seed(2020)

df1 %>%
  mutate(row = row_number()) %>%
  filter(row %in% strata(df1, stratanames = c('City', 'Year'), size = rep(1, 1000), method = 'srswor')$ID_unit) %>%
  select(-row) %>%
  group_by(City) %>%
  sample_n(10) %>%
  arrange(City, Year)
1
Rui Barradas 1 sep. 2020 a las 15:35