Muestrear data frames contenidos dentro de una lista en R

Si tenemos una lista que contiene varios data frames, podemos tomar una muestra de un número determinado de filas de un modo iterativo. Pero antes de comenzar, generemos una lista con varios data frames siguiendo lo descrito en la entrada sobre filtrar todos los factores de una variable. De este modo, podremos muestrear data frames contenidos de una lista en R.

data(iris) # Cargamos los datostendréis que saber cómo muestrear teniendo en cuenta variables factoriales

# Generamos la lista con 3 data frames
especies <- split(iris, iris$Species)
str(especies)
List of 3
 $ setosa    :'data.frame':  50 obs. of  5 variables:
  ..$ Sepal.Length: num [1:50] 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
  ..$ Sepal.Width : num [1:50] 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
  ..$ Petal.Length: num [1:50] 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
  ..$ Petal.Width : num [1:50] 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
  ..$ Species     : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
 $ versicolor:'data.frame':  50 obs. of  5 variables:
  ..$ Sepal.Length: num [1:50] 7 6.4 6.9 5.5 6.5 5.7 6.3 4.9 6.6 5.2 ...
  ..$ Sepal.Width : num [1:50] 3.2 3.2 3.1 2.3 2.8 2.8 3.3 2.4 2.9 2.7 ...
  ..$ Petal.Length: num [1:50] 4.7 4.5 4.9 4 4.6 4.5 4.7 3.3 4.6 3.9 ...
  ..$ Petal.Width : num [1:50] 1.4 1.5 1.5 1.3 1.5 1.3 1.6 1 1.3 1.4 ...
  ..$ Species     : Factor w/ 3 levels "setosa","versicolor",..: 2 2 2 2 2 2 2 2 2 2 ...
 $ virginica :'data.frame':  50 obs. of  5 variables:
  ..$ Sepal.Length: num [1:50] 6.3 5.8 7.1 6.3 6.5 7.6 4.9 7.3 6.7 7.2 ...
  ..$ Sepal.Width : num [1:50] 3.3 2.7 3 2.9 3 3 2.5 2.9 2.5 3.6 ...
  ..$ Petal.Length: num [1:50] 6 5.1 5.9 5.6 5.8 6.6 4.5 6.3 5.8 6.1 ...
  ..$ Petal.Width : num [1:50] 2.5 1.9 2.1 1.8 2.2 2.1 1.7 1.8 1.8 2.5 ...
  ..$ Species     : Factor w/ 3 levels "setosa","versicolor",..: 3 3 3 3 3 3 3 3 3 3 ...

Como podemos ver, se trata de una lista con 3 data frames, cada uno correspondiéndose con una especie distinta, y cada uno compuesto por 50 observaciones o filas.

Si lo que queréis es seleccionar aleatoriamente las flores teniendo en cuenta el tipo de especie, tendréis que saber cómo muestrear teniendo en cuenta variables factoriales.

Muestrear data frames contenidos dentro de una lista

Volviendo a lo que nos atañe, queremos seleccionar aleatoriamente el 80% de las filas en cada uno de los data frames. Para ello empleamos la función lapply(), que permite aplicar una función a todos los objetos de una lista. La función que queremos aplicar aquí es sample().

Creamos una función

Pero para optimizar el código, vamos a generar una función que llamaremos muestra(), y que contendrá en su interior la función sample(). Esta función nos devolverá el 80% de las filas de un data frame, seleccionadas aleatoriamente y sin repetición. Si queréis más detalles sobre esta función os recomendamos leer esta entrada.

muestra <- function(x) {
  x[sample(1:nrow(x), round(0.8*nrow(x)), replace = F),]
}

Ejecutamos lapply() con la función creada

Ahora es cuando vamos a aplicar lapply(). En esta función indicamos primero el nombre del objeto que contiene la lista (especies), seguido del nombre de la función a aplicar sobre cada elemento de esa lista (la función que creamos antes llamada muestra).

especies_muestra <- lapply(especies, muestra)
str(especies_muestra)
List of 3
 $ setosa    :'data.frame':  40 obs. of  5 variables:
  ..$ Sepal.Length: num [1:40] 5.1 5.1 5.7 5.1 5.5 5 5.1 4.7 4.6 5 ...
  ..$ Sepal.Width : num [1:40] 3.5 3.8 3.8 3.7 4.2 3.4 3.3 3.2 3.4 3.4 ...
  ..$ Petal.Length: num [1:40] 1.4 1.6 1.7 1.5 1.4 1.5 1.7 1.6 1.4 1.6 ...
  ..$ Petal.Width : num [1:40] 0.2 0.2 0.3 0.4 0.2 0.2 0.5 0.2 0.3 0.4 ...
  ..$ Species     : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
 $ versicolor:'data.frame':  40 obs. of  5 variables:
  ..$ Sepal.Length: num [1:40] 6 5.4 5.7 6.4 6.2 6.3 5.7 5.6 5.6 6.1 ...
  ..$ Sepal.Width : num [1:40] 2.9 3 3 3.2 2.2 2.5 2.9 3 2.9 2.8 ...
  ..$ Petal.Length: num [1:40] 4.5 4.5 4.2 4.5 4.5 4.9 4.2 4.1 3.6 4.7 ...
  ..$ Petal.Width : num [1:40] 1.5 1.5 1.2 1.5 1.5 1.5 1.3 1.3 1.3 1.2 ...
  ..$ Species     : Factor w/ 3 levels "setosa","versicolor",..: 2 2 2 2 2 2 2 2 2 2 ...
 $ virginica :'data.frame':  40 obs. of  5 variables:
  ..$ Sepal.Length: num [1:40] 6.5 6.4 7.1 7.3 7.7 6.1 6.9 6.4 6.9 6.7 ...
  ..$ Sepal.Width : num [1:40] 3 3.1 3 2.9 2.8 3 3.1 2.8 3.1 2.5 ...
  ..$ Petal.Length: num [1:40] 5.8 5.5 5.9 6.3 6.7 4.9 5.4 5.6 5.1 5.8 ...
  ..$ Petal.Width : num [1:40] 2.2 1.8 2.1 1.8 2 1.8 2.1 2.1 2.3 1.8 ...
  ..$ Species     : Factor w/ 3 levels "setosa","versicolor",..: 3 3 3 3 3 3 3 3 3 3 ...

Como podemos observar, el 80% de 50 observaciones se corresponde con 40. Y es precisamente ese el número de filas en cada uno de los data frames contenidos dentro de especies_muestra.

1 comentario en “Muestrear data frames contenidos dentro de una lista en R”

Deja un comentario