Chapter 2 Programación básica en R

Introduction to R

2.1 Introducción a R

2.1.1 Operaciones aritméticas con R

El lenguaje de programación R puede funcionar como una calculadora, permitiéndonos realizar las operaciones aritméticas más básicas con valores numéricos:

  • Suma: +
  • Resta: -
  • Multiplicación *
  • División: /
  • Exponencia: ^
  • Módulo: %%. Esta operación devuelve el resto de una división. Por ejemplo, 5 %% 3 es igual a 2.
5 + 5 # suma 
## [1] 10
5 - 5 # resta
## [1] 0
3 * 5 # multiplicación
## [1] 15
(5 + 5) / 2 # división (previa suma)
## [1] 5
2^5 # exponencia
## [1] 32
28 %% 6 # resto de la división
## [1] 4

2.1.2 Asignación de variables

Un concepto básico en estadística se conoce como variable. Una variable te permite almacenar un valor o un objeto en R. Siempre se utiliza el símbolo <-.

var1 <- 5 # la variable var1 tiene el valor de 5
var2 <- 6 # la variable var2 tiene el valor de 6
var1 + var2 # suma las dos variables anteriores
## [1] 11
suma <- var1 + var2 # la variable "suma" representa la suma de var1 y var2
suma # muestra el valor de "suma"
## [1] 11

Fijáos que al generar una variable, al ejecutarse esa línea no da ningún resultado. Eso es porque R interpreta que utilizarás en un futuro esa variable y no la muestra en el momento.

2.1.3 Tipos de datos básicos en R

  • Reales. Son los números reales, con decimales y enteros. 4, 2.3, -10.2…
  • Enteros. Son los números sin decimales. También son reales. 5, 8, -4…
  • Lógicos. Son booleanos, habiendo dos opciones: TRUE y FALSE.
  • Texto. Son cadenas de caracteres, puesta entre comillas "".

2.1.4 Averiguar el tipo de dato con class()

Para averiguar el tipo de variable que estamos manejando, ejecutamos la función class().

class(integer(3))
## [1] "integer"
class(2.54)
## [1] "numeric"
class(TRUE)
## [1] "logical"
class("hola")
## [1] "character"

2.2 Vectores en R

Los vectores son objetos de una única dimensión que puede contener datos numéricos, cadena de caracteres o datos lógicos, entre otros.

2.2.1 Función c() y tipos de vectores

Los vectores se generan en R usando la función c(), que proviene de combine. Los elementos situados dentro del paréntesis tienen que estar separados por comas. Si son caracteres, hay que poner cada elemento entre comillas, y si son lógicos o booleanos hay que escribir TRUE y/o FALSE en mayúsculas y sin comillas. Igual pasa con los vectores numéricos, que no llevan comillas. Veamos estos tres tipos de vectores:

# Primero numérico, segundo de texto, tercero lógico / booleano
vector_numerico <- c(1, 3, 5, 7)
vector_texto <- c("a", "b", "c", "d")
vector_logico <- c(TRUE, FALSE, TRUE, TRUE)

2.2.2 Dar nombres a los elementos de un vector con la función names()

Vamos a dar nombre a cada elemento dentro de un vector. Para ello, usemos el siguiente ejemplo:

# Generamos un vector de 12 elementos llamado "orden_meses"
orden_meses <- c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)

# También podemos acortar el código anterior poniendo 1:12
orden_meses <- c(1:12)

# Vemos el vector
orden_meses
##  [1]  1  2  3  4  5  6  7  8  9 10 11 12

Para indicarle ahora que el 1 le corresponde el nombre de enero, y así sucesivamente hasta diciembre, utilizamos la función names(), indicando dentro del paréntesis el nombre del vector al que queremos dar nombres.

names(orden_meses) <- c("Ene", "Feb", "Mar", "Abr", "May", "Jun", "Jul", "Ago", "Sep", "Oct", "Nov", "Dic")

# Vemos nuevamente el vector "orden_meses"
orden_meses
## Ene Feb Mar Abr May Jun Jul Ago Sep Oct Nov Dic 
##   1   2   3   4   5   6   7   8   9  10  11  12
# Simplificando código, podemos crear un vector con los nombres de los meses...
meses <- c("Ene", "Feb", "Mar", "Abr", "May", "Jun", "Jul", "Ago", "Sep", "Oct", "Nov", "Dic")

#...y después ejecutar la función "names()"
names(orden_meses) <- meses

2.2.3 Operaciones aritméticas entre vectores

Realizar operaciones aritméticas (suma, resta, multiplicación y división) con vectores es muy sencillo. Para ello, vamos a crear dos vectores con el nombre Vector_1 y Vector_2.

Vector_1 <- c(1, 2, 3)
Vector_2 <- c(4, 5, 6)

Ahora vamos a realizar operaciones aritméticas entre estos dos vectores, incluyendo la suma, la resta, la multiplicación y la división. Es muy importante destacar que estas operaciones aritméticas se producen entre los valores situados en una misma posición dentro de los vectores respectivos. Es devir, el primer elemento del Vector_1 (1) se relaciona con el primer elemento del Vector_2 (4). Si fuese una suma, el resultado de esta primer elemento sería 5. Este proceso se repite sucesivamente con el resto de los elementos de los vectores.

Vector_1 + Vector_2 # suma de los dos vectores
## [1] 5 7 9
Vector_1 - Vector_2 # resta de los dos vectores
## [1] -3 -3 -3
Vector_1 / Vector_2 # división de los dos vectores
## [1] 0.25 0.40 0.50
Vector_1 * Vector_2 # multiplicación de los dos vectores
## [1]  4 10 18
# Generamos 4 vectores resultado de las operaciones aritméticas
suma_vectores <- Vector_1 + Vector_2
resta_vectores <- Vector_1 - Vector_2
division_vectores <- Vector_1 / Vector_2
multiplicacion_vectores <- Vector_1 * Vector_2
  
# Vemos los resultados
suma_vectores
## [1] 5 7 9
resta_vectores
## [1] -3 -3 -3
division_vectores
## [1] 0.25 0.40 0.50
multiplicacion_vectores
## [1]  4 10 18
# Comparamos si los valores de multiplicación son mayores que los de la suma
# Esto nos devuelve un resultado lógico por tantos elementos existan
multiplicacion_vectores > suma_vectores
## [1] FALSE  TRUE  TRUE

Es interesante destacar que el resultado de realizar operaciones aritméticas entre vectores nos devuelve un objeto que también es un vector.

2.2.4 Sumando los elementos de un vector con la función sum()

Si quisiéramos sumar todos los elementos situados dentro de un único vector, tendremos que usar la función sum().

# Vamos a sumar los 4 vectores obtenidos en el ejemplo anterior
sum(suma_vectores)
## [1] 21
sum(resta_vectores)
## [1] -9
sum(division_vectores)
## [1] 1.15
sum(multiplicacion_vectores)
## [1] 32

2.2.5 Seleccionar elementos de un vector

A diferencia de otros lenguajes de programación, como Python, en R el primer elemento lleva el valor de 1, y no de 0. Para seleccionar un elemento de un vector, tenemos que poner el nombre del vector más un corchete [] con la posición del elemento en cuestión.

Vector_1[2]       # seleccionamos el segundo elemento del Vector_1
## [1] 2
Vector_1[3]       # seleccionamos el tercer elemento del Vector_1
## [1] 3
Vector_2[1:2]     # seleccionamos el intervalo entre la posición 1 y 3 del Vector_2
## [1] 4 5
Vector_2[c(1, 3)] # seleccionamos el primer y el tercer elemento del Vector_2
## [1] 4 6

Podemos a su vez dar nombre a cada uno de las selecciones realizadas para recurrir a ellas en el futuro de un modo más rápido.

seleccion_1 <- Vector_1[2]      
seleccion_2 <- Vector_1[3]    
seleccion_3 <- Vector_2[1:2]    
seleccion_4 <- Vector_2[c(1, 3)]

2.2.5.1 Selección usando operadores de comparación

TEnemos que distinguir 6 tipos de operadores:

  • <. Menor que.
  • >. Mayor que.
  • <=. Menor o igual que.
  • >=. Mayor o igual que.
  • ==. Igual que.
  • !=. Distinto que.
# Vemos si los elementos de un vector son mayores que 20
c(15, 24, 21, 18) > 20
## [1] FALSE  TRUE  TRUE FALSE
# Si le llamamos al vector anterior como "horas", queremos ver cuáles están por debajo de 20
horas <- c(15, 24, 21, 18)
horas < 20
## [1]  TRUE FALSE FALSE  TRUE

Como vemos, el resultado de la selección vista nos devuelve un resultado lógico TRUE o FALSE. ¿Y si queremos ver sus valores?

horas <- c(15, 24, 21, 18) # mismo vector con las horas
horas_20 <- horas < 20     # llamamos a la selección de horas menores de 20 como "horas_20"
horas[horas_20]            # al vector original le seleccionamos los valores seleccionados "horas_20"
## [1] 15 18

Si damos nombre a cada uno de los elementos con otro vector, podemos seleccionarlo a través del nombre y no de la posición.

# Generamos un vector con nombre "dias" con los nombres de las posiciones
dias <- c("Lunes", "Martes", "Miércoles")

# Ejecutamos la función "names()" con el nombre del vector en paréntesis
names(Vector_1) <- dias

# Seleccionamos elementos del vector en base al nombre y no la posición.
Vector_1["Lunes"]
## Lunes 
##     1
Vector_1[c("Lunes", "Miércoles")]
##     Lunes Miércoles 
##         1         3

2.2.6 head() y tail() de un vector

Si tuviésemos un vector de una longitud considerable, nos interesaría ver solo los datos del comienzo con head() o del final con tail().

# Generamos un vector
vector <- c(2, 4, 3, 5, 6, 2, 3, 4, 1, 5, 3, 5, 2, 4)

# Vemos su cabecera y su final
head(vector) # te saca de modo predeterminado los 6 primeros valores
## [1] 2 4 3 5 6 2
tail(vector) # te saca de modo predeterminado los 6 últimos valores
## [1] 1 5 3 5 2 4
# Seleccionamos el número de elementos a mostrar
head(vector, 3) # nos saca los 3 primeros valores
## [1] 2 4 3
tail(vector, 4) # nos saca los 4 últimos valores
## [1] 3 5 2 4

2.3 Matrices en R

Una matriz en R es un conjunto de elementos del mismo tipo (numérico, carácter, lógico, etc) organizado en filas y columnas. En R, una matriz se construye con la función matrix(). Veamos un ejemplo a continuación:

matrix(1:25, byrow = TRUE, nrow = 5)
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    1    2    3    4    5
## [2,]    6    7    8    9   10
## [3,]   11   12   13   14   15
## [4,]   16   17   18   19   20
## [5,]   21   22   23   24   25

Como hemos visto, la función matrix() presenta 3 atributos principales:

  • 1:25 indica que se genere un vector de números del 1 al 25, de este modo c(1, 2, 3, ..., 22, 23, 24, 25)
  • byrow = TRUE indica que esos números se van a incorporar a la matriz de izquiera a derecha y de arriba a abajo.
  • nrow = 5 indica que van a formarse 5 filas.

Veamos qué pasa si ponemos byrow = FALSE:

matrix(1:25, byrow = FALSE, nrow = 5)
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    1    6   11   16   21
## [2,]    2    7   12   17   22
## [3,]    3    8   13   18   23
## [4,]    4    9   14   19   24
## [5,]    5   10   15   20   25

Vemos ahora que la matriz se ha rellenado con los datos de arriba a abajo y de izquierda a derecha.

Como tenemos 25 números, hemos decidido generar tantas filas y columnas para que esos 25 números estuvieran bien repartidos (5x5) ¿Qué pasa si ponemos un número de filas que no sea múltiplo de 25, por ejemplo 7?

matrix(1:25, byrow = FALSE, nrow = 7)
## Warning in matrix(1:25, byrow = FALSE, nrow = 7): data length [25] is not a
## sub-multiple or multiple of the number of rows [7]
##      [,1] [,2] [,3] [,4]
## [1,]    1    8   15   22
## [2,]    2    9   16   23
## [3,]    3   10   17   24
## [4,]    4   11   18   25
## [5,]    5   12   19    1
## [6,]    6   13   20    2
## [7,]    7   14   21    3

Pues que nos sale un mensaje de advertencia diciendo que 7 filas no genera una matriz de igual número de columnas que de filas. Si nos fijamos en detenimiento, en las filas 5, 6, 7 y en la columna 4, nos aparecen los números consecutivos 1, 2, 3.

matrix(1:25, byrow = FALSE)
##       [,1]
##  [1,]    1
##  [2,]    2
##  [3,]    3
##  [4,]    4
##  [5,]    5
##  [6,]    6
##  [7,]    7
##  [8,]    8
##  [9,]    9
## [10,]   10
## [11,]   11
## [12,]   12
## [13,]   13
## [14,]   14
## [15,]   15
## [16,]   16
## [17,]   17
## [18,]   18
## [19,]   19
## [20,]   20
## [21,]   21
## [22,]   22
## [23,]   23
## [24,]   24
## [25,]   25
matrix(1:25, byrow = FALSE, nrow = 25)
##       [,1]
##  [1,]    1
##  [2,]    2
##  [3,]    3
##  [4,]    4
##  [5,]    5
##  [6,]    6
##  [7,]    7
##  [8,]    8
##  [9,]    9
## [10,]   10
## [11,]   11
## [12,]   12
## [13,]   13
## [14,]   14
## [15,]   15
## [16,]   16
## [17,]   17
## [18,]   18
## [19,]   19
## [20,]   20
## [21,]   21
## [22,]   22
## [23,]   23
## [24,]   24
## [25,]   25

Veamos un ejemplo con 6 valores:

matrix(1:8, byrow = FALSE, nrow = 2)
##      [,1] [,2] [,3] [,4]
## [1,]    1    3    5    7
## [2,]    2    4    6    8
matrix(1:8, byrow = FALSE, nrow = 4)
##      [,1] [,2]
## [1,]    1    5
## [2,]    2    6
## [3,]    3    7
## [4,]    4    8

Vemos que no aparecen mensajes de error.

2.3.1 Generar una matriz a partir de vectores

Vamos a unir 3 vectores independientes en una matriz. Les vamos a llamar A, B, y C.

# Creamos los 3 vectores: A, B, C
A <- c(460.998, 314.4)
B <- c(290.475, 247.900)
C <- c(309.306, 165.8)

# Los juntamos en un objeto llamado D
D <- c(A, B, C)

# Vemos cómo es el objeto D.
print(D)
## [1] 460.998 314.400 290.475 247.900 309.306 165.800
# Construimos la matriz
D_matriz <- matrix(D, byrow=TRUE, nrow=3)
D_matriz
##         [,1]  [,2]
## [1,] 460.998 314.4
## [2,] 290.475 247.9
## [3,] 309.306 165.8

2.3.2 Añadir nombre de columnas y filas a una matriz

Existen dos formas de añadir nombre de columnas y filas a una matriz:

  • Con las funciones rownames() y colnames(), para filas y columnas respectivamente.
  • Con el atributo dimnames incluido dentro de la función matrix().

2.3.2.1 Usando rownames() y colnames()

Vamos a aprender a añadir nombres de columnas y filas a nuestra matriz de datos. Para ello, vamos a utilizar las funciones rownames() y colnames().

# Llamamos con el nombre "a" a nuestra matriz del inicio
a <- matrix(1:25, byrow = TRUE, nrow = 5)

# Añadimos los nombres de las filas y columnas indicando la matrix a la que queremos añadir o cambiar esos nombres
rownames(a) <- c("a", "b", "c", "d", "e")
colnames(a) <- c("A", "B", "C", "D", "E")

# Visualizamos la matriz
a
##    A  B  C  D  E
## a  1  2  3  4  5
## b  6  7  8  9 10
## c 11 12 13 14 15
## d 16 17 18 19 20
## e 21 22 23 24 25

Es importante conocer de antemano cuántas filas y columnas hay para escribir tantos nombres como columnas y filas existan.

2.3.2.2 Usando dimnames

En esta ocasión, los nombres se filas y columnas se incluyen dentro de la función matrix(), utilizando el atributo dimnames. Este nombre proviene de dimension names.

# Llamamos con el nombre "b" a nuestra matriz del inicio
b <- matrix(1:25, byrow = TRUE, nrow = 5, dimnames = list(c("a", "b", "c", "d", "e"), c("A", "B", "C", "D", "E")))

# Visualizamos la matriz
b
##    A  B  C  D  E
## a  1  2  3  4  5
## b  6  7  8  9 10
## c 11 12 13 14 15
## d 16 17 18 19 20
## e 21 22 23 24 25

Como podemos ver, se ha creado el atributo dimnames que incluye la función list(). Ésta a su vez, incluye dos vectores con los nombres de las filas a la izquierda, y los nombres de las columnas a la derecha.

Para mostrarlo de otro modo complementario, también podemos crear dos vectores con el nombre de las filas y columnas por un lado, y posteriormente incluir el nombre de esos vectores en dimnames.

# Creamos los vectores con los nombres de filas y folumnas
nombre_filas <- c("a", "b", "c", "d", "e")
nombre_columnas <- c("A", "B", "C", "D", "E")

# Llamamos con el nombre "c" a nuestra matriz del inicio
c <- matrix(1:25, byrow = TRUE, nrow = 5, dimnames = list(nombre_filas, nombre_columnas))

# Visualizamos la matriz
c
##    A  B  C  D  E
## a  1  2  3  4  5
## b  6  7  8  9 10
## c 11 12 13 14 15
## d 16 17 18 19 20
## e 21 22 23 24 25

2.3.3 Eliminar nombres de columnas y filas a una matriz

Si queremos eliminar los nombres de filas y columnas de una matriz, volvemos a usar las funciones rownames() y colnames(), pero esta vez añadiendo una función c() vacía.

rownames(a) <- c()
colnames(a) <- c()

2.3.4 Sumar los valores de columnas y filas con colSums() y rowSums()

Para sumar todos los valores de cada fila, usamos la función rowSums(), mientras que para sumar todos los valores de cada columna usamos la función colSums(). Dentro de cada una de estas funciones tenemos que incluir el nombre de la matriz sobre la que queremos hacer las sumas.

2.3.4.1 Sumar los valores de las filas con rowSums()

# Sumamos los valores en cada fila de la matriz "c"
rowSums(c)
##   a   b   c   d   e 
##  15  40  65  90 115

2.3.4.2 Sumar los valores de las columnas con colSums()

# Sumamos los valores en cada columna de la matriz "c"
colSums(c)
##  A  B  C  D  E 
## 55 60 65 70 75

2.3.5 Añadir columnas y filas nuevas a una matriz

2.3.5.1 Añadir columnas con cbind()

Vamos a añadir una columna extra a nuestra matriz c que sea la suma de las filas utilizando la función cbind(). Esta función une matrices y/o vectores por columnas. De hecho, su nombre viene de column bind.

# Primero damos el nombre a la suma de las filas
suma_filas <- rowSums(c)

# Ahora unimos la matriz "c" con "suma_filas"
cbind(c, suma_filas)
##    A  B  C  D  E suma_filas
## a  1  2  3  4  5         15
## b  6  7  8  9 10         40
## c 11 12 13 14 15         65
## d 16 17 18 19 20         90
## e 21 22 23 24 25        115

2.3.5.2 Añadir filas con rbind()

Vamos a añadir una fila extra a nuestra matriz c que sea la suma de las columnas utilizando la función rbind(). Esta función une matrices y/o vectores por filas. De hecho, su nombre viene de row bind.

# Primero damos el nombre a la suma de las filas
suma_columnas <- colSums(c)

# Ahora unimos la matriz "c" con "suma_columnas"
rbind(c, suma_columnas)
##                A  B  C  D  E
## a              1  2  3  4  5
## b              6  7  8  9 10
## c             11 12 13 14 15
## d             16 17 18 19 20
## e             21 22 23 24 25
## suma_columnas 55 60 65 70 75

2.3.6 Seleccionar los elementos de una matriz

Mientras que un vector tiene solo una dimensión, una matriz, tiene dos. Podemos seleccionar filas y/o columnas específicas de dentro de una matriz usando los corchetes [], separando por una coma las filas a la izquierda y columnas a la derecha.

# Seleccionamos sólo la fila 2 del objeto "c"
c[2, ]
##  A  B  C  D  E 
##  6  7  8  9 10
# Seleccionamos sólo la columna 3
c[, 3]
##  a  b  c  d  e 
##  3  8 13 18 23
# Seleccionamos el valor que está en la fila 1 y columna 2
c[1,2]
## [1] 2
# Seleccionamos las filas 2,3,4 y las columnas 1,2,3 del objeto "c"
c[2:4, 1:3]
##    A  B  C
## b  6  7  8
## c 11 12 13
## d 16 17 18

2.3.7 Operaciones aritméticas con las matrices

Podemos sumar, restar, multiplicar y dividir fácilmente una matriz.

# Multiplicamos por 10 la matriz "c"
c * 10
##     A   B   C   D   E
## a  10  20  30  40  50
## b  60  70  80  90 100
## c 110 120 130 140 150
## d 160 170 180 190 200
## e 210 220 230 240 250
# La dividimos por 2
c / 2
##      A    B    C    D    E
## a  0.5  1.0  1.5  2.0  2.5
## b  3.0  3.5  4.0  4.5  5.0
## c  5.5  6.0  6.5  7.0  7.5
## d  8.0  8.5  9.0  9.5 10.0
## e 10.5 11.0 11.5 12.0 12.5
# La sumamos 1
c + 1
##    A  B  C  D  E
## a  2  3  4  5  6
## b  7  8  9 10 11
## c 12 13 14 15 16
## d 17 18 19 20 21
## e 22 23 24 25 26
# Y le restamos 3
c - 3
##    A  B  C  D  E
## a -2 -1  0  1  2
## b  3  4  5  6  7
## c  8  9 10 11 12
## d 13 14 15 16 17
## e 18 19 20 21 22

2.3.7.1 Operando con 2 matrices

c*c
##     A   B   C   D   E
## a   1   4   9  16  25
## b  36  49  64  81 100
## c 121 144 169 196 225
## d 256 289 324 361 400
## e 441 484 529 576 625

2.3.8 Número de filas y columnas con nrow() y ncol()

nrow(c)
## [1] 5
ncol(c)
## [1] 5

2.4 Factores

El término factor se refiere a un tipo de datos estadístico que almacena variables categóricas o cualitativas. Por definición, las variables categóricas cuentan con un número limitado de factores (o categorías). Por ejemplo, la variable sexo solo tiene dos factores: hombre o mujer.

2.4.1 Creando factores con la función factor()

# Tenemos un vector
sexo <- c("hombre", "mujer", "mujer", "mujer", "hombre", "mujer")

# Vemos que ese vector tiene dos factores, por lo que lo convertimos en factorial
factor(sexo)
## [1] hombre mujer  mujer  mujer  hombre mujer 
## Levels: hombre mujer

2.4.2 Tipos de variables categóricas

Podemos distinguir 2 tipos de variables categóricas:

  • Variables categóricas nominales. No implica ningún orden. Por ejemplo el sexo.
  • Variables categóricas ordinales. Implica orden o gradación. Por ejemplo, Bajo, Medio, Alto.

Las variables nominales son las que hemos visto ya en el ejemplo sexo, donde no hay ningún orden. Vamos a ver ahora cómo añadir las variables categóricas ordinales.

# Veamos cómo categorizar el peso de niños
peso <- c("Alto", "Bajo", "Bajo", "Medio", "Bajo", "Medio", "Alto")

# Lo convertimos en categórico añadiendo que hay un orden
factor_peso <- factor(peso, order = TRUE, levels = c("Bajo", "Medio", "Alto"))

Como podemos ver, al introducir el atributo levels() dentro de la función factor(), podemos indicar el orden correcto de nuestra variable categórica nominal.

# Al ver el objeto "factor_peso", vemos que las categorías ya están ordenadas con el símbolo "<"
factor_peso
## [1] Alto  Bajo  Bajo  Medio Bajo  Medio Alto 
## Levels: Bajo < Medio < Alto

2.4.3 Conocer las categorías y cambiar sus nombres con levels()

Si queremos conocer las categorías o factores de una variable categórica, tenemos que usar la función levels().

# Hemos hecho una encuesta y hemos registrado el sexo con "H" hombre y "M" mujer.
encuesta <- c("M", "M", "H", "H", "M", "H")
encuestafac <- factor(encuesta) # convertimos "encuesta" en factorial
levels(encuestafac) # vemos las categorías que tiene
## [1] "H" "M"
# Cambiamos el nombre de las categorías siguiendo el orden que sale en levels(encuesta)
levels(encuestafac) <- c("Hombre", "Mujer")
levels(encuestafac) # comprobamos el cambio de nombre
## [1] "Hombre" "Mujer"

2.4.4 Resumiendo una variable categórica con summary()

summary(encuesta)
##    Length     Class      Mode 
##         6 character character
summary(encuestafac)
## Hombre  Mujer 
##      3      3
summary(factor_peso)
##  Bajo Medio  Alto 
##     3     2     2

2.4.5 Comparando factores ordinales con operadores

# Creamos el vector velocidad
velocidad <- c("medio", "lento", "lento", "medio", "rápido")
factor_velocidad <- factor(velocidad, ordered = TRUE, levels = c("lento", "medio", "rápido"))

# Seleccionamos al segundo
da2 <- factor_velocidad[2]

# Seleccionamos al quinto
da5 <- factor_velocidad[5]

# ¿Es el 2 más rápido que el 5?
da2 > da5
## [1] FALSE

2.5 Dataframes en R

Si recordamos, las matrices eran objetos donde todos sus elementos son del mismo tipo. Sin embargo, en los dataframes pueden existir elementos de varios tipos al mismo tiempo. Es el ejemplo clásico de una entrevista, donde la base de datos que se genera provienen de preguntas de diversa naturaleza: ¿eres hombre o mujer? ¿estás casado/a? (lógica), ¿qué edad tienes? (número entero), ¿cuánto mides? (número real) ¿qué estudiaste? (cadena de texto), etc.

En un dataframe, en las columnas están las variables y en las filas las observaciones. Vamos a emplear el ejemplo de mtcars.

data(mtcars)

2.5.1 head() y tail() de un dataframe

Cuando tenemos dataframes de grandes dimensiones, cuando queremos ver cómo son los datos podemos cargar las primeras filas o las últimas nada más. Y esto lo conseguimos con las funciones head() y tail().

head(mtcars) # muestra las primeras 6 observaciones
##                    mpg cyl disp  hp drat    wt  qsec vs am gear carb
## Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
## Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
## Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
## Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
## Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
## Valiant           18.1   6  225 105 2.76 3.460 20.22  1  0    3    1
tail(mtcars) # muestra las últimas 6 observaciones
##                 mpg cyl  disp  hp drat    wt qsec vs am gear carb
## Porsche 914-2  26.0   4 120.3  91 4.43 2.140 16.7  0  1    5    2
## Lotus Europa   30.4   4  95.1 113 3.77 1.513 16.9  1  1    5    2
## Ford Pantera L 15.8   8 351.0 264 4.22 3.170 14.5  0  1    5    4
## Ferrari Dino   19.7   6 145.0 175 3.62 2.770 15.5  0  1    5    6
## Maserati Bora  15.0   8 301.0 335 3.54 3.570 14.6  0  1    5    8
## Volvo 142E     21.4   4 121.0 109 4.11 2.780 18.6  1  1    4    2
# Recordad que nos puede sacar el número que queramos, head(mtcars, n = 4), por ejemplo, nos devuelve las primeras 4 filas.

head(mtcars, n = 10)
##                    mpg cyl  disp  hp drat    wt  qsec vs am gear carb
## Mazda RX4         21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
## Mazda RX4 Wag     21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
## Datsun 710        22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
## Hornet 4 Drive    21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
## Hornet Sportabout 18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
## Valiant           18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
## Duster 360        14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
## Merc 240D         24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
## Merc 230          22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
## Merc 280          19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4

2.5.2 Estructura de un dataframe con str()

Cuando recibimos un nuevo dataframe, lo primero que debemos hacer es ver cómo es su estructura, conocer cuántas variables tiene, de qué tipo son, etc. Esto lo conseguimos con la función str(), que proviene del inglés structure. Con esta función conoceremos de un dataframe lo siguiente:

  • Número total de observaciones (filas)
  • Número total de variables (columnas)
  • Lista completa del nombre de las variables
  • El tipo de dato de cada variable
  • Las primeras observaciones (filas)
str(mtcars)
## 'data.frame':    32 obs. of  11 variables:
##  $ mpg : num  21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
##  $ cyl : num  6 6 4 6 8 6 8 4 4 6 ...
##  $ disp: num  160 160 108 258 360 ...
##  $ hp  : num  110 110 93 110 175 105 245 62 95 123 ...
##  $ drat: num  3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
##  $ wt  : num  2.62 2.88 2.32 3.21 3.44 ...
##  $ qsec: num  16.5 17 18.6 19.4 17 ...
##  $ vs  : num  0 0 1 1 0 1 0 1 1 1 ...
##  $ am  : num  1 1 1 0 0 0 0 0 0 0 ...
##  $ gear: num  4 4 4 3 3 3 3 4 4 4 ...
##  $ carb: num  4 4 1 1 2 1 4 2 2 4 ...

2.5.3 Crear un dataframe con data.frame()

Vamos a crear un dataframe (df) que describan las principales características de 8 planetas de nuestro Sistema Solar con 4 variables (tipo de planeta, diámetro, rotación, presencia de anillos).

# Definimos 5 vectores, uno con el nombre de los planetas y 4 con las variables mencionadas.
name <- c("Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune")
type <- c("Terrestrial planet", "Terrestrial planet", "Terrestrial planet", 
          "Terrestrial planet", "Gas giant", "Gas giant", "Gas giant", "Gas giant")
diameter <- c(0.382, 0.949, 1, 0.532, 11.209, 9.449, 4.007, 3.883)
rotation <- c(58.64, -243.02, 1, 1.03, 0.41, 0.43, -0.72, 0.67)
rings <- c(FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE)

# Juntamos los vectores anteriores en un mismo dataframe llamándolo "planets.df"
planets.df <- data.frame(name, type, diameter, rotation, rings)

# Vemos su estructura
str(planets.df)
## 'data.frame':    8 obs. of  5 variables:
##  $ name    : Factor w/ 8 levels "Earth","Jupiter",..: 4 8 1 3 2 6 7 5
##  $ type    : Factor w/ 2 levels "Gas giant","Terrestrial planet": 2 2 2 2 1 1 1 1
##  $ diameter: num  0.382 0.949 1 0.532 11.209 ...
##  $ rotation: num  58.64 -243.02 1 1.03 0.41 ...
##  $ rings   : logi  FALSE FALSE FALSE FALSE TRUE TRUE ...

2.5.4 Seleccionar elementos de un dataframe

Al igual que con los vectores y matrices, usaremos los corchetes [] para seleccionar elementos, dividiendo con una coma las filas (a la izquierda) y las columnas (a la derecha).

planets.df[1,3] # seleccionamos el elemento situado en la fila 1 y columna 3
## [1] 0.382
planets.df[1:3, 3:5] # seleccionamos las filas 1 a 3, y las columnas 3 a 5
##   diameter rotation rings
## 1    0.382    58.64 FALSE
## 2    0.949  -243.02 FALSE
## 3    1.000     1.00 FALSE
planets.df[ , 5] # seleccionamos todas las filas y la columna 5
## [1] FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE

Si queremos seleccionar toda una columna, tenemos 3 formas de hacerlo:

# Vamos a seleccionar la columna "diameter"
planets.df[, 3] # indicando la posición de la columna
## [1]  0.382  0.949  1.000  0.532 11.209  9.449  4.007  3.883
planets.df[, "diameter"] # indicando el nombre de la columna
## [1]  0.382  0.949  1.000  0.532 11.209  9.449  4.007  3.883
planets.df$diameter # uniendo nombre de dataframe con el nombre de la columna usando el símbolo de dólar "$"
## [1]  0.382  0.949  1.000  0.532 11.209  9.449  4.007  3.883

Si queremos seleccionar solo los nombres de los planetas con anillos, hacemos lo siguiente.

rings_vector <- planets.df$rings # seleccionamos la columna rings
planets.df[rings_vector,] # automáticamente te salen solo los TRUE
##      name      type diameter rotation rings
## 5 Jupiter Gas giant   11.209     0.41  TRUE
## 6  Saturn Gas giant    9.449     0.43  TRUE
## 7  Uranus Gas giant    4.007    -0.72  TRUE
## 8 Neptune Gas giant    3.883     0.67  TRUE

2.5.4.1 Usando subset()

Lo visto anteriormente nos permite seleccionar elementos concretos de un dataframe. Pero con subsets() este proceso se automatiza. Su estructura es: subset(dataframe, subset=condición).

subset(planets.df, subset = rings) # mismo resultado que en el anterior ejemplo, marcando solo TRUE
##      name      type diameter rotation rings
## 5 Jupiter Gas giant   11.209     0.41  TRUE
## 6  Saturn Gas giant    9.449     0.43  TRUE
## 7  Uranus Gas giant    4.007    -0.72  TRUE
## 8 Neptune Gas giant    3.883     0.67  TRUE
subset(planets.df, subset = diameter < 1) # seleccionamos los que tengan diámetro menor que 1
##      name               type diameter rotation rings
## 1 Mercury Terrestrial planet    0.382    58.64 FALSE
## 2   Venus Terrestrial planet    0.949  -243.02 FALSE
## 4    Mars Terrestrial planet    0.532     1.03 FALSE

2.5.5 Ordenar los datos de un dataframe con order()

En muchas ocasiones nos interesa ordenar los datos para poder ver cómo de gradual son los cambios, por ejemplo. Para ordenar los datos, tenemos que usar la función order().

a <- c(100, 10, 1000) # creamos un vector
order(a) # nos ordena según la posición de menor a mayor
## [1] 2 1 3
a[order(a)] # nos ordena según los valores de menor a mayor
## [1]   10  100 1000
# Vamos a hcer lo mismo que en el caso anterior pero ordenando por diámetro los planetas
positions <- order(planets.df$diameter)
planets.df[positions,]
##      name               type diameter rotation rings
## 1 Mercury Terrestrial planet    0.382    58.64 FALSE
## 4    Mars Terrestrial planet    0.532     1.03 FALSE
## 2   Venus Terrestrial planet    0.949  -243.02 FALSE
## 3   Earth Terrestrial planet    1.000     1.00 FALSE
## 8 Neptune          Gas giant    3.883     0.67  TRUE
## 7  Uranus          Gas giant    4.007    -0.72  TRUE
## 6  Saturn          Gas giant    9.449     0.43  TRUE
## 5 Jupiter          Gas giant   11.209     0.41  TRUE

2.6 Listas en R

Las listas en R nos permiten reunir un conjunto de objetos bajo un nombre. Estos objetos pueden ser matrices, vectores, dataframes, incluso otras listas. Es como si dijéramos, un superobjeto que puede almacenar prácticamente cualquier tipo de información.

2.6.1 Creamos una lista con list()

Usamos la función list() para reunir una variedad de objetos.

# Unimos con list() un conjunto de elementos vistos anteriormente
mi_lista <- list(planets.df, encuesta, peso)

2.6.2 Dar nombre a los elementos de una lista

mi_lista <- list(Planetas = planets.df, Encuesta_hoy = encuesta, Peso = peso) # Modo 1. Directamente en el paréntesis
names(mi_lista) <- c("Planetas", "Encuesta", "Peso en kg") # Modo 2. Usando la función names()

mi_lista
## $Planetas
##      name               type diameter rotation rings
## 1 Mercury Terrestrial planet    0.382    58.64 FALSE
## 2   Venus Terrestrial planet    0.949  -243.02 FALSE
## 3   Earth Terrestrial planet    1.000     1.00 FALSE
## 4    Mars Terrestrial planet    0.532     1.03 FALSE
## 5 Jupiter          Gas giant   11.209     0.41  TRUE
## 6  Saturn          Gas giant    9.449     0.43  TRUE
## 7  Uranus          Gas giant    4.007    -0.72  TRUE
## 8 Neptune          Gas giant    3.883     0.67  TRUE
## 
## $Encuesta
## [1] "M" "M" "H" "H" "M" "H"
## 
## $`Peso en kg`
## [1] "Alto"  "Bajo"  "Bajo"  "Medio" "Bajo"  "Medio" "Alto"

2.6.3 Seleccionar elementos de una lista

Si quisiéramos seleccionar el elemento Planetas, tenemos tres formas de hacerlo en R. La principal diferencia respecto a la selección en vectores, matrices y dataframes es que se usa el doble corchete [[]].

mi_lista[[1]] # indicando la posición de "Planetas" dentro de la lista
##      name               type diameter rotation rings
## 1 Mercury Terrestrial planet    0.382    58.64 FALSE
## 2   Venus Terrestrial planet    0.949  -243.02 FALSE
## 3   Earth Terrestrial planet    1.000     1.00 FALSE
## 4    Mars Terrestrial planet    0.532     1.03 FALSE
## 5 Jupiter          Gas giant   11.209     0.41  TRUE
## 6  Saturn          Gas giant    9.449     0.43  TRUE
## 7  Uranus          Gas giant    4.007    -0.72  TRUE
## 8 Neptune          Gas giant    3.883     0.67  TRUE
mi_lista[["Planetas"]] # indicando el nombre del elemento entre paréntesis
##      name               type diameter rotation rings
## 1 Mercury Terrestrial planet    0.382    58.64 FALSE
## 2   Venus Terrestrial planet    0.949  -243.02 FALSE
## 3   Earth Terrestrial planet    1.000     1.00 FALSE
## 4    Mars Terrestrial planet    0.532     1.03 FALSE
## 5 Jupiter          Gas giant   11.209     0.41  TRUE
## 6  Saturn          Gas giant    9.449     0.43  TRUE
## 7  Uranus          Gas giant    4.007    -0.72  TRUE
## 8 Neptune          Gas giant    3.883     0.67  TRUE
mi_lista$Planetas # enlazando el nombre de la lista con el nombre del elemento usando el dólar $
##      name               type diameter rotation rings
## 1 Mercury Terrestrial planet    0.382    58.64 FALSE
## 2   Venus Terrestrial planet    0.949  -243.02 FALSE
## 3   Earth Terrestrial planet    1.000     1.00 FALSE
## 4    Mars Terrestrial planet    0.532     1.03 FALSE
## 5 Jupiter          Gas giant   11.209     0.41  TRUE
## 6  Saturn          Gas giant    9.449     0.43  TRUE
## 7  Uranus          Gas giant    4.007    -0.72  TRUE
## 8 Neptune          Gas giant    3.883     0.67  TRUE

2.6.3.1 Seleccionar elementos dentro de elementos de una lista

Si quisiéramos el segundo elemento del elemento Peso en kg, tendremos que indicar que nos coja el elemento de la lista (Peso en kg), y dentro de éste, el segundo elemento (que en nuestro ejemplo es Bajo). Esto se hace seleccionando secuencialmente los elementos.

# 3 formas de hacerlo
mi_lista[["Peso en kg"]] [2]
## [1] "Bajo"
mi_lista[[3]] [2]
## [1] "Bajo"
mi_lista$`Peso en kg`[2]
## [1] "Bajo"

2.6.4 Incluir nuevos elementos a una lista con c()

Si quisiéramos aumentar los elementos de una lista ya creada, basta con usar la función c().

# Incluimos la variable "velocidad"" a "mi_lista", dándole ya el nombre.

mi_lista_ampliada <- c(mi_lista, Año=1980)