# Introducción a R

## Máster en Bioinformática. Universitat de València.

Francisco García García, fgarcia@cipf.es (2021-09-24)

### 1. ¿Qué es R?

### 2. Instalación de R

### 3. Instalación de RStudio

### 4. Empezando a trabajar con R y RStudio

### 5. Principales objetos en R

### 6. Enlaces interesantes

## 1. ¿Qué es R?

- `R` es un entorno de programación que permite hacer análisis estadísticos.

- `R` es de código abierto y pertenece al proyecto GNU de software libre.

- Disponible para las plataformas Linux, Macintosh y Windows.

- `R` es un software orientado tanto a usuarios principiantes com profesionales e investigadores que necesiten analizar y representar gráficamente sus datos.

- `R` es gratuito. No necesitamos ningún tipo de licencia.

## 2. Instalación de R

- Nos dirigimos a la web del proyecto `R`: https://www.r-project.org/

- Seleccionamos Download CRAN y escogemos un servidor para iniciar la descarga.

- Elegimos nuestro sistema operativo y seguimos las indicaciones para la descarga del fichero ejecutable.

- Por ejemplo, con Windows si es la primera vez que instalamos R, seleccionaremos el subdirectorio base y descargaremos el fichero ejecutable.

- Para Linux o OS X hay varias opciones específicas para estos sistemas operativos.

## 3. Instalación de RStudio

- Descargamos el fichero ejecutable desde la web de `RStudio`: https://www.rstudio.com/

- Queremos la opción Desktop y para empezar Free ;)

- Escogemos el fichero correspondiente para nuestro sistema operativo

## 4. Empezando a trabajar con R y RStudio

### Preliminares

Tras iniciar una sesión en RStudio, ya estamos listos para trabajar con R.

Revisemos las 4 áreas de trabajo que se presentan en la interfaz de RStudio

    #esto es una linea comentada

Para salir de R escribir: `q ()`

R se puede utilizar como calculadora

    2+2

    #> [1] 4

    2*3

    #> [1] 6

La asignacion de valores se hace utilizando: `<-` o `=`

    variableA <- 3
    variableA

    #> [1] 3

    variableB <- 4
    variableB

    #> [1] 4

Las variables asi definidas se pueden usar en la calculadora

    variableA * 2

    #> [1] 6

R es case sensitive: mayusculas y minusculas describen elementos diferentes

    VARIABLEA <- 5
    VARIABLEA

    #> [1] 5

    variableA

    #> [1] 3

### Más operadores aritméticos:

    4 - 3

    #> [1] 1

    5 * 10

    #> [1] 50

    10 / 2

    #> [1] 5

    3^5

    #> [1] 243

### Operadores comparativos:

    4 > 3

    #> [1] TRUE

    4 < 3

    #> [1] FALSE

    4 <= 3

    #> [1] FALSE

    4 == 3

    #> [1] FALSE

    4 != 3

    #> [1] TRUE

### Funciones

Todas las funciones en R van siempre seguidas de paréntesis que envuelven los argumentos de la función

    sqrt (3)

    #> [1] 1.732051

    sqrt (variableA)

    #> [1] 1.732051

    SQRT (variableA)   #R es _case sensitive_ no funciona en mayusculas

    #> Error in SQRT(variableA): could not find function "SQRT"

    variableA

    #> [1] 3

    VARIABLEA

    #> [1] 5

    sqrt ("variableA") #cada funcion está definida para un tipo o clase de argumentos

    #> Error in sqrt("variableA"): non-numeric argument to mathematical function

### Acceso al historial de comando

Utilizando los cursores del teclado.

### Funciones para obtener ayuda:

- help(comando) para obtener ayuda sobre la función

- ?comando atajo equivalente a help(comando)

- help.search(“comando”) busca ayuda en la ayuda del sistema

- help.start() para acceder a los manuales instalados con R

- example(comando) para ejecutar los ejemplos disponibles sobre la función comando

## 5. Principales objetos en R

### Clases de objetos en R:

- numeric, character, factor, logical: vectores con elementos del mismo tipo.

- matrix: matrices de 2 dimensiones y con elementos del mismo tipo.

- array: matrices con más de 2 dimensiones y con elementos del mismo tipo.

- data frame: matrices de 2 dimensiones pero con la posibilidad de que los elementos nos sean del mismo tipo.

- list: listas que contienen objetos de diferentes clases.

## 5.1. Vectores

Varios elementos se pueden concatenar en un vector utilizando el operador o funcion: `c ()`

    c (1,2,3)

    #> [1] 1 2 3

    c ("a","b","c")

    #> [1] "a" "b" "c"

Todos los elementos del vector tienen la misma clase. Si no R cambia el tipo de alguno de ellos.

    c ("a","b","c", 1,2,3)

    #> [1] "a" "b" "c" "1" "2" "3"

La longitud es una característica de los vectores que se podemos conocer utilizando la funcion `length`

    length (c (1,2,3))

    #> [1] 3

    length (c ("a","b","c"))

    #> [1] 3

    length (c ("a","b","c", 1,2,3))

    #> [1] 6

Todas las variables en R son vectores de longitud 1

    is.vector (1)

    #> [1] TRUE

    class (1)

    #> [1] "numeric"

    length (1)

    #> [1] 1

    is.vector ("adjgfagkjg")

    #> [1] TRUE

    class ("adjgfagkjg")

    #> [1] "character"

    length ("adjgfagkjg")

    #> [1] 1

    is.vector (TRUE)

    #> [1] TRUE

    class (TRUE)

    #> [1] "logical"

    length (TRUE)

    #> [1] 1

Son lo mismo:

    1

    #> [1] 1

    c (1)

    #> [1] 1

    1 == c (1)

    #> [1] TRUE

    identical (1, c (1))

    #> [1] TRUE

Asignacion de valores a variables

    a <- 4
    a

    #> [1] 4

    b <- c (1,2,3)
    b

    #> [1] 1 2 3

    c <- c (5,4,3,2,1)
    c

    #> [1] 5 4 3 2 1

    d <- c ("a", "b", "c", "d", "e", "f")
    d

    #> [1] "a" "b" "c" "d" "e" "f"

    length (a)

    #> [1] 1

    length (b)

    #> [1] 3

    length (c)

    #> [1] 5

    length (d)

    #> [1] 6

Se puede reasignar valores

    a

    #> [1] 4

    a <- 7
    a

    #> [1] 7

    a <- c ("a","b","c")
    a

    #> [1] "a" "b" "c"

Los vectores pueden ser de varias CLASES

    class (1:10)               #"integer"

    #> [1] "integer"

    class (c (1.0, 2.0, 3.0))  #"numeric"

    #> [1] "numeric"

    class (c ("A", "B", "C"))  #"character"

    #> [1] "character"

    class (c (TRUE, FALSE))    #"logical"

    #> [1] "logical"

Se puede acceder a los elementos del vector por su posición

    d

    #> [1] "a" "b" "c" "d" "e" "f"

    d[1]

    #> [1] "a"

    d[3]

    #> [1] "c"

Varias posiciones del vector se indican a su vez, como un vector numérico

    d[c (1,2,3)]

    #> [1] "a" "b" "c"

    d[c (3,2,1)]  #sigue siendo un vector en otro orden

    #> [1] "c" "b" "a"

quizá sea más claro así:

    v <- c (3,2,1)
    class (v)  ## v es un vector

    #> [1] "numeric"

    d[v]       ## que 'indexa' a otro vector d

    #> [1] "c" "b" "a"

    class (d[c (1,2,3)])  # es un vector nuevo

    #> [1] "character"

    length (d[c (1,2,3)]) # con longitud diferente

    #> [1] 3

Se puede acceder a todo el vector menos algunas posiciones

    d

    #> [1] "a" "b" "c" "d" "e" "f"

    d[-1]

    #> [1] "b" "c" "d" "e" "f"

    d[c (-1,-3,-5)]

    #> [1] "b" "d" "f"

    d[ - c (1,3,5)]  # el operador - se aplica a todos los elementos del vector

    #> [1] "b" "d" "f"

    #d[c (1, 3, -5)] # no se pueden mezclar las dos formas de acceso

El operador ':' indica una secuencia de enteros

    10:15

    #> [1] 10 11 12 13 14 15

    c (10, 11, 12 ,13 ,14, 15)

    #> [1] 10 11 12 13 14 15

    identical (10:15, c(10, 11, 12 ,13 ,14, 15))

    #> [1] FALSE

    class (10:15)

    #> [1] "integer"

    class (c(10, 11, 12 ,13 ,14, 15))

    #> [1] "numeric"

Al ser un vector, se puede usar para indexar las posiciones de otros

    d[3:1]

    #> [1] "c" "b" "a"

OBS: los vectores tambien se pueden nombrar

    v <- 101:103
    v

    #> [1] 101 102 103

    names (v)

    #> NULL

    names (v) <- c ("n1", "n2", "n3")
    v

    #>  n1  n2  n3
    #> 101 102 103

    names (v)

    #> [1] "n1" "n2" "n3"

de hecho se pueden nombrar al definirlos

    c (N1 = "primer valor", N2 = "segundo valor")

    #>              N1              N2
    #>  "primer valor" "segundo valor"

Podemos acceder a las posiciones de los vectores por sus nombres si las tienen

    v[2]

    #>  n2
    #> 102

    v["n2"]

    #>  n2
    #> 102

    v[3:2]

    #>  n3  n2
    #> 103 102

    v[c("n3", "n2")]

    #>  n3  n2
    #> 103 102

Tambien se puede acceder a los elementos de un vector indexando con vectores logicos

    v

    #>  n1  n2  n3
    #> 101 102 103

    logico <- c(TRUE, FALSE, TRUE)
    is.vector (logico)

    #> [1] TRUE

    class (logico)

    #> [1] "logical"

    v[logico]

    #>  n1  n3
    #> 101 103

### Operaciones entre vectores

Las operaciones entre vectores se realizan entre los elementos de vectores segun la posicion

    c (1,1,2,3) + c (4,5,6,9)

    #> [1]  5  6  8 12

    A <- c (1,1,2,3)
    B <- c (4,5,6,9)

    A + B

    #> [1]  5  6  8 12

    A * B

    #> [1]  4  5 12 27

    B / A

    #> [1] 4 5 3 3

potencias

    A^2

    #> [1] 1 1 4 9

    A^3

    #> [1]  1  1  8 27

potencias (forma alternativa)

    A**2

    #> [1] 1 1 4 9

    3*A ## es tambien una operacion entre elementos de vectores; el vector c(3) se extiende automaticamente

    #> [1] 3 3 6 9

    1/A

    #> [1] 1.0000000 1.0000000 0.5000000 0.3333333

    1/B

    #> [1] 0.2500000 0.2000000 0.1666667 0.1111111

Generalmente, vectores de diferente longitud se reciclan en las operaciones

    A

    #> [1] 1 1 2 3

    c (2,3) * A

    #> [1] 2 3 4 9

    c (3,3) * c (1,2,3,4)

    #> [1]  3  6  9 12

    c (1,2) * c (1,2,3,4) #es lo mismo que:

    #> [1] 1 4 3 8

    c (1,2,1,2) * c (1,2,3,4)

    #> [1] 1 4 3 8

La longitud de uno de los vectores ha de ser multiplo de la longitud del otro vector. Este tipo de repeticiones suele funcionar con todas las operaciones entre vectores.

    c (1,2,1) * c (1,2,3,4)

    #> Warning in c(1, 2, 1) * c(1, 2, 3, 4): longer object length is not a multiple of
    #> shorter object length

    #> [1] 1 4 3 4

Missing values: NA (not available)

    m <- c (1:2, NA, 4:6)
    m

    #> [1]  1  2 NA  4  5  6

    class (m)

    #> [1] "integer"

    class (m[3])

    #> [1] "integer"

    m[3]

    #> [1] NA

    n <- c ("a", NA, "b")
    n

    #> [1] "a" NA  "b"

    class (n)

    #> [1] "character"

    class (n[2])

    #> [1] "character"

    n[2]

    #> [1] NA

Podemos saber que elementos de un vector son missing

    is.na (m)

    #> [1] FALSE FALSE  TRUE FALSE FALSE FALSE

    is.na (n)

    #> [1] FALSE  TRUE FALSE

los NA se propagan al hacer operaciones

    m

    #> [1]  1  2 NA  4  5  6

    m+1

    #> [1]  2  3 NA  5  6  7

### Operaciones no numericas entre vectores

No todas las operaciones entre vectores son numericas. Por ejemplo la funcion para concatenar textos:

    paste ("texto primero", "texto segundo", sep = " ")

    #> [1] "texto primero texto segundo"

    paste ("texto primero", "texto segundo", sep = "_")

    #> [1] "texto primero_texto segundo"

    paste ("texto primero", "texto segundo", sep = " Y ")

    #> [1] "texto primero Y texto segundo"

    paste ( c("texto1", "texto2"), c("TEXTO1", "TEXTO2", "TEXTO3", "TEXTO4"), sep = " ")

    #> [1] "texto1 TEXTO1" "texto2 TEXTO2" "texto1 TEXTO3" "texto2 TEXTO4"

Tambien hay operaciones logicas definidas para los vectores logicos

    vectorlogico <- is.na (m)
    vectorlogico

    #> [1] FALSE FALSE  TRUE FALSE FALSE FALSE

    class (vectorlogico)

    #> [1] "logical"

    length (vectorlogico)

    #> [1] 6

    vectorlogico[1:3]

    #> [1] FALSE FALSE  TRUE

Operadores logicos: NEGACION

    !TRUE

    #> [1] FALSE

    !FALSE

    #> [1] TRUE

    !vectorlogico       ##afectan a todos los elementos del vector

    #> [1]  TRUE  TRUE FALSE  TRUE  TRUE  TRUE

Operadres logicos: Y

    TRUE  & TRUE

    #> [1] TRUE

    TRUE  & FALSE

    #> [1] FALSE

    FALSE & FALSE

    #> [1] FALSE

    c (TRUE, TRUE) & c (TRUE, FALSE)

    #> [1]  TRUE FALSE

Operadres logicos: O

    TRUE | TRUE

    #> [1] TRUE

    TRUE | FALSE

    #> [1] TRUE

    FALSE | FALSE

    #> [1] FALSE

    c (TRUE, TRUE) | c (TRUE, FALSE)

    #> [1] TRUE TRUE

Son ejemplo de operaciones en las que operar con NA no siempre devuelve NA

    NA & TRUE

    #> [1] NA

    NA & FALSE

    #> [1] FALSE

    NA | FALSE

    #> [1] NA

    NA | TRUE

    #> [1] TRUE

    !NA

    #> [1] NA

Ejemplo de cambio de tipo o clase: Se puede hacer operaciones aritmeticas con variables logicas

    2 * TRUE

    #> [1] 2

    2 * FALSE

    #> [1] 0

    TRUE + TRUE

    #> [1] 2

    TRUE + FALSE

    #> [1] 1

    FALSE == 0

    #> [1] TRUE

    TRUE  == 1

    #> [1] TRUE

    TRUE  == 2

    #> [1] FALSE

A la inversa se pueden hacer operaciones logicas con datos numericos

    0 | 0

    #> [1] FALSE

    0 | 1

    #> [1] TRUE

    1 | 1

    #> [1] TRUE

    0 & 0

    #> [1] FALSE

    0 & 1

    #> [1] FALSE

    1 & 1

    #> [1] TRUE

    !1

    #> [1] FALSE

    !0

    #> [1] TRUE

    !2

    #> [1] FALSE

    !3

    #> [1] FALSE

    !-3

    #> [1] FALSE

    as.logical (-5:5)

    #>  [1]  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE

Vamos a realizar los ejercicios sobre vectores!

## 5.2. Matrices

Cuando tenemos varios vectores …

    vector1 <- 1:4
    vector2 <- c (12,34,56,34)

    vector1

    #> [1] 1 2 3 4

    vector2

    #> [1] 12 34 56 34

estos se pueden agrupar en estructuras más complejas

    cbind (vector1, vector2) #column bind

    #>      vector1 vector2
    #> [1,]       1      12
    #> [2,]       2      34
    #> [3,]       3      56
    #> [4,]       4      34

    rbind (vector1, vector2) #row bind

    #>         [,1] [,2] [,3] [,4]
    #> vector1    1    2    3    4
    #> vector2   12   34   56   34

Como en otras operaciones o cálculos, vectores de diferentes tamaños se reciclan

    vector3 <- 1:2
    vector3

    #> [1] 1 2

    cbind (vector3, vector2) #column bind

    #>      vector3 vector2
    #> [1,]       1      12
    #> [2,]       2      34
    #> [3,]       1      56
    #> [4,]       2      34

    rbind (vector3, vector2) #row bind

    #>         [,1] [,2] [,3] [,4]
    #> vector3    1    2    1    2
    #> vector2   12   34   56   34

Uniendo por filas o columnas generamos una nueva clase de objetos

    class (cbind (vector3, vector2)) #es una matriz

    #> [1] "matrix"

La función `matrix` define matrices por columnas (por defecto)

    M <- matrix (c (vector1, vector2), nrow = 4)
    M

    #>      [,1] [,2]
    #> [1,]    1   12
    #> [2,]    2   34
    #> [3,]    3   56
    #> [4,]    4   34

    class (M)

    #> [1] "matrix"

Funciones útiles definidas sobre matrices

    nrow (M) #número de filas

    #> [1] 4

    ncol (M) #número de columnas

    #> [1] 2

    dim (M)  #dimensión

    #> [1] 4 2

Estas funciones no están definidas para otros tipos de objetos

    dim (vector1)

    #> NULL

Operaciones con matrices

    M

    #>      [,1] [,2]
    #> [1,]    1   12
    #> [2,]    2   34
    #> [3,]    3   56
    #> [4,]    4   34

    M*2

    #>      [,1] [,2]
    #> [1,]    2   24
    #> [2,]    4   68
    #> [3,]    6  112
    #> [4,]    8   68

    M+1

    #>      [,1] [,2]
    #> [1,]    2   13
    #> [2,]    3   35
    #> [3,]    4   57
    #> [4,]    5   35

    M

    #>      [,1] [,2]
    #> [1,]    1   12
    #> [2,]    2   34
    #> [3,]    3   56
    #> [4,]    4   34

    M+(0:1)  #reciclado del vector 0:1 por columnas

    #>      [,1] [,2]
    #> [1,]    1   12
    #> [2,]    3   35
    #> [3,]    3   56
    #> [4,]    5   35

    t (M) #traspuesta

    #>      [,1] [,2] [,3] [,4]
    #> [1,]    1    2    3    4
    #> [2,]   12   34   56   34

Las columnas de las matrices se pueden nombrar

    colnames (M) <- c ("v1", "v2")
    M

    #>      v1 v2
    #> [1,]  1 12
    #> [2,]  2 34
    #> [3,]  3 56
    #> [4,]  4 34

y los nombres se pueden recuperar

    nombres <- colnames (M)
    nombres

    #> [1] "v1" "v2"

en un vector de caracteres (colnames devuelve un vector)

    class (nombres)

    #> [1] "character"

    length (nombres)

    #> [1] 2

También estan definidos los nombres de las filas aunque por defecto puedan ser un elemento nulo

    rownames (M)

    #> NULL

    rn <- rownames (M) #es un elemento NULL
    rn

    #> NULL

    length (rn)

    #> [1] 0

    class (rn)  #tiene clase propia diferente de la de vector

    #> [1] "NULL"

Asignamos estos nombres a las filas de la matriz

    c ("row1", "row2", "row3", "row4")

    #> [1] "row1" "row2" "row3" "row4"

    paste ("row", 1:4, sep = "") #otra forma de escribir los nombres

    #> [1] "row1" "row2" "row3" "row4"

    rownames (M) <- c ("row1", "row2", "row3", "row4") #ASIGNANDO nombres a las filas
    M

    #>      v1 v2
    #> row1  1 12
    #> row2  2 34
    #> row3  3 56
    #> row4  4 34

    rownames (M)

    #> [1] "row1" "row2" "row3" "row4"

cambiando los nombres

    colnames (M) <- c ("col1", "col2")
    M

    #>      col1 col2
    #> row1    1   12
    #> row2    2   34
    #> row3    3   56
    #> row4    4   34

R comprueba que las dimensiones son correctas y si no lo son, devuelve ERRORES

    # colnames (M) <- c ("col1", "col2", "col3")

### Acceso a los elementos de la matriz según su posición

    M

    #>      col1 col2
    #> row1    1   12
    #> row2    2   34
    #> row3    3   56
    #> row4    4   34

    M[2, 1] #fila 2, columna 1

    #> [1] 2

    M[ , 1] #toda la columna 1

    #> row1 row2 row3 row4
    #>    1    2    3    4

    M[2,  ] #toda la fila 2

    #> col1 col2
    #>    2   34

    class (M)

    #> [1] "matrix"

    class (M[,1])  ##recuperamos los vectores (columna)

    #> [1] "numeric"

    class (M[2,])  ##recuperamos los vectores (fila)

    #> [1] "numeric"

    dim (M)         #la matriz tiene dimensión

    #> [1] 4 2

    dim (M[,1])     #un vector no tiene dimensión

    #> NULL

    dim (M[2,])

    #> NULL

    length (M[,1])  #un vector tiene longitud

    #> [1] 4

    length (M[2,])

    #> [1] 2

Podemos acceder a varias filas o columnas a la vez

    M

    #>      col1 col2
    #> row1    1   12
    #> row2    2   34
    #> row3    3   56
    #> row4    4   34

    M[1:2,]

    #>      col1 col2
    #> row1    1   12
    #> row2    2   34

    M[c(1,3),]

    #>      col1 col2
    #> row1    1   12
    #> row3    3   56

    M[c(1,3), 1]

    #> row1 row3
    #>    1    3

    M[c(1,3), 2]

    #> row1 row3
    #>   12   56

El resultado es entonces una matriz

    class (M[1:2,])

    #> [1] "matrix"

Se puede utilizar este tipo de acceso para reordenar filas y columnas de la matriz

    M[,c(2,1)] #reordenar la matriz. Cambiamos las columnas.

    #>      col2 col1
    #> row1   12    1
    #> row2   34    2
    #> row3   56    3
    #> row4   34    4

    M[c(1,3), 2] #es un vector con nombres

    #> row1 row3
    #>   12   56

Podemos acceder a los elementos de las matrices tambieen para modificar su valor

    M

    #>      col1 col2
    #> row1    1   12
    #> row2    2   34
    #> row3    3   56
    #> row4    4   34

    M[1, 1] <- 1000
    M

    #>      col1 col2
    #> row1 1000   12
    #> row2    2   34
    #> row3    3   56
    #> row4    4   34

    M[,2] <- M[,2] * 10
    M

    #>      col1 col2
    #> row1 1000  120
    #> row2    2  340
    #> row3    3  560
    #> row4    4  340

### Selección de filas y columnas utilizando sus nombres

Hemos visto como podemos acceder a las posiciones (filas y columnas) de las matrices según su posición, pero tambieen se puede acceder a ellos utilizando sus nombres, si los tienen

    M

    #>      col1 col2
    #> row1 1000  120
    #> row2    2  340
    #> row3    3  560
    #> row4    4  340

    M[2,2]

    #> [1] 340

    M["row2","col2"]

    #> [1] 340

    M[,c("col2", "col1")]

    #>      col2 col1
    #> row1  120 1000
    #> row2  340    2
    #> row3  560    3
    #> row4  340    4

    M[c("row3", "row1"),]

    #>      col1 col2
    #> row3    3  560
    #> row1 1000  120

    M[c("row3", "row1"), 1] #se pueden combinar las dos notaciones

    #> row3 row1
    #>    3 1000

El acceso nos permite no solo obtener el valor sino modificarlo

    M[c("row3", "row1"), 1]

    #> row3 row1
    #>    3 1000

    M[c("row3", "row1"), 1] <- 0
    M[c("row3", "row1"), 1]

    #> row3 row1
    #>    0    0

## Selección de filas y columnas utilizando variables booleanas (o indicadores)

Se pueden usar vectores lógicos para “recortar” las filas y columnas de una matriz

    M

    #>      col1 col2
    #> row1    0  120
    #> row2    2  340
    #> row3    0  560
    #> row4    4  340

    M[c(TRUE, FALSE, FALSE, TRUE), c(FALSE, TRUE)]

    #> row1 row4
    #>  120  340

Se pueden combinar las formas de acceso

    M[c(1, 4), c(FALSE, TRUE)]

    #> row1 row4
    #>  120  340

Y se pueden usar para reasignar valores

    M[c(1, 4), c(FALSE, TRUE)]

    #> row1 row4
    #>  120  340

    M[c(1, 4), c(FALSE, TRUE)] <- M[c(4, 1), c(FALSE, TRUE)]
    M[c(1, 4), c(FALSE, TRUE)]

    #> row1 row4
    #>  340  120

### Tipo o clase de los elementos de una matriz

Todos los elementos de una matriz son de la misma clase. Esto la diferencia de un data.frame (ver más adelante)

    class (M)

    #> [1] "matrix"

    class (M[1,])

    #> [1] "numeric"

    class (M[,1])

    #> [1] "numeric"

    class (M[1,1])

    #> [1] "numeric"

Se pueden añadir filas o columnas a la matriz sobre escribiendo el objeto

    M

    #>      col1 col2
    #> row1    0  340
    #> row2    2  340
    #> row3    0  560
    #> row4    4  120

    M <- cbind (M, c (-5,-10))
    M

    #>      col1 col2
    #> row1    0  340  -5
    #> row2    2  340 -10
    #> row3    0  560  -5
    #> row4    4  120 -10

    class (M)

    #> [1] "matrix"

    class (M[1,])

    #> [1] "numeric"

    class (M[,1])

    #> [1] "numeric"

    class (M[1,1])

    #> [1] "numeric"

Se puede replicar todo el objeto para utilizarlo mas adelante

    N <- M

esto crea una copia de la matriz independiente de la original. al modificar los valores de una matriz NO se modifican los de la otra.

    N[1,1] <- 1000
    N

    #>      col1 col2
    #> row1 1000  340  -5
    #> row2    2  340 -10
    #> row3    0  560  -5
    #> row4    4  120 -10

    M

    #>      col1 col2
    #> row1    0  340  -5
    #> row2    2  340 -10
    #> row3    0  560  -5
    #> row4    4  120 -10

R cambia automáticamente el tipo de toda la matriz cuando es necesario

    M <- cbind (M, "hola")

    M

    #>      col1 col2
    #> row1 "0"  "340" "-5"  "hola"
    #> row2 "2"  "340" "-10" "hola"
    #> row3 "0"  "560" "-5"  "hola"
    #> row4 "4"  "120" "-10" "hola"

    class (M)

    #> [1] "matrix"

    class (M[1,])

    #> [1] "character"

    class (M[,1])

    #> [1] "character"

    class (M[1,1])

    #> [1] "character"

OBS: las nuevas no tienen nombre

    M[,3:4]

    #>
    #> row1 "-5"  "hola"
    #> row2 "-10" "hola"
    #> row3 "-5"  "hola"
    #> row4 "-10" "hola"

o mejor dicho, lo tienen vacío

    colnames (M)  # "" indica un texto de longitud 0

    #> [1] "col1" "col2" ""     ""

pero podemos incluirlos

    colnames (M)[3] <- "COL3"
    colnames (M)[4] <- "COL4"

o mas rápido

    colnames (M)[3:4] <- c ("col3", "col4")

Se puede usar una matriz booleana para indexar una matriz de las mismas dimensiones

    N > 500  ##matriz lógica

    #>       col1  col2
    #> row1  TRUE FALSE FALSE
    #> row2 FALSE FALSE FALSE
    #> row3 FALSE  TRUE FALSE
    #> row4 FALSE FALSE FALSE

para extraer los valores deseados en un vector

    N[N > 500]

    #> [1] 1000  560

o para reemplazar los valores deseados

    N[N > 500] <- NA
    N

    #>      col1 col2
    #> row1   NA  340  -5
    #> row2    2  340 -10
    #> row3    0   NA  -5
    #> row4    4  120 -10

Ahora practiquemos con los ejercicios 1 y 2 sobre matrices.

## 5.3. Listas

Un grupo de objetos de R

    unVector <- 1:10
    unVector

    #>  [1]  1  2  3  4  5  6  7  8  9 10

    otroVector <- LETTERS ##LETTERS es una variable definida internamente en R
    otroVector

    #>  [1] "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q" "R" "S"
    #> [20] "T" "U" "V" "W" "X" "Y" "Z"

    unaMatriz <- cbind (1:10, 10:1)
    rownames (unaMatriz) <- LETTERS[1:10]  #con nombres en las filas
    colnames (unaMatriz) <- letters[1:2]   #y en las columnas
    unaMatriz

    #>    a  b
    #> A  1 10
    #> B  2  9
    #> C  3  8
    #> D  4  7
    #> E  5  6
    #> F  6  5
    #> G  7  4
    #> H  8  3
    #> I  9  2
    #> J 10  1

se pueden agrupar en una estructura de lista

    lista0 <- list (unVector, otroVector, unaMatriz)
    class (lista0)

    #> [1] "list"

    length (lista0)

    #> [1] 3

Acceso por orden o posición

    lista0[1]

    #> [[1]]
    #>  [1]  1  2  3  4  5  6  7  8  9 10

    lista0[1:2]

    #> [[1]]
    #>  [1]  1  2  3  4  5  6  7  8  9 10
    #>
    #> [[2]]
    #>  [1] "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q" "R" "S"
    #> [20] "T" "U" "V" "W" "X" "Y" "Z"

    lista0[c(1,3)]  #reordenaciones

    #> [[1]]
    #>  [1]  1  2  3  4  5  6  7  8  9 10
    #>
    #> [[2]]
    #>    a  b
    #> A  1 10
    #> B  2  9
    #> C  3  8
    #> D  4  7
    #> E  5  6
    #> F  6  5
    #> G  7  4
    #> H  8  3
    #> I  9  2
    #> J 10  1

OBS: el acceso con un un único corchete conserva la estructura de lista

    class (lista0[1])

    #> [1] "list"

    length (lista0[1])

    #> [1] 1

Hay que usar dos corchetes para obtener el objeto guardado sin la 'envoltura' de lista

    lista0[[1]]

    #>  [1]  1  2  3  4  5  6  7  8  9 10

    class (lista0[[1]])

    #> [1] "integer"

    length (lista0[[1]])

    #> [1] 10

Los elementos de la lista se pueden nombrar

    names (lista0)

    #> NULL

    names (lista0) <- c("uno", "dos", "tres")
    names (lista0)

    #> [1] "uno"  "dos"  "tres"

De hecho se puede generar la lista ya con los nombres

    lista1 <- list (uno=unVector, dos=otroVector, tres=unaMatriz)
    lista1

    #> $uno
    #>  [1]  1  2  3  4  5  6  7  8  9 10
    #>
    #> $dos
    #>  [1] "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q" "R" "S"
    #> [20] "T" "U" "V" "W" "X" "Y" "Z"
    #>
    #> $tres
    #>    a  b
    #> A  1 10
    #> B  2  9
    #> C  3  8
    #> D  4  7
    #> E  5  6
    #> F  6  5
    #> G  7  4
    #> H  8  3
    #> I  9  2
    #> J 10  1

Entonces se puede acceder por nombre a los elementos de la lista

    lista1["uno"]

    #> $uno
    #>  [1]  1  2  3  4  5  6  7  8  9 10

    lista1[c("uno", "dos")]

    #> $uno
    #>  [1]  1  2  3  4  5  6  7  8  9 10
    #>
    #> $dos
    #>  [1] "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q" "R" "S"
    #> [20] "T" "U" "V" "W" "X" "Y" "Z"

Con las mismas consideraciones sobre los corchetes

    class  (lista1["uno"])  #corchete único mantiene la estructura de lista

    #> [1] "list"

    length (lista1["uno"])  #alrededor del objeto

    #> [1] 1

    class  (lista1[["uno"]])  #corchete doble extrae el objeto de la posicion

    #> [1] "integer"

    length (lista1[["uno"]])  #en su propio formato

    #> [1] 10

Cuando las listas tiene nombres, se puede además utilizar la notacion $ que es equivalente a la del doble corchete

    lista1$uno

    #>  [1]  1  2  3  4  5  6  7  8  9 10

    class  (lista1$uno)

    #> [1] "integer"

    length (lista1$uno)

    #> [1] 10

Realiza el ejercicio preparado sobre listas.

## 5.4. Data frames y factores

### Dataframes

Vectores, listas y matrices (como columnas de vectores) en R

    vector <- c(TRUE, FALSE, FALSE, TRUE)
    vector

    #> [1]  TRUE FALSE FALSE  TRUE

    lista <- list("n" = 1:4, "l" = letters[1:4])
    lista

    #> $n
    #> [1] 1 2 3 4
    #>
    #> $l
    #> [1] "a" "b" "c" "d"

    matriz <- matrix(c(22, 33), nrow = 4, ncol = 2, byrow = TRUE)
    matriz

    #>      [,1] [,2]
    #> [1,]   22   33
    #> [2,]   22   33
    #> [3,]   22   33
    #> [4,]   22   33

se pueden transformar en una estructura de matricial data.frame siempre que todos los vectores que se van a combinar tengan la misma longitud.

    data.frame (vector, lista)   #Cada elemento de la lista es una columna del data frame

    #>   vector n l
    #> 1   TRUE 1 a
    #> 2  FALSE 2 b
    #> 3  FALSE 3 c
    #> 4   TRUE 4 d

    data1 <- data.frame(matriz) #Cada columna de la matriz es una columna del data frame
    data1

    #>   X1 X2
    #> 1 22 33
    #> 2 22 33
    #> 3 22 33
    #> 4 22 33

    rownames (matriz) <- LETTERS[1:4]
    colnames (matriz) <- letters[1:2]
    data2 <- data.frame(lista, matriz, vector)
    data2

    #>   n l  a  b vector
    #> A 1 a 22 33   TRUE
    #> B 2 b 22 33  FALSE
    #> C 3 c 22 33  FALSE
    #> D 4 d 22 33   TRUE

    class(data2)

    #> [1] "data.frame"

    length(data2)

    #> [1] 5

Las columnas de los data.frames siempre tienen un nombre asignado… aunque sea por defecto. En este caso

    data1

    #>   X1 X2
    #> 1 22 33
    #> 2 22 33
    #> 3 22 33
    #> 4 22 33

    colnames(data1)

    #> [1] "X1" "X2"

o el nombre de los objetos por los que estan compuestos

    data2

    #>   n l  a  b vector
    #> A 1 a 22 33   TRUE
    #> B 2 b 22 33  FALSE
    #> C 3 c 22 33  FALSE
    #> D 4 d 22 33   TRUE

    colnames(data2)

    #> [1] "n"      "l"      "a"      "b"      "vector"

Estos nombres se pueden recuperar

    nc <- colnames(data2)
    nc

    #> [1] "n"      "l"      "a"      "b"      "vector"

    class (nc)

    #> [1] "character"

    length (nc)

    #> [1] 5

y también se pueden modificar

    colnames (data2) <- paste0 ("dato", 1:5)
    colnames (data2)

    #> [1] "dato1" "dato2" "dato3" "dato4" "dato5"

También estan definidos por defecto los nombres de las filas de los data frames

    data1

    #>   X1 X2
    #> 1 22 33
    #> 2 22 33
    #> 3 22 33
    #> 4 22 33

    rownames(data1)

    #> [1] "1" "2" "3" "4"

    nr <- rownames(data1)
    nr

    #> [1] "1" "2" "3" "4"

    class(nr)

    #> [1] "character"

    length(nr)

    #> [1] 4

Las filas heredan los nombres de las filas de las matrices

    matriz

    #>    a  b
    #> A 22 33
    #> B 22 33
    #> C 22 33
    #> D 22 33

    data2

    #>   dato1 dato2 dato3 dato4 dato5
    #> A     1     a    22    33  TRUE
    #> B     2     b    22    33 FALSE
    #> C     3     c    22    33 FALSE
    #> D     4     d    22    33  TRUE

    nr <- rownames(data2)
    nr

    #> [1] "A" "B" "C" "D"

    class(nr)

    #> [1] "character"

Modificando los nombres:

    rownames(data2) <- paste0("obs", 1:4)
    data2

    #>      dato1 dato2 dato3 dato4 dato5
    #> obs1     1     a    22    33  TRUE
    #> obs2     2     b    22    33 FALSE
    #> obs3     3     c    22    33 FALSE
    #> obs4     4     d    22    33  TRUE

Todas las filas deben tener un nombre unico

    ## rownames(data2)[2] <- "obs1" #Devuelve un error por duplicacion de nombres.

Las columnas de los data frames se reciclan

    data1[,3] <- 44
    data1

    #>   X1 X2 V3
    #> 1 22 33 44
    #> 2 22 33 44
    #> 3 22 33 44
    #> 4 22 33 44

Acceso a los elementos del data frame por posicion

    data2

    #>      dato1 dato2 dato3 dato4 dato5
    #> obs1     1     a    22    33  TRUE
    #> obs2     2     b    22    33 FALSE
    #> obs3     3     c    22    33 FALSE
    #> obs4     4     d    22    33  TRUE

    data2[3,5] #fila 3, columna 1

    #> [1] FALSE

    class(data2[3,5])

    #> [1] "logical"

    length(data2[3,5])

    #> [1] 1

OBS: las columnas se pueden recuperar como vectores

    data2[ ,1] #columna 1

    #> [1] 1 2 3 4

    class(data2[ ,1]) #recuperamos los vectores columna

    #> [1] "integer"

    length(data2[ ,1])

    #> [1] 4

o como data.frame

    data2[1]

    #>      dato1
    #> obs1     1
    #> obs2     2
    #> obs3     3
    #> obs4     4

    class(data2[1])

    #> [1] "data.frame"

    length(data2[1])

    #> [1] 1

OBS: el acceso a filas enteras devuelve una estructura de data frame

    data2[1, ] #fila 1

    #>      dato1 dato2 dato3 dato4 dato5
    #> obs1     1     a    22    33  TRUE

    class(data2[1, ])

    #> [1] "data.frame"

    length(data2[1, ])

    #> [1] 5

Podemos acceder a varias filas y columnas a la vez

    data2

    #>      dato1 dato2 dato3 dato4 dato5
    #> obs1     1     a    22    33  TRUE
    #> obs2     2     b    22    33 FALSE
    #> obs3     3     c    22    33 FALSE
    #> obs4     4     d    22    33  TRUE

    data2[1:2, c(3,5)]

    #>      dato3 dato5
    #> obs1    22  TRUE
    #> obs2    22 FALSE

    class(data2[1:2, c(3,5)])

    #> [1] "data.frame"

Acceso a los elementos del data frame por nombre

    data2["obs3",]

    #>      dato1 dato2 dato3 dato4 dato5
    #> obs3     3     c    22    33 FALSE

    data2[,c("dato2","dato5")]

    #>      dato2 dato5
    #> obs1     a  TRUE
    #> obs2     b FALSE
    #> obs3     c FALSE
    #> obs4     d  TRUE

    data2["dato1"]

    #>      dato1
    #> obs1     1
    #> obs2     2
    #> obs3     3
    #> obs4     4

    data2[1, c("dato2","dato5")]

    #>      dato2 dato5
    #> obs1     a  TRUE

OBS: a las filas del data frame también se puede acceder utilizando la notacion $

    data2$dato1

    #> [1] 1 2 3 4

    class(data2$dato1)

    #> [1] "integer"

    data2[1:2,]$dato1

    #> [1] 1 2

    class(data2[1:2,]$dato1)

    #> [1] "integer"

### Funciones útiles sobre data frames

Muchas funciones son compartidas con las matrices Funciones vistas para matrices

    nrow(data2) #numero de filas

    #> [1] 4

    ncol(data2) #numero de columnas

    #> [1] 5

    dim(data2) #dimension

    #> [1] 4 5

Otras funciones

    attach (data2) #hace "visible" el data frame, de modo que se puede acceder directamente a las variables por su nombre
    search()

    #>  [1] ".GlobalEnv"        "data2"             "package:knitr"
    #>  [4] "package:rmarkdown" "package:stats"     "package:graphics"
    #>  [7] "package:grDevices" "package:utils"     "package:datasets"
    #> [10] "package:methods"   "Autoloads"         "package:base"

    dato3

    #> [1] 22 22 22 22

    detach (data2) #dejamos de hacer "visible" el data frame
    ## dato1 ## Ya no se puede acceder a este dato. Devuelve error

## FACTORES

    data2

    #>      dato1 dato2 dato3 dato4 dato5
    #> obs1     1     a    22    33  TRUE
    #> obs2     2     b    22    33 FALSE
    #> obs3     3     c    22    33 FALSE
    #> obs4     4     d    22    33  TRUE

    data2[,2]

    #> [1] a b c d
    #> Levels: a b c d

    class(data2[,2])

    #> [1] "factor"

La función `factor` define el objeto factor (algunas otras funciones también devuelven factores)

    f <- factor(c(LETTERS[1:3], "A", "C"))
    class(f)

    #> [1] "factor"

Los elementos de los factores se pueden nombrar (NULL por defecto)

    f

    #> [1] A B C A C
    #> Levels: A B C

    names(f) <- letters[1:5]
    f

    #> a b c d e
    #> A B C A C
    #> Levels: A B C

    names(f)

    #> [1] "a" "b" "c" "d" "e"

Acceso a los elementos del factor

    f[1] #por posicion

    #> a
    #> A
    #> Levels: A B C

    class(f[1])

    #> [1] "factor"

    length(f[1])

    #> [1] 1

    f["a"] #por nombre (si los tienen)

    #> a
    #> A
    #> Levels: A B C

    class(f["a"])

    #> [1] "factor"

Categorías de los factores. Funcion `levels`

    f

    #> a b c d e
    #> A B C A C
    #> Levels: A B C

    levels(f)

    #> [1] "A" "B" "C"

    nlevels(f) #número de niveles

    #> [1] 3

## Operaciones sobre factores

La única operación entre factores permitida es la comparación

    f1 <- factor(c(1:3,5:4))
    f1

    #> [1] 1 2 3 5 4
    #> Levels: 1 2 3 4 5

    f2 <- factor(c(3:1, 4:5))
    f2

    #> [1] 3 2 1 4 5
    #> Levels: 1 2 3 4 5

    f1 == f2

    #> [1] FALSE  TRUE FALSE FALSE FALSE

    f1 != f2

    #> [1]  TRUE FALSE  TRUE  TRUE  TRUE

OBS: La comparación solo se puede realizar entre factores con niveles idénticos

    ## f == f1 #Devuelve error

Vamos a los ejercicios!

## 6. Enlaces interesantes:

- Quick-R Web con recursos para trabajar con R.

- r-tutor An R Introduction to Statistics.