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