Subset en R

Manipulación de datos con R Transformación de datos
Crea subconjuntos de datos en R

Hacer un subset en R consiste en obtener una submuestra de los datos originales, con el fin de obtener elementos específicos basados en alguna condición lógica.

En este tutorial aprenderás en detalle a utilizar crear subconjuntos de datos a través de los distintos métodos y mediante la función subset de R para filtrar datos.

¿Cómo hacer un subset en R?

Crear subconjuntos de datos en R se puede lograr de diferentes maneras, dependiendo de los datos con los que estés trabajando. En general, puedes crear un subconjunto:

  1. Usando corchetes ([] o [[]]).
  2. Usando el signo de dólar ($ ) si los elementos del objeto tienen nombres.
  3. Con funciones, como el comando subset, para obtener subconjuntos basados en condiciones lógicas.

Corchetes simples y dobles en R

Antes de las explicaciones para cada caso, cabe mencionar la diferencia entre usar corchetes simples y dobles a la hora de obtener un subconjunto de datos en R. Supongamos que tienes el siguiente vector numérico:

x <- c(uno = 1, dos = 2)

Como explicaremos con más detalle en la sección correspondiente, puedes acceder al primer elemento del vector usando corchetes simples o dobles y especificando el índice del elemento.

La diferencia es que los corchetes simples mantendrán la estructura original del input, mientras que los dobles la simplificarán tanto como sea posible. Esto se puede ilustrar con el siguiente ejemplo:

# Corchetes simples
x[1]
uno       # <-- Conserva el nombre del elemento
 1
# Corchetes dobles
x[[1]]
1         # <-- Se simplifica el output

Otra característica interesante se produce cuando intentas acceder a observaciones fuera de los límites del vector. En este caso, si usas corchetes simples, obtendrás un NA, mientras que obtendrás un error si usas corchetes dobles.

# Corchetes simples
x[6]
<NA> 
  NA 
# Corchetes dobles
x[[6]]
Error en x[[6]] : subíndice fuera de límites

Sin embargo, en algunas ocasiones no es posible usar corchetes dobles, como sucede con data frames y matrices en varios casos, tal y como se señalará en sus correspondientes secciones.

Ten en cuenta que si el subconjunto no devuelve observaciones significa que estás tratando de crear un subconjunto bajo alguna condición que nunca se cumple.

La función subset

La función subset permite obtener subconjuntos de datos en R en base a ciertas condiciones lógicas para objetos de tipo vector, matrices y data frames.

# Para vectores
subset(x,             # Vector numérico
       condition)     # Condición/es lógica/s

# Para matrices y data frames
subset(x,             # Vector numérico
       condition,     # Condición/es lógica/s
       select,        # Columnas seleccionadas
       drop = FALSE)  # Si se debe mantener la estructura del objeto (predeterminado) o no

En las siguientes secciones se utilizará esta función y los operadores para la mayoría de los ejemplos. Cabe destacar que esta función permite hacer un subset en R con una o múltiples condiciones.

Subset de un vector en R

Se puede crear un subset en R de un vector de varias formas:

  1. Especificando entre corchetes los índices que quieres obtener. Si quieres más de uno, selecciónalos utilizando la función c.
  2. Usando índices booleanos para indicar si se debe seleccionar un valor (TRUE) o no (FALSE).
  3. Utilizando operadores lógicos con la función subset.
  4. Si quieres seleccionar todos los valores, excepto uno o algunos, crea un subconjunto e indica el índice con signo negativo.

A continuación se resumen las formas de crear subconjuntos de vectores en R con varios ejemplos.

mi_vector <- c(15, 21, 17, 25, 12, 51)
# Devuelve todo el vector
mi_vector[]

# Tercer valor
mi_vector[3]

# Tercer valor, simplificando el output
mi_vector[[3]]

# Elementos del 1 al 3
mi_vector[1:3]

# Segundo y quinto componente
mi_vector[c(2, 5)]

# Segundo elemento, dos veces
mi_vector[c(2, 2)]

# Todos los valores excepto el cuarto
mi_vector[-4]

# Todos los valores excepto del cuarto y el quinto
mi_vector[-c(4, 5)]
mi_vector[c(-4, -5)] # Equivalente

# Primer, tercer, cuarto y sexto elemento
mi_vector[c(TRUE, FALSE, TRUE, TRUE, FALSE, TRUE)]

# Componentes mayores que 15
mi_vector[mi_vector > 15]

# Con la función subset
subset(mi_vector, mi_vector > 15)

mi_vector[] es útil cuando quieres asignar el mismo valor a todos los elementos de un vector ya creado. Por ejemplo, mi_vector[] <- 1 reemplazará todos los valores del vector con 1, mientra que mi_vector <- 1 sobreescribirá el vector como un único número.

Además, si se nombran los elementos del vector, puedes usar las formas anteriores y las siguientes para hacer un subset, especificando el nombre de los elementos como caracter.

mi_vector_nombres <- setNames(mi_vector, letters[2:7])
# Elemento "b"
mi_vector_nombres["b"]

# Elemento "b", simplificado
mi_vector_nombres[["b"]]

# Elementos "d" y "f"
mi_vector_nombres[c("d", "f")]

Recuerda que los vectores pueden ser de cualquier tipo de dato.

Subset de una lista en R

Considera la siguiente lista de ejemplo:

mi_lista <- list(1:10, c(TRUE, FALSE), 1)

Puedes crear un subconjunto de los elementos de una lista con corchetes simples y dobles para crear subconjuntos de los elementos o sub elementos de la lista.

# Segundo objeto de la lista
mi_lista[2]

# Segundo objeto de la lista, simplificado
mi_lista[[2]]

# Primer elemento del segundo objeto simplificado
mi_lista[[2]][1]

# Primer elemento del segundo objeto. Ambos simplificados
mi_lista[[2]][[1]]

En caso de que tengas una lista con nombres, puedes acceder a ellos especificando el nombre del elemento o accediendo a ellos con el signo del dólar.

mi_lista_nombres <- list(x = 1:10, y = c(TRUE, FALSE), z = 1)
# Primer elemento
mi_lista_nombres["x"]
mi_lista_nombres$x # Equivalente

# Segundo elemento, simplificado
mi_lista_nombres[["y"]]

Por otra parte, también es posible obtener subconjuntos condicionales con elementos de listas. Por ejemplo, podrías sustituir el primer elemento de la lista por un subconjunto de la misma de la siguiente forma:

mi_lista[[1]] <- subset(mi_lista[[1]], mi_lista[[1]] > 5)
mi_lista
[[1]]
[1]  6  7  8  9 10

[[2]]
[1]  TRUE FALSE

[[3]]
[1] 1

Subset en R de un data frame

Hacer un subset con un data frame consiste en obtener algunas filas o columnas de todo el data frame o algunas que cumplan con una o varias condiciones. Es muy habitual hacer un subset en R con este tipo de estructura para posteriormente analizar los datos. Considera el siguiente data frame de muestra:

set.seed(24)
mi_df <- data.frame(x = 1:10,
                    y = 11:20,
                    z = 3:12,
                    w = sample(c("Grupo 1", "Grupo 2"), 10, replace = TRUE))
head(mi_df)
x   y  z    w
1  11  3  Grupo 1
2  12  4  Grupo 1
3  13  5  Grupo 2
4  14  6  Grupo 2
5  15  7  Grupo 2
6  16  8  Grupo 2

Filtrar columnas

Puedes hacer un subset por columnas en R de diferentes maneras:

  1. Si quieres solo una columna, puedes usar corchetes simples o dobles para especificar el índice o el nombre (entre comillas) de la columna.
  2. Especificando los índices después de una coma (dejar el primer argumento en blanco selecciona todas las columnas del data frame). En este caso no podrías usar corchetes dobles, pero sí el argumento drop.
  3. En caso de crear un subconjunto con múltiples columnas de un data frame, simplemente indica las columnas dentro de un vector.

El siguiente bloque de código muestra varios ejemplos:

# Primera columna (simplificada como vector)
mi_df[[1]]
mi_df[, 1]   # Equivalente
mi_df[["x"]] # Equivalente
mi_df[, c(TRUE, FALSE, FALSE, FALSE)] # Equivalente

# Primera columna (con nombre de la columna y de las filas)
mi_df[1]
mi_df[, 1, drop = FALSE] # Equivalente
mi_df["x"]               # Equivalente
mi_df[c(TRUE, FALSE, FALSE, FALSE)] # Equivalente

# Segunda y tercera columna
mi_df[c(2, 3)]
mi_df[, c(2, 3)]   # Equivalente
mi_df[c("y", "z")] # Equivalente
mi_df[c(FALSE, TRUE, TRUE, FALSE)] # Equivalente

Cuando se crea un subconjunto con más de una columna o al especificar filas y columnas (usando una coma), deberás establecer drop = FALSE para mantener la estructura original del objeto, en lugar de usar corchetes dobles.

Filtrar un data frame en función del nombre de las columnas

Un subconjunto de columnas de un data frame también se puede lograr con el signo de dólar ($), especificando el nombre de la columna con o sin comillas.

# Primera columna
mi_df$x

# Segunda columna
mi_df$y
mi_df$"y" # Equivalente

Filtrar un data frame según el valor de las variables

También se puede crear un subconjunto de un data frame dependiendo de los valores de las columnas. Como ejemplo, es posible que quieras hacer un subconjunto con todos los valores del data frame donde el valor correspondiente de la columna z sea mayor que 5, o donde el grupo de la columna w sea el Grupo 1.

# Valores donde la columna z es mayor que 5
mi_df[mi_df$z > 5, ]

# Todos los valores correspondientes al Grupo 1
mi_df[mi_df$w == "Grupo 1", ]

Ten en cuenta que para crear un subconjunto de un data frame por el valor de una columna, debes especificar la condición en el primer argumento, ya que la salida será un subconjunto de filas.

Asimismo, puedes crear un subconjunto basado en una condición según los valores de las columnas con la función subset, tal y como se muestra a continuación. Ten en cuenta que al usar esta función puedes usar los nombres de las variables directamente.

# Todos los valores correspondientes al Grupo 1
subset(mi_df, w == "Grupo 1")
  x   y   z    w
  1  11   3  Grupo 1
  2  12   4  Grupo 1
  7  17   9  Grupo 1
 10  20  12  Grupo 1
# Todos los valores donde 'y' es menor o igual a 14
subset(mi_df, y <= 14)
 x   y  z     w
 1  11  3  Grupo 1
 2  12  4  Grupo 1
 3  13  5  Grupo 2
 4  14  6  Grupo 2

Al usar la función subset con un data frame puedes especificar las columnas que quieres que se devuelvan, indicándolas en el argumento select.

# Seleccionando las columnas que queremos devolver
subset(mi_df, x > 3, select = c(x, w))
  x    w
  4  Grupo 2
  5  Grupo 2
  6  Grupo 2
  7  Grupo 1
  8  Grupo 2
  9  Grupo 2
 10  Grupo 1

Además, puedes usar múltiples condiciones a la vez para crear un subconjunto. Crear un subcojunto basado en múltiples condiciones es tan fácil como crear un subconjunto con una sola condición. En el siguiente ejemplo seleccionamos los valores de la columna x donde el valor es 1 o donde es igual a 6.

mi_df[mi_df$x == 1 | mi_df$x == 6, ]
x   y  z
1  11  3
6  16  8

Subconjunto de filas en R

De manera análoga a crear subconjuntos de columnas, puedes hacer un subset de filas de un data frame indicando los índices de las filas que quieres como primer argumento dentro de los corchetes.

# Primera fila
mi_df[1, ]

# Cuarta y sexta fila
mi_df[c(4, 6), ]

Subconjunto de filas en base a un vector

Para crear un subconjunto de filas de un data frame en función de un vector puedes usar el operador %in% o la función is.element de la siguiente manera:

valores <- c(12, 14)

mi_df[mi_df$y %in% valores, ]
mi_df[is.element(mi_df$y, valores), ] # Equivalente
 x   y  z    w
 2  12  4  Grupo 1
 4  14  6  Grupo 2

Puedes hacer el opuesto de %in% creando un nuevo operador con '%ni%' <- Negate('%in%') o escribiendo mi_df[!(mi_df$y %in% valores), ].

Subconjunto en base a fechas

En determinadas ocasiones los data frames tienen una columna de fechas. En este caso, cada fila representa una fecha y cada columna un evento registrado en esas fechas. Para este propósito, necesitas transformar esa columna de fechas con la función as.Date para convertir la columna en formato fecha.

fechas <- seq(as.Date("2011/1/1"), by = "day", length.out = 10)

mi_df_fechas <- cbind(fechas, mi_df)
head(mi_df_fechas)
  fechas    x   y  z     w
2011-01-01  1  11  3  Grupo 1
2011-01-02  2  12  4  Grupo 1
2011-01-03  3  13  5  Grupo 2
2011-01-04  4  14  6  Grupo 2
2011-01-05  5  15  7  Grupo 2
2011-01-06  6  16  8  Grupo 2

Como ejemplo, puedes crear un subconjunto de los valores correspondientes a fechas superiores al 5 de enero de 2011 con el siguiente código:

subset(mi_df_fechas, fechas > as.Date("2011-01-5"))
  fechas     x   y   z    w
2011-01-06   6  16   8  Grupo 2
2011-01-07   7  17   9  Grupo 1
2011-01-08   8  18  10  Grupo 2
2011-01-09   9  19  11  Grupo 2
2011-01-10  10  20  12  Grupo 1

Subconjunto de fecha única

En caso de que tu columna de fechas contenga la misma fecha varias veces y desees seleccionar todas las filas que contienen esa fecha, puedes usar el operador lógico == junto con la función subset de la siguiente manera:

subset(mi_df_fechas, fechas == as.Date("2011-01-02"))

Subconjuntos de matrices en R

Obtener subconjuntos de una matriz en R es muy similar al proceso con data frames. Considera la siguiente matriz de ejemplo:

set.seed(45)

mi_matriz <- matrix(sample(1:9), ncol = 3)
colnames(mi_matriz) <- c("uno", "dos", "tres")
mi_matriz
       uno  dos tres
[1, ]   6    8    1
[2, ]   3    7    4
[3, ]   2    5    9

Puedes seleccionar las filas y columnas especificando los índices de filas y luego de las columnas. También puedes usar el tipo de datos booleano para determinar si se debe seleccionar una determinada fila o columna o no.

# Filtrando con índices de filas y columnas
mi_matriz[c(1, 3), c(1, 2)]

# Filtrando con valores lógicos
mi_matriz[c(TRUE, FALSE, TRUE), c(TRUE, TRUE, FALSE)] # Equivalente

# Si lo prefieres, puedes mezclar
mi_matriz[c(1, 3), c(TRUE, TRUE, FALSE)] # Equivalente
      uno dos
[1, ]  6   8
[2, ]  2   5

Cabe destacar que si te quedas con una sola fila o columna, el resultado será de tipo vector. Para preservar la clase original de la matriz, puedes establecer el argumento drop como FALSE.

mi_matriz[, 2] # 8 7 5
 8 7 5
mi_matriz[, 2, drop = FALSE]
      dos
[1, ]  8
[2, ]  7
[3, ]  5

Filtrar matriz por nombres de filas y columnas

En caso de que tu matriz tenga nombres de fila o columna, puedes usarlos en lugar del índice para hacer un subset de la matriz. En el siguiente ejemplo, seleccionamos las columnas llamadas ‘dos’ y ‘tres’.

mi_matriz[, c("dos", "tres")]
       dos   tres
[1, ]   8     1
[2, ]   7     4
[3, ]   5     9

Subconjuntos de matrices según valores

De manera equivalente a los data frames, puedes crear subsets de una matriz según los valores de las columnas. En el siguiente ejemplo estamos creando un subconjunto basado en una condición sobre los valores de la tercera columna.

mi_matriz[mi_matriz[, 3] > 2, ]
     uno  dos  tres
[1,]  3    7    4
[2,]  2    5    9

Subconjunto de series temporales

Las series de tiempo o series temporales son un tipo de objeto con el que se pueden crear subconjuntos de datos basados en fechas. Para mostrar un ejemplo usaremos la serie temporal nottem.

nottem

class(nottem) # ts

La función window es la que nos permite crear subconjuntos de series temporales, como se muestra en el siguiente ejemplo:

# Datos a partir de 1930 (incluido)
window(nottem, start = c(1930))

# Datos a partir de abril de 1930 (incluido)
window(nottem, start = c(1930, 4))