Puedes comprar el libro en: https://www.leanpub.com/analisis_exploratorio_datos_con_R

Capítulo 3 Conceptos básicos de R

3.1 Introducción.

El objetivo de este tutorial es familiarizarnos con los conceptos básicos de R. ¿Qué es un objeto en R? ¿Con qué clases/tipos de objetos se trabaja en R? A lo largo de este tutorial aprenderemos a definir vectores y operar con ellos; a crear matrices, listas y data frames; a seleccionar elementos, añadir filas y columnas, etc. Como lo que se pretende es que se entienda la filosofía y la práctica del trabajo con R, todos los conceptos que se introducen se ilustran con ejemplos muy sencillos. No obstante, la selección de funciones que se realiza en este tutorial tienen una aplicación directa en el tratamiento real de datos.

3.2 Lo más básico y fundamental!!!

Vamos a realizar paso a paso este sencillo ejercicio para introducir algunos conceptos importantes.

3+4
## [1] 7
log(10)
## [1] 2.302585
x <- 3+4  
x  # x es un vector cuya primera componente es 7. Enseguida vamos con los vectores!
## [1] 7
y = 2+6
y
## [1] 8
z <- c(x,y)
z
## [1] 7 8
mean(z)
## [1] 7.5
w <- mean(z)
w
## [1] 7.5
round(w, digits=0)
## [1] 8

R utiliza funciones para realizar operaciones. Una función es, por ejemplo, mean(). Para utilizar una función deben especificarse unos argumentos, que es lo que escribimos dentro de los paréntesis. En el caso de la función round() hemos especificado dos argumentos: el vector que queremos redondear (w) y el número de decimales del redondeo (digits).

El símbolo <- es el operador para asignar. También se puede utilizar = (o menos frecuente ->), aunque es preferible utilizar el <-.

El símbolo # se utiliza para introducir un comentario. Todo lo que quede a la derecha de # no se ejecutará.

Cuando se realiza una asignación se obtiene un objeto. Podemos ver el resultado o contenido de un objeto de varias formas. Por ejemplo, para ver qué es el objeto x podemos escribir en la consola:

  • x
  • print(x)
  • (x <- 3+4)

También lo podemos ver en el panel de entorno del escritorio de RStudio.

3.3 Como definir vectores…

Básicamente R trabaja con los siguientes tipos de objetos:

  • VECTORES
  • MATRICES y ARRAYS (variables indexadas)
  • LISTAS
  • FACTORES
  • DATA FRAME
  • FUNCIONES

Empezaremos viendo los objetos más sencillos, los vectores. Poco a poco iremos viendo el resto de objetos.

La mayoría de las operaciones (+, -, *, /) y funciones en R están definidas con carácter vectorial. ¿Qué significa esto? Que R opera componente a componente.

Antes de entender el concepto “caracter vectorial”, vamos a ver cómo se define/crea un vector.

Para crear un vector se utiliza la función c() (c de concatenate). Por ejemplo:

x <- c(1,2,3,4)
x                  # x es un vector que tiene cuatro componentes
## [1] 1 2 3 4
y <- c(5,6,7,8)
y
## [1] 5 6 7 8

Volvemos sobre el tema del carácter vectorial, es decir, se opera componente a componente. Pensemos, si

z <- x + y

¿Qué resultado espero obtener para z?

Exacto!!! Como la operación se realiza vectorialmente (componente a componente, muy importante!) el resultado es:

## [1]  6  8 10 12

Vamos a ver si lo entendemos de verdad. Supongamos que x e y son los siguientes vectores:

x <- c(1,2,3,4)
y <- c(1,2,3)

¿Qué longitud tienen los vectores x e y? Aquí la respuesta está clara, pero en aplicaciones reales utilizaríamos la función length().

length(x)                # esta función es muy útil, conviene recordarla.
## [1] 4
length(y)
## [1] 3

Los vectores no tienen la misma longitud, entonces.. ¿Cuál será el resultado de z <- x + y?

z <- x+y
## Warning in x + y: longitud de objeto mayor no es múltiplo de la longitud de
## uno menor
z
## [1] 2 4 6 5

R nos da un mensaje de aviso (warning), no es lo mismo que un error. Nos avisa que hay algo que no cuadra pero…realiza la operación que nosotros queremos.

Una cuestión muy importante que siempre tenemos que tener en cuenta cuando trabajamos con vectores es que en un vector sólo podemos concatenar elementos del mismo tipo. ¿Qué tipos/clases de elementos (o datos) tenemos en R?

  • Carácter
  • Numéricos
  • Enteros
  • Complejos
  • Lógicos

Veamos algunos ejemplos…

x <- c(1,2,3,4)    # creamos el vector x
class(x)           # devuelve el tipo de objeto
## [1] "numeric"
y <- c("a","b")
class(y)
## [1] "character"
z <- c(1L,2L,3L)   # escribimos L detrás del número para obligar a que sea entero
class(z)
## [1] "integer"
w <- c(TRUE, F)    # en general, puede escribirse TRUE/FALSE o T/F
class(w)
## [1] "logical"
t <- c(1+2i, 1+3i)
class(t)
## [1] "complex"

En los ejemplos anteriores hemos definido un vector en el que todos sus elementos eran del mismo tipo. Pero….¿qué pasa si tenemos los siguientes vectores?

x <- c(1,2,"a")
y <- c(FALSE, 1)
z <- c("a",T)

¿De qué tipo son ahora los vectores x, y, z?

class(x)
## [1] "character"
class(y)
## [1] "numeric"
class(z)
## [1] "character"

R ha forzado a que todos los elementos del vector sean del mismo tipo. A esto se le llama implicit coercion. Fijémonos cúal es el resultado de los vectores que hemos definido antes.

x 
## [1] "1" "2" "a"
y
## [1] 0 1
z
## [1] "a"    "TRUE"

En ocasiones somos nosotros los que estamos interesados en forzar que todos los elementos del vector sean del mismo tipo (esto es la explicit coercion). Para ello utilizamos las funciones as.numeric() , as.character(), as.logical() … Si el resultado no tiene sentido R producirá un mensaje de error o warning. Un ejemplo:

x <- c(1,2,"a")
x
## [1] "1" "2" "a"
as.numeric(x)
## [1]  1  2 NA
as.character(x)
## [1] "1" "2" "a"

Por último, podemos evaluar el tipo/clase de objeto con las funciones is.numeric(), is.character(), etc.

3.3.1 Acceder a un elemento de un objeto.

Para seleccionar/acceder a un elemento de un objeto se suelen emplear: [], $, [[]].

Vamos a crear el objeto x que será un vector de cuatro componentes formado por los cuatro primeros números pares. Así:

x <- c(2,4,6,8)

Si queremos acceder/seleccionar/extraer al/el segundo componente de x

x[2]
## [1] 4

¿Qué resultados darán los siguientes ejemplos?

z[6]
z # si primero z[6]<-12
z[-2]
length(z)
z # si primero length(z)<-3

Comprobemos nuestras respuestas!!

## [1] NA
## [1] "a"    "TRUE" NA     NA     NA     "12"
## [1] "a"  NA   NA   NA   "12"
## [1] 6
## [1] "a"    "TRUE" NA

Más tarde veremos con más profundidad cómo acceder a elementos de un objeto. ¡Esto es esencial!

3.3.2 Listar y borrar objetos.

Las funciones ls() y objects() hacen lo mismo: listan los objetos que hemos definido en la sesión.

ls()
## [1] "t" "w" "x" "y" "z"
objects()
## [1] "t" "w" "x" "y" "z"

Si queremos borrar objetos utilizamos la función rm()

rm(z)  # borramos el objeto z
ls()
## [1] "t" "w" "x" "y"

y si estamos interesados en borrar todos los objetos que hemos definido:

rm(list=ls()) # o también rm(list=objects())
ls()
## character(0)

3.4 Tipos de objetos: Vectores, Matrices, Listas, Data frame y Factores.

De los vectores ya hemos hablado en el punto 2. Ahora vamos a ver algunas cuestiones básicas relativas a otros tipos de objetos.

3.4.1 Matrices.

La función matrix() permite organizar los datos en una matriz con tantas filas y columnas como se indiquen.

Vamos a pedir ayuda a R sobre la función matrix()

?matrix # una forma de obtener ayuda en R es escribiendo ? delante de la función de la que solicitamos ayuda

3.4.1.1 Cómo crear y trabajar con matrices

Una vez hemos leído en la ayuda cómo usar la función matrix, vamos a practicarlo con el siguiente ejemplo. Pero antes de ejecutarlo, pensemos en qué es lo que queremos hacer y, sobre todo, pensemos en cuál es el resultado que esperamos obtener.

x <- matrix (data= c(1,2,3,4), nrow=2, ncol=2) # o x <- matrix (c(1,2,3,4), nrow=2, ncol=2)
x
##      [,1] [,2]
## [1,]    1    3
## [2,]    2    4

Observemos que se ha creado una matrix de 2x2 (2 filas y 2 columnas) y, además, muy importante, ¿cómo se ha completado la matriz? ¡Exacto! La matriz se ha rellenado por columnas. Si queremos que se rellene por filas hay que incluir el argumento byrow en los argumentos de la función.

y <- matrix (c(1,2,3,4), nrow=2, ncol=2, byrow=T)
y
##      [,1] [,2]
## [1,]    1    2
## [2,]    3    4

Fijaros en la diferencia entre los objetos x e y.

Una forma más simple para definir una matrix es:

y <- matrix (c(1,2,3,4), 2, 2, byrow=T)
y
##      [,1] [,2]
## [1,]    1    2
## [2,]    3    4

aunque también podíamos haber omitido el argumento relativo al número de filas o de columnas, porque conocida una dimensión R completaría la matrix dados los datos con los que se trabaja.

y <- matrix (c(1,2,3,4), 2, byrow=T)  # no especificamos nrow porque por defecto es el primer argumento después de los datos
y
##      [,1] [,2]
## [1,]    1    2
## [2,]    3    4
x <- matrix(c(1,2,3,4,5,6), ncol=3)
x
##      [,1] [,2] [,3]
## [1,]    1    3    5
## [2,]    2    4    6

3.4.1.2 Nombres en filas/columnas

Si queremos asignar nombres a las filas y/o columnas…

y <- matrix (c(1,2,3,4), nrow=2, ncol=2, byrow=T, dimnames=list(c("X1","X2"),c("Y1", "Y2")))
y
##    Y1 Y2
## X1  1  2
## X2  3  4

Para añadir o modificar el nombre de filas y columnas de una matriz se hace uso de las funciones colnames() y rownames(). También se puede utilizar la función dinmanes(), como en el ejemplo anterior) y asignar nombres a través de una lista (ver el punto 5.2 de este tutorial).

y <- matrix (1:10, nrow=5)
y
##      [,1] [,2]
## [1,]    1    6
## [2,]    2    7
## [3,]    3    8
## [4,]    4    9
## [5,]    5   10
colnames(y) <- c("Variable 1", "Variable 2")
rownames(y) <- c("obs1","obs2","obs3","obs4","obs5")
y
##      Variable 1 Variable 2
## obs1          1          6
## obs2          2          7
## obs3          3          8
## obs4          4          9
## obs5          5         10

3.4.1.3 Dimensión de una matriz

Vamos a comprobar la dimensión de una matriz con este otro ejemplo:

z <- matrix(1:20, 4)

¿Cuál es la dimensión de la matriz z?

dim(z)
## [1] 4 5
dim(z)[1] # seleccionamos el primer componente de dim(Z), es decir, las filas.
## [1] 4
dim(z)[2] # seleccionamos el segundo componente de dim(z), las columnas
## [1] 5

3.4.1.4 Añadir filas/columnas

Dos funciones muy útiles, se utilizan muchísimo, cuando se trabaja con matrices (o vectores o dataframes) son rbind y cbind. La función rbind permite añadir filas, la función cbind permite añadir columnas. Vamos a ver cómo se utilizan.

Creamos dos objetos, uno será una matriz y el otro un vector.

x <- matrix(c(1,2,3,4),2,2)
y <- c(5,6)
x
##      [,1] [,2]
## [1,]    1    3
## [2,]    2    4
y
## [1] 5 6

Si ahora queremos añadir, por filas, los datos contenidos en el objeto y al objeto x entonces haremos…

z <- rbind(x,y)
z
##   [,1] [,2]
##      1    3
##      2    4
## y    5    6

y si queremos añadir los datos de y a los de x por columnas:

z <- cbind(x,y)
z
##          y
## [1,] 1 3 5
## [2,] 2 4 6

Cuidado!! En el caso que el número de filas (o columnas) del objeto que añadimos (objeto y) no sea múltiplo del número de filas (o columnas) del objeto al que se añaden los datos (objeto x), R nos dará un mensaje de aviso (Warning message). R no da un error, nos avisa de que hay algo que “no cuadra”; con todo, realiza la operación. Vamos a comprobar esta circunstancia.

x <- c(4,5)
x
## [1] 4 5
y <- c(10,11,12)
y
## [1] 10 11 12

z <- rbind(x,y)
z
##   [,1] [,2] [,3]
## x    4    5    4
## y   10   11   12

En otras ocasiones interesa crear una matriz directamente a partir de un vector (o vectores). Esto lo podemos hacer al añadir un atributo de dimensión.

w <- 1:10 # w es un vector que se crea a partir de la secuencia del 1 al 10 (1:10)
w
##  [1]  1  2  3  4  5  6  7  8  9 10
dim(w) <- c(2,5) # al dimensionar el vector w lo convertimos en una matriz
w
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    1    3    5    7    9
## [2,]    2    4    6    8   10

En otras ocasiones, sobre todo si definimos una función, interesa crear vectores o matrices vacías. Para ello..

x <- c()           # crea un vector vacío. También podemos utilizar la función vector()
x
## NULL
y <- matrix(nrow=3, ncol=4)    # crea una matriz vacía
y
##      [,1] [,2] [,3] [,4]
## [1,]   NA   NA   NA   NA
## [2,]   NA   NA   NA   NA
## [3,]   NA   NA   NA   NA
dim(y)
## [1] 3 4
attributes(y)
## $dim
## [1] 3 4

3.4.1.5 Seleccionando elementos de una matriz

Lo primero, vamos a crear el objeto A que será una matriz.

A <- matrix(1:16,4,4)
A
##      [,1] [,2] [,3] [,4]
## [1,]    1    5    9   13
## [2,]    2    6   10   14
## [3,]    3    7   11   15
## [4,]    4    8   12   16

Para seleccionar elementos de una matriz utilizamos el símbolo de los corchetes: [].

Pensemos un momento en el posible resultado de estos ejemplos antes de efectuarlos.

A[2,3]
A[c(1,2),c(2,4)]
A[1:3,2:4]
A[1,]
A[1:2,]
A[,2:3]
A[-c(1,3),]  # si utilizamos el signo *-* estamos indicando que queremos mantener todas las filas/columnas menos aquellas que tienen el signo

¿Coinciden nuestros resultados esperados con los obtenidos? Aquí va…

A[2,3]
## [1] 10
A[c(1,2),c(2,4)]
##      [,1] [,2]
## [1,]    5   13
## [2,]    6   14
A[1:3,2:4]
##      [,1] [,2] [,3]
## [1,]    5    9   13
## [2,]    6   10   14
## [3,]    7   11   15
A[1,]
## [1]  1  5  9 13
A[1:2,]
##      [,1] [,2] [,3] [,4]
## [1,]    1    5    9   13
## [2,]    2    6   10   14
A[,2:3]
##      [,1] [,2]
## [1,]    5    9
## [2,]    6   10
## [3,]    7   11
## [4,]    8   12
A[-c(1,3),]
##      [,1] [,2] [,3] [,4]
## [1,]    2    6   10   14
## [2,]    4    8   12   16

3.4.2 Listas.

A diferencia de los vectores o matrices, las listas pueden contener elementos/componentes de distinto tipo. Observemos esta lista que tiene 5 componentes (pueden ser matrices, vectores, dataframes,..).

x <- list(c(1,2,3,4), "Curso", F, 1+2i, 3L)
x
## [[1]]
## [1] 1 2 3 4
## 
## [[2]]
## [1] "Curso"
## 
## [[3]]
## [1] FALSE
## 
## [[4]]
## [1] 1+2i
## 
## [[5]]
## [1] 3

Utilizamos el doble corchete [[]] para acceder al contenido concreto de una lista.

x[[3]]  # accedemos al tercer componente de la lista
## [1] FALSE
x[[1]][2] # accedemos al segundo elemento del primer componente de la lista
## [1] 2

Vamos a crear otra lista para practicar.

y <- list( Titulacion = c("Economía", "Sociología", "Derecho"), Edad =c(25,26,27))

y
## $Titulacion
## [1] "Economía"   "Sociología" "Derecho"   
## 
## $Edad
## [1] 25 26 27

Fijémonos en la diferencia de presentación de las listas x e y. Como en la lista y hemos nombrado los componentes, estos aparecen al ejecutar el objeto precedidos del símbolo $. Ahora también podemos acceder a un componente de la lista por su nombre.

y$Titulacion
## [1] "Economía"   "Sociología" "Derecho"
y[[1]]
## [1] "Economía"   "Sociología" "Derecho"
y[1]
## $Titulacion
## [1] "Economía"   "Sociología" "Derecho"
y[[1]][1]
## [1] "Economía"
y$Titulacion[1]
## [1] "Economía"

Evidentemente, también podemos realizar operaciones con listas.

y[[2]]*3
## [1] 75 78 81

Podemos crear una lista vacía con una determinada longitud:

z <- vector("list", length= 3)

Las listas combinadas con funciones como apply (la veremos en otro tutorial) son muy útiles.

3.4.3 Data Frame.

Los data frame se usan para almacenar datos en forma de tablas (filas / columnas), como estamos habituados en Excel, Spss, etc.

Los data frame pueden almacenar objetos/datos de distinto tipo: numéricos, carácter, … En las matrices todos los elementos tenían que ser enteros o numéricos.

Los data frame pueden entenderse como un tipo especial de lista donde cada elemento de la lista tiene que tener la misma longitud. Cada elemento de la lista sería una columna y la longitud de cada elemento de la lista serían las filas.

Aunque normalmente los data frame los creamos al cargar/leer una base de datos (ver el tutorial), vamos crear una data frame para ver su estructura.

x <- data.frame(Titulacion = c("Economía", "ADE", "Sociología", "Magisterio"), Edad = c(25, 27, 25, 24))
x
##   Titulacion Edad
## 1   Economía   25
## 2        ADE   27
## 3 Sociología   25
## 4 Magisterio   24
class(x)
## [1] "data.frame"

¿Cuál es la dimensión del objeto x (que es una data frame)?

nrow(x) # número de filas
## [1] 4
ncol(x) # número de columnas
## [1] 2
dim(x)  # número de filas y columnas
## [1] 4 2

Para acceder a los elementos de un data frame utilizamos los símbolos $ o []. La forma de proceder es similar a la que se ha visto con vectores o matrices.

Si queremos seleccionar la variable Titulacion del objeto x (que es un data frame):

x$Titulacion
## [1] Economía   ADE        Sociología Magisterio
## Levels: ADE Economía Magisterio Sociología
# También lo podemos hacer así:
x[1]
##   Titulacion
## 1   Economía
## 2        ADE
## 3 Sociología
## 4 Magisterio

y para seleccionar sus dos primeros elementos:

x$Titulacion[1:2]
## [1] Economía ADE     
## Levels: ADE Economía Magisterio Sociología

Si trabajamos con una base de datos (o data frame), para no tener que acceder a una variable utilizando la expresión objeto$variable, que a veces resulta farragoso, puede hacerse un attach al objeto. Esto nos permitirá acceder directamente a las variables de la base de datos por su nombre.

x
##   Titulacion Edad
## 1   Economía   25
## 2        ADE   27
## 3 Sociología   25
## 4 Magisterio   24
# si escribo Titulacion dará: Error: object 'Titulacion' not found 
attach(x)
Titulacion  # ahora puedo acceder directamente a las variables por su nombre
## [1] Economía   ADE        Sociología Magisterio
## Levels: ADE Economía Magisterio Sociología

Por avanzar alguna cosas que veremos más adelante en la práctica, podemos incluir directamente una nueva variable a nuestro data frame. Por ejemplo, vamos a añadir la variable id (de identificador) al objeto x. Esto lo podemos hacer directamente utilizando el símbolo $.

x$id <- 1:4
x
##   Titulacion Edad id
## 1   Economía   25  1
## 2        ADE   27  2
## 3 Sociología   25  3
## 4 Magisterio   24  4

o podemos crear la nueva variable, por ejemplo la variable obs (de observación) y después combinarla con nuestro data frame x.

obs <- 1:4
x <- cbind(obs,x)
x
##   obs Titulacion Edad id
## 1   1   Economía   25  1
## 2   2        ADE   27  2
## 3   3 Sociología   25  3
## 4   4 Magisterio   24  4

3.4.3.1 Ver el contenido de un data frame: head y tail.

Normalmente los data frames con los que trabajamos tienen muchas filas (individuos) y muchas columnas (variables). Si directamente escribimos el nombre del objeto (data frame) para ver su contenido lo que ocurrirá es que veremos poca cosa, apenas si observaremos como R nos lista todo el contenido de forma continua. Para entender lo que queremos decir, vamos a ver el siguiente ejemplo en el que cargamos los datos EuStockMarkets. Estos datos hacen referencia al precio de cierre diario entre los años 1991 y 1998 de las principales bolsas europeas.

data(EuStockMarkets)        # cargamos los datos EuStockMarkets
EuStockMarkets              # para ver el contenido del objeto

¿Hemos visto algo?

Para echar un vistazo al contenido de un data frame (en este caso EuStockMarket) suelen utilizarse las funciones head() y tail(). Por defecto, la primera permite ver las 6 primeras observaciones y la segunda las 6 últimas. También podemos indicar el número de observaciones que queremos visualizar

head(EuStockMarkets)
##          DAX    SMI    CAC   FTSE
## [1,] 1628.75 1678.1 1772.8 2443.6
## [2,] 1613.63 1688.5 1750.5 2460.2
## [3,] 1606.51 1678.6 1718.0 2448.2
## [4,] 1621.04 1684.1 1708.1 2470.4
## [5,] 1618.16 1686.6 1723.1 2484.7
## [6,] 1610.61 1671.6 1714.3 2466.8
tail(EuStockMarkets)
##             DAX    SMI    CAC   FTSE
## [1855,] 5598.32 7952.9 4041.9 5680.4
## [1856,] 5460.43 7721.3 3939.5 5587.6
## [1857,] 5285.78 7447.9 3846.0 5432.8
## [1858,] 5386.94 7607.5 3945.7 5462.2
## [1859,] 5355.03 7552.6 3951.7 5399.5
## [1860,] 5473.72 7676.3 3995.0 5455.0
head(EuStockMarkets,10)
##           DAX    SMI    CAC   FTSE
##  [1,] 1628.75 1678.1 1772.8 2443.6
##  [2,] 1613.63 1688.5 1750.5 2460.2
##  [3,] 1606.51 1678.6 1718.0 2448.2
##  [4,] 1621.04 1684.1 1708.1 2470.4
##  [5,] 1618.16 1686.6 1723.1 2484.7
##  [6,] 1610.61 1671.6 1714.3 2466.8
##  [7,] 1630.75 1682.9 1734.5 2487.9
##  [8,] 1640.17 1703.6 1757.4 2508.4
##  [9,] 1635.47 1697.5 1754.0 2510.5
## [10,] 1645.89 1716.3 1754.3 2497.4
tail(EuStockMarkets,10)
##             DAX    SMI    CAC   FTSE
## [1851,] 5774.38 8139.2 4095.0 5809.7
## [1852,] 5718.70 8170.2 4047.9 5736.1
## [1853,] 5614.77 7943.2 3976.4 5632.5
## [1854,] 5528.12 7846.2 3968.6 5594.1
## [1855,] 5598.32 7952.9 4041.9 5680.4
## [1856,] 5460.43 7721.3 3939.5 5587.6
## [1857,] 5285.78 7447.9 3846.0 5432.8
## [1858,] 5386.94 7607.5 3945.7 5462.2
## [1859,] 5355.03 7552.6 3951.7 5399.5
## [1860,] 5473.72 7676.3 3995.0 5455.0

Ahora, vamos a crear una lista con el mismo contenido que el data frame para que podamos ver la diferencia.

## $Titulacion
## [1] "Economía"   "ADE"        "Sociología" "Magisterio"
## 
## $Edad
## [1] 25 27 25 24

Podemos convertir la lista en una data frame:

y <- data.frame(lista)
y
##   Titulacion Edad
## 1   Economía   25
## 2        ADE   27
## 3 Sociología   25
## 4 Magisterio   24

3.4.3.2 Nombres de filas/columnas

En los data frame que hemos creado las columnas representarían variables y las filas representarían individuos (observaciones).

Si las columnas de un data frame no tienen nombres (en nuestro ejemplo son Titulación y Edad), podemos incluirlos utilizando la función names(). Para incluir nombres a las filas se utiliza la función row.names()

lista2 <- list(c("Economía", "ADE", "Sociología", "Magisterio"), c(25, 27, 25, 24))
z <- data.frame(lista2)
z
##   c..Economía....ADE....Sociología....Magisterio.. c.25..27..25..24.
## 1                                         Economía                25
## 2                                              ADE                27
## 3                                       Sociología                25
## 4                                       Magisterio                24
# Para incluir los nombre a las columnas:
names(z) <- c("Titulación", "Edad")
z
##   Titulación Edad
## 1   Economía   25
## 2        ADE   27
## 3 Sociología   25
## 4 Magisterio   24

También se puede crear un data frame entrando directamente los datos (o para modificarlos) utilizando la función edit()

x <- edit(data.frame(x)) # para modificar un data frame (en este caso el objeto x)
y <- edit(data.frame()) # para crear un nuevo data frame

o podemos visualizar los datos con la función View()

View(x)

3.4.3.3 Eliminando valores NA

En R los valores perdidos se denotan por NA (Not Available). Cuando trabajamos con datos, una de las tareas más importantes que hay que realizar es la de limpiar la base de datos y prepararla para los posteriores análisis (lo veremos más adelante en el curso).

Vamos a hacer una breve introducción a cómo eliminar los valores NA a través del siguiente ejemplo:

x <- c(1,2,NA,NA,5)
malos <- is.na(x)  # identificamos los NA. La función is.na() es una función lógica.
malos
## [1] FALSE FALSE  TRUE  TRUE FALSE
x[!malos]  # el símbolo ! equivale a "lo contrario". Por tanto, en esta línea estamos diciendo "de x, selecciona lo contrario de malos"
## [1] 1 2 5
x
## [1]  1  2 NA NA  5

Ahora supongamos que tenemos dos objetos (dos vectores), que tienen NAs, y nos queremos quedar únicamente con los casos completos. Esta situación se ilustra en el siguiente ejemplo:

x <- c(1,2,NA,4,NA,6)
y <- c("a","b",NA,"d",NA,"f" )

completos <- complete.cases(x,y) # complete.cases() es una función lógica
completos
## [1]  TRUE  TRUE FALSE  TRUE FALSE  TRUE
x[completos]
## [1] 1 2 4 6
y[completos]
## [1] "a" "b" "d" "f"

Por último, vamos a ver lo anterior aplicado a un caso más práctico. Cargamos los datos airquality que se encuentran en el paquete datasets y vamos a seleccionar únicamente los casos que están completos.

data("airquality")
head(airquality)
##   Ozone Solar.R Wind Temp Month Day
## 1    41     190  7.4   67     5   1
## 2    36     118  8.0   72     5   2
## 3    12     149 12.6   74     5   3
## 4    18     313 11.5   62     5   4
## 5    NA      NA 14.3   56     5   5
## 6    28      NA 14.9   66     5   6
length(airquality) # nos dará el número de variables
## [1] 6
dim(airquality) # indicará el número de observaciones (filas) y de variables (columnas)
## [1] 153   6
summary(airquality)  # la función summary() proporciona un resumen de todas las variables de la base de datos
##      Ozone           Solar.R           Wind             Temp      
##  Min.   :  1.00   Min.   :  7.0   Min.   : 1.700   Min.   :56.00  
##  1st Qu.: 18.00   1st Qu.:115.8   1st Qu.: 7.400   1st Qu.:72.00  
##  Median : 31.50   Median :205.0   Median : 9.700   Median :79.00  
##  Mean   : 42.13   Mean   :185.9   Mean   : 9.958   Mean   :77.88  
##  3rd Qu.: 63.25   3rd Qu.:258.8   3rd Qu.:11.500   3rd Qu.:85.00  
##  Max.   :168.00   Max.   :334.0   Max.   :20.700   Max.   :97.00  
##  NA's   :37       NA's   :7                                       
##      Month            Day      
##  Min.   :5.000   Min.   : 1.0  
##  1st Qu.:6.000   1st Qu.: 8.0  
##  Median :7.000   Median :16.0  
##  Mean   :6.993   Mean   :15.8  
##  3rd Qu.:8.000   3rd Qu.:23.0  
##  Max.   :9.000   Max.   :31.0  
## 
completos <- complete.cases(airquality)  # nos dirá si tenemos datos de todas las variables para cada individuo
head(completos)
## [1]  TRUE  TRUE  TRUE  TRUE FALSE FALSE
datos <- airquality[completos,] # de airquality, selecciona todas las columnas de los casos completos 
head(datos)
##   Ozone Solar.R Wind Temp Month Day
## 1    41     190  7.4   67     5   1
## 2    36     118  8.0   72     5   2
## 3    12     149 12.6   74     5   3
## 4    18     313 11.5   62     5   4
## 7    23     299  8.6   65     5   7
## 8    19      99 13.8   59     5   8
dim(datos) # observad que han sido eliminados 42 casos.
## [1] 111   6

3.4.3.4 Selección de datos (Subsetting)

Vamos a aprovechar que hemos cargado los datos de airquality para recordar algunas ideas sobre la selección de datos (observaciones y/o variables) en un data frame e introducir algunas otras.

En primer lugar, seleccionamos las variables: Ozone, Solar.R y Wind.

datos2 <- datos[,1:3]

Ahora, seleccionamos del objeto datos las variables: Ozone, Solar.R y Temp.

datos3 <- datos[,c(1,2,4)]

Sin en lugar de seleccionar variables (columnas) estamos interesados en seleccionar individuos/observaciones (filas):

datos4 <- datos[1:6,]
datos5 <- datos[seq(1,nrow(datos),5),] # ¿qué observaciones estamos seleccionando?

Para seleccionar tanto observaciones como variables no tenemos más que combinar las estrategias anteriores:

datos6 <- datos[seq(1,nrow(datos),5), c(1,2,4)] 

En ocasiones estamos interesados en seleccionar los casos para los que cierta variable toma determinado valor. Por ejemplo, queremos seleccionar las variables Ozone y Temp para todas las observaciones en las que la variable Wind satisfaga un valor:

datos7 <- datos[datos$Wind<=4, c(1,2)] 

datos8 <- datos[datos$Wind>=2 & datos$Wind<=5.1, c(1,2)] 

datos9 <- datos[datos$Wind==4 , c(1,2)] 

Para seleccionar subconjuntos de datos en un data frame también podemos utilizar la función subset().

datos10 <- subset(datos, Month==5 & Day<=15, select=c(Ozone,Solar.R,Temp))

datos11 <- subset(datos, Month !=5 & Day <=15)

3.4.4 Factores

Los factores, que pueden ser ordenados o no ordenados, se utilizan para representar variables de naturaleza categórica.

factor_nominal <- factor(rep(c("Ford","Seat","Renault"),10))
levels(factor_nominal)     # ordena los factores por orden alfabético
## [1] "Ford"    "Renault" "Seat"
nuevo_factor_nominal <- factor(factor_nominal, levels=c("Seat","Renault","Ford"))  # reordenación de factores
levels(nuevo_factor_nominal)
## [1] "Seat"    "Renault" "Ford"

Vamos a cargar la base de datos iris, que se encuentra en el paquete datasets(). Iris contiene información sobre longitud y anchura de pétalos y sépalos y especie de un total de 150 lirios.

data("iris")
str(iris)
## 'data.frame':    150 obs. of  5 variables:
##  $ Sepal.Length: num  5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
##  $ Sepal.Width : num  3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
##  $ Petal.Length: num  1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
##  $ Petal.Width : num  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 ...

Como podemos ver, el tipo de especie (Species) es una variable categórica (o factor) que tiene tres niveles (levels): setosa, versicolor, virginica. Vamos a ver la distribución del tipo de especie con una tabla

levels(iris$Species)
## [1] "setosa"     "versicolor" "virginica"
table(iris$Species)
## 
##     setosa versicolor  virginica 
##         50         50         50

En ocasiones, cuando cargamos variables que son carácter se crean como factores.

Si vamos a realizar un análisis de regresión es conveniente guardar las variables categóricas como factores (R codificará internamente los distintos niveles del factor como enteros). Además, puede que sea de nuestro interés cambiar el orden de los niveles. Para aprender más sobre factores aquí.

3.5 Referencias útiles