# Introduccion a R: matrices

David Montaner (2014-03-31)

Script que introduce los comandos mas basicos de `R` relacionados con matrices.

    # rm (list = ls ())

Vectores

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

    vector1

    #> [1] 1 2 3 4

    vector2

    #> [1] 12 34 56 34

Se pueden agrupar en estructuras mas 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 calculos, vectores de diferentes tamaños se reciclan

    vector3 <- 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"

## MATRICES

La funcion `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 utiles definidas sobre matrices

    nrow (M) #numero de filas

    #> [1] 4

    ncol (M) #numero de columnas

    #> [1] 2

    dim (M)  #dimension

    #> [1] 4 2

no estan 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

Tambien 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 segun su posicion

    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 dimension

    #> [1] 4 2

    dim (M[,1])     #un vector no tiene dimension

    #> 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 tambien 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

## Seleccion de filas y columnas utilizando sus nombres

Hemos visto como podemos acceder a las posiciones (filas y columnas) de las matrices segun su posicion, pero tambien 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

## Seleccion de filas y columnas utilizando variables booleanas (o indicadores)

Se pueden usar vectores logicos 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 mas 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

R cambia automaticamente 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 vacio

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

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

pero podemos incluirlos

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

o mas rapido

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

# LOOPS con matrices

Se puede iterar en las dos dimensiones de la matriz utilizando indices, o nombres

    for (i in 1:nrow (M)) {
      for (j in colnames (M)) {
        cat ("\n") #linea nueva
        ##
        print (i)
        print (j)
        dato <- M[i, j]
        print (dato)
      }
    }

    #>
    #> [1] 1
    #> [1] "col1"
    #> [1] "0"
    #>
    #> [1] 1
    #> [1] "col2"
    #> [1] "340"
    #>
    #> [1] 1
    #> [1] "col3"
    #> [1] "-5"
    #>
    #> [1] 1
    #> [1] "col4"
    #> [1] "hola"
    #>
    #> [1] 2
    #> [1] "col1"
    #> [1] "2"
    #>
    #> [1] 2
    #> [1] "col2"
    #> [1] "340"
    #>
    #> [1] 2
    #> [1] "col3"
    #> [1] "-10"
    #>
    #> [1] 2
    #> [1] "col4"
    #> [1] "hola"
    #>
    #> [1] 3
    #> [1] "col1"
    #> [1] "0"
    #>
    #> [1] 3
    #> [1] "col2"
    #> [1] "560"
    #>
    #> [1] 3
    #> [1] "col3"
    #> [1] "-5"
    #>
    #> [1] 3
    #> [1] "col4"
    #> [1] "hola"
    #>
    #> [1] 4
    #> [1] "col1"
    #> [1] "4"
    #>
    #> [1] 4
    #> [1] "col2"
    #> [1] "120"
    #>
    #> [1] 4
    #> [1] "col3"
    #> [1] "-10"
    #>
    #> [1] 4
    #> [1] "col4"
    #> [1] "hola"

Aunque existen funciones que simplifican la sintaxis (y la velocidad)

    N

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

    apply (N, 1, sum)  #suma de las filas

    #> row1 row2 row3 row4
    #>  335  332  555  114

    apply (N, 2, min)  #minimo de las columnas

    #> col1 col2
    #>    0  120  -10