Estructuras de datos en R

En R como en cualquier otro lenguaje existen diversas estructuras de Datos, pero a diferencia de otros lenguajes en R la estructura básica son los vectores. Incluso los números y las cadenas de texto se de hecho vectores de un solo elemento. En este artículo explicaré algunas estructuras de datos y como manipularlas.

Visión general

Estas son las estructuras de datos en R:

  • Vectores. La estructura más simple, un arreglo cuyas entradas son todas del mismo tipo
  • Matrices. Son vectores bidimensionales
  • Arreglos. Vectores multidimensionales
  • Data Frames. En términos generales son matrices que permiten almacenar datos de diferentes tipos. Son la estructura de datos que más se usa en R.
  • Listas. Son la estructura de datos más abstracta y flexible. Se puede guardar prácticamente cualquier cosa dentro de una lista, incluidas funciones.
  • Factores. Estructuras categóricas, en cierto sentido son conjuntos que permiten tener elementos repetidos.

Vectores

Los vectores son conjuntos ordenados, es decir a cada elemento le corresponde un índice; y todos sus elementos son del mismo tipo (enteros, flotantes, cadenas de texto, etc). Para crear un vector se usa el comando c( ) y entre paréntesis se ingresan los elementos como una lista separada por comas. Para que sea fácil recordar el comando lo que éste hace es concatenar los elementos.

> v1 <- c(1, 4, 5, -8, 2)
> print(v1)
[1]  1  4  5 -8  2
> v2 <- c(1, 4, 5, -8, 2 + 3i)
> print(v2)
[1]  1+0i  4+0i  5+0i -8+0i  2+3i
> v3 <- c(1, 2, 'a', 'b', 'c')
> print(v3)
[1] "1" "2" "a" "b" "c"

Hay formas alternativas para crear listas automáticamente:

> v4 <- 1:7
> print(v4)
[1] 1 2 3 4 5 6 7
> v5 <- seq(-20, 20, 10)
> print(v5)
[1] -20 -10   0  10  20
> v6 <- rep(c('a', 'b'), 3)
> print(v6)
[1] "a" "b" "a" "b" "a" "b"
  • El comando 1:7 crea una lista de números consecutivos entre el uno y el 7.
  • Para crear una sucesión (sequence) de números se usa seq( ) que toma como argumentos el primer elemento, el último elemento y la distancia entre elementos consecutivos.
  • El último ejemplo rep repite el primer argumento (el vector 'a', 'b') tantas veces como lo indique el segundo argumento.

Tal como en Python o Matlab/Octave uno puede acceder a subconjuntos de un vector por medio de índices:

> v1 <- c("ratas", "latas", "orchatas", "piñatas", "cataratas")
> print(v1[3])
[1] "orchatas"
> print(v1[2:4])
[1] "latas"     "orchatas"  "piñatas"

En entradas posteriores hablaré un poco más sobre como filtrar y seleccionar subconjuntos de datos en un vector y en un dataframe. Este tema es súmamente importante, es una de las tareas más comunes cuando se maneja mucha información.

Otra característica de los vectores es que se puede asignar un nombre a cada entrada y acceder a esos elementos con la misma sintaxis que cuando se usa un índice. Veamos:

> info <- c("nombre" = "Geri", "oficio" = "Blogero", "edad" = "Desconocida")
> info["nombre"]
nombre
"Geri"

> info[c("nombre", "edad")]
       nombre          edad
       "Geri" "Desconocida"

Matrices

Las matrices son esencialmente vectores bidimensionales. La sintaxis más simple para crear una matriz es crear un vector con todos los elementos y luego indicarle al comando cuantos renglones y columnas tendrá la matriz.

> m1 <- matrix(1:12, nrow = 3, ncol = 4)
> print(m1)
     [,1] [,2] [,3] [,4]
     [1,]    1    4    7   10
     [2,]    2    5    8   11
     [3,]    3    6    9   12

También es posible pegar varios renglones juntos con rbind( ):

> v1 <- c('primis', 'segus', 'terce')
> v2 <- c('primero', 'segundo', 'tercero')
> v3 <- c('uno', 'dos', 'tres')
> m1 <- rbind(v1, v2, v3)

     > print(m1)
        [,1]      [,2]      [,3]
     v1 "primis"  "segus"   "terce"
     v2 "primero" "segundo" "tercero"
     v3 "uno"     "dos"     "tres"

o pegar varias columnas juntas con cbind( ):

> m2 <- cbind(v1, v2, v3)
> print(m2)
     v1       v2        v3
[1,] "primis" "primero" "uno"
[2,] "segus"  "segundo" "dos"
[3,] "terce"  "tercero" "tres"

Es posible acceder a renglones, columnas, elementos y subconjuntos de datos en una matriz por medio de sus índices.

> print(m1)
   [,1]      [,2]      [,3]
v1 "primis"  "segus"   "terce"
v2 "primero" "segundo" "tercero"
v3 "uno"     "dos"     "tres"

> print(m1[2,3])
       v2
"tercero"

> print(m1[2,])
[1] "primero" "segundo" "tercero"

> print(m1[,3])
       v1        v2        v3
  "terce" "tercero"    "tres"

> print(m1[2:3, 1:2])
   [,1]      [,2]
v2 "primero" "segundo"
v3 "uno"     "dos"

Arreglos

Los Arreglos son vectores multidimencionales, de los cuáles las matrices son un caso particular. La sintaxis para crear arreglos es similar a la de las matrices, se usa el comando array() y dos argumentos: un vector con los datos y un vector con el tamaño del vector en cada dimensión.

> arr1 <- array(1:18, c(3, 2, 3))

> print(arr1);
, , 1

     [,1] [,2]
[1,]    1    4
[2,]    2    5
[3,]    3    6

, , 2

     [,1] [,2]
[1,]    7   10
[2,]    8   11
[3,]    9   12

, , 3

     [,1] [,2]
[1,]   13   16
[2,]   14   17
[3,]   15   18

Para acceder a elementos, columnas renglones o subconjuntos la sintaxis es la misma que con las matrices.

> print(arr1[, , 1])
     [,1] [,2]
[1,]    1    4
[2,]    2    5
[3,]    3    6

> print(arr1[, 1, 2])
[1] 7 8 9

> print(arr1[3, 1, 2])
[1] 9

Factores

Los factores son variables categóricas que permiten agrupar datos, algo muy común al momento de graficar información.

> f1 <- factor(c("si","no","si","talvez","talvez","no","talvez","no","no"))

> print(f1)
[1] si     no     yes    talvez talvez no     talvez no     no
Levels: no si talvez yes

Un caso común sería una encuesta donde las respuestas están guardadas en este formato y necesitamos cuantificarlas.

Otro característica de los factores es que se pueden ordenar arbitrariamente:

> f1 <- factor(c("si","no","si","talvez","talvez","no","talvez","no","no"), ordered = T,     labels = c('no', 'talvez', 'si'))
> print(f1)
[1] talvez no     talvez si     si     no     si     no     no
Levels: no < talvez < si

> print(table(f1))
f1
    no talvez     si
     4      2      3

La función table( ) imprime un resumen de los datos.

Datafames

Los dataframes son los objetos más comunes en R. Permiten manipular información en algo muy parecido a una tabla de datos.

> datos <- data.frame(nombres = c('Pedro', 'Juan', 'Alberto', 'Alejandro'),
+ edades = c(16, 17, 16, 15),
+ calificaciones = c(9.1, 8.2, 8.5, 9.9))

> print(datos)
    nombres edades calificaciones
1     Pedro     16            9.1
2      Juan     17            8.2
3   Alberto     16            8.5
4 Alejandro     15            9.9

Un comando adicional que vale la pena mencionar sobre dataframes es summary( ) que presenta un resumen (media, mediana, cuartiles, mínimo, máximo) sobre la información contenida en el dataframe:

> summary(datos)
      nombres      edades      calificaciones
 Alberto  :1   Min.   :15.00   Min.   :8.200
 Alejandro:1   1st Qu.:15.75   1st Qu.:8.425
 Juan     :1   Median :16.00   Median :8.800
 Pedro    :1   Mean   :16.00   Mean   :8.925
               3rd Qu.:16.25   3rd Qu.:9.300
               Max.   :17.00   Max.   :9.900

Dada la importancia de esta estructura puedes encontrar más información en este artículo sobre dataframes

Listas

Las listas funcionan igual que los vectores, pero se pueden incluir cualquier tipo de elementos en ellas. En el siguiente ejemplo vamos a guardar el dataframe de la sección anterior, una función y un número en el mismo contenedor:

> hola <- function() {return("hola mundo")}
> lista1 <- list(datos, hola, 35)
> typeof(lista1)
[1] "list"

> print(lista1)
[[1]]
    nombres edades calificaciones
1     Pedro     16            9.1
2      Juan     17            8.2
3   Alberto     16            8.5
4 Alejandro     15            9.9

[[2]]
function ()
{
    return("hola mundo")
}

[[3]]
[1] 35