En clases anteriores hemos abordado ya el concepto de vector. Lo que veremos ahora es la idea detrás de las matrices. Las matrices pueden entenderse como vectores de dos dimensiones, donde a los vectores le asociamos una dimensión de \(1\times n\), donde \(n\) es el número de entradas que tiene dicho vector. Por ejemplo
# vector de dimension 1x2
v1 <- c(0,0)
v2 <- c(1,4)
# vector de dimension 1x4
v3 <- c(1,4,5,8)
# vector de dimension 1x100
v4 <- c(1:100)
el hecho de que la dimensión sea \(1\times n\) en los vectores es debido a que un vector puede considerarse como una sola fila de datos. Escalando a otra dimensión, podremos considerar vectores de dimensión \(m\times n\), que puede entenderse como un conjunto de \(m\) vectores (o filas), que cada uno tiene \(n\) entradas. Por ejemplo
\[ \left(\begin{array}{cc} 1&0\\ 0&1 \end{array}\right) \]
es una matriz de \(2\times 2\), o
también puede decirse que son dos vectores, \((1 \ \ 0)\) y \((0\ \ 1)\), que tienen dos entradas cada
uno. De hecho, con las funciones rbind
y cbind
podemos crear matrices:
# Matriz de 2x2
matriz1 <- rbind(v1, v2)
matriz1
## [,1] [,2]
## v1 0 0
## v2 1 4
# Matriz de 2x2
matriz2 <- cbind(v1, v2)
matriz2
## v1 v2
## [1,] 0 1
## [2,] 0 4
Podemos crear explícitamente matrices utilizando la función
matrix()
como sigue
# Le pasamos un vector de numeros, los cuales acomodaremos en 3 filas por 3 columnas, lo cual nos da como resultado una matriz de 3x3.
# Especificamos el numero de filas y columnas
matriz3 <- matrix(1:9, nrow = 3, ncol = 3)
matriz3
## [,1] [,2] [,3]
## [1,] 1 4 7
## [2,] 2 5 8
## [3,] 3 6 9
A la matriz anterior le podemos agregar una columna nueva con la
función cbind
:
# Definimos un vector con tres entradas
v5 <- 1:3
# Le agregamos dicho vector a la matriz3
cbind(matriz3, v5)
## v5
## [1,] 1 4 7 1
## [2,] 2 5 8 2
## [3,] 3 6 9 3
Así como en los vectores, las operaciones con las matrices son entrada a entrada.
# A cada entrada le sumaremos un 7
matriz3 + 7
## [,1] [,2] [,3]
## [1,] 8 11 14
## [2,] 9 12 15
## [3,] 10 13 16
# A cada entrada la multiplicamos por un 4
matriz3 * 4
## [,1] [,2] [,3]
## [1,] 4 16 28
## [2,] 8 20 32
## [3,] 12 24 36
Podemos sumar, entrada a entrada, dos matrices
# Definimos otra matriz de 3x3
matriz4 <- matrix(10:18, nrow = 3, ncol = 3)
# Sumamos
matriz3 + matriz4
## [,1] [,2] [,3]
## [1,] 11 17 23
## [2,] 13 19 25
## [3,] 15 21 27
# Multiplicamos
matriz3 * matriz4
## [,1] [,2] [,3]
## [1,] 10 52 112
## [2,] 22 70 136
## [3,] 36 90 162
etcétera.
Considerando la matriz de \(2\times 3\)
ma <- matrix(1:6, nrow = 2, ncol = 3)
ma
## [,1] [,2] [,3]
## [1,] 1 3 5
## [2,] 2 4 6
podemos obtener, a partir de dicha matriz, otra matriz de \(3\times 2\) con la función
t()
:
# t(): funcion para transponer
t(ma)
## [,1] [,2]
## [1,] 1 2
## [2,] 3 4
## [3,] 5 6
donde las filas de ma
pasaron a ser columnas, lo cual
invirtió el orden de la dimensión. En general, dada una matriz de
dimensión \(m\times n\), al aplicar una
operación de transpuesta obtendremos una matriz de \(n\times m\), cambiando las filas por
columnas.
Finalmente, con la fucnión dim()
obtenemos la dimensión
de una matriz
# Dimension de la matriz ma
dim(ma)
## [1] 2 3
# Dimension de la transpuesta de la matriz ma
dim(t(ma))
## [1] 3 2
Cabe mencionar que en las matrices y en los vectores solo se admite un tipo de dato para todas las entradas, quedándose el tipo de dato de mayor jerarquía. Por ejemplo, si consideramos
v6 <- c(1, "Msj")
v6
## [1] "1" "Msj"
tenemos que el número 1 ahora es considerado, dentro del vector
v6
, como una cadena de texto. Lo mismo pasaría si
definimos en una matriz números y cadenas de texto. De tal manera, estas
estructuras de datos solo admiten un tipo de dato para todas sus
entradas.
Dentro de R
existen librerías que traen funcionalidades
adicionales. Por ejemplo, en la librería datasets
vienen
integrados varios conjuntos de datos, por ejemplo:
# Cargamos la libreria datasets para poderla utilizar
library(datasets)
# De la libreria datasets accedemos al conjunto de datos iris
data <- datasets::iris
# Veamos
head(data)
con la función head()
solo vemos la información de las
primeras 6 filas. O podemos especificar el número de filas que queremos
ver si escribimos head(data, 10)
para ver las 10 primeras
filas.
Podemos acceder a la información de una columna en específico, pero antes de ello obtengamos los nombres de todas las columnas:
# colnames(): nos regresa el nombre de todas las columnas
colnames(data)
## [1] "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width" "Species"
luego
# Vemos los primeros 6 valores de la columna Petal.Length escribiendo para ello data$Petal.Length
head(data$Petal.Length)
## [1] 1.4 1.4 1.3 1.5 1.4 1.7
esto es, dado un conjunto de datos, accedemos a los elementos de una
columna utilizando el símbolo $
. Adicionalmente, podemos
acceder a un número determinado de filas y columnas:
# Entre corchetes escribimos:
# [numero de fila, numero de columna]
data[1, 3]
## [1] 1.4
O también podemos obtener rangos de filas y/o de columnas
# Datos de la fila 1 a la 3 considerando solo las columnas de la 2 a la 5
data[1:3, 2:5]
Podemos obtener la información de todas las columnas para cierto número de filas
# Seleccionamos de la fila 1 a la 3, pero todas las columnas
data[1:3, ]
o seleccionar todas las filas para ciertas columnas
# Todas las filas para las primeras 3 columnas
data[, 1:3]
En vez de utilizar vectores de secuencias seguidas (1,2,3), podemos utilizar:
# Todas las filas de las columnas 1 y 4
data[, c(1, 4)]
o, en vez de utilizar números para referirnos a las columnas, podemos utilizar directamente sus nombres
# Todas las filas de las columnas 1 y 4
data[, c("Sepal.Length", "Petal.Width")]
Podemos seleccionar información con base en una condición. Por
ejemplo, seleccionar los elementos donde los valores de
"Sepal.Length"
sea mayores a 5:
# Entre corchetes ponemos la condicion.
# Accederemos a la columna Sepal.Length:
data[data$Sepal.Length > 5, ]
donde seleccionamos las filas que cumplían dicha condición y seleccionamos todas las columnas. Otro ejemplo:
# Seleccionamos toda la informacion donde la especie sea setosa
data[data$Species == "setosa", ]
Observamos que el conjunto de datos con el que estamos trabajando
tiene 50 filas. Luego, podemos agregar columnas nuevas a nuestros
conjuntos de datos, para ello escribiremos
nombre_dataset$nombre_columna_nueva
y asignaremos los
valores que queremos agregar a esa columna nueva. Por ejemplo,
agregaremos una columna nueva a data
que tenga los números
del 1 al 50
# Agregamos una columna nueva
data$ID <- 1:50
# Veamos
head(data$ID)
## [1] 1 2 3 4 5 6
Podemos eliminiar columnas. Para ello necesitaremos de dos componentes: los nombres de las columnas del dataset y un vector que tenga los nombres de las columnas que queremos eliminar. Por ejemplo
!( colnames(data) %in% c("Petal.Width", "Species", "ID") )
nos dice que, no queremos considerar la información de las
columnas cuyos nombres estén en el vector
c("Petal.Width", "Species", "ID")
, lo cual significa,
básicamente, que queremos eliminar dichas columnas. Recordemos que
!
es el operador de negación not. De tal
manera:
# Consideraremos un dataset sin las columnas "Petal.Width" "Species" y "ID". El dataset resultante lo almacenaremos en un nuevo dataser denominado dataset2:
data2 <- data[, !(colnames(data) %in% c("Petal.Width", "Species", "ID"))]
data2
Alternativamente podemos escribir
data3 <- data[, (colnames(data) %in% c("Sepal.Length", "Sepal.Width", "Petal.Length"))]
data3
que nos arroja la información de únicamente las columnas
"Sepal.Length", "Sepal.Width"
y
"Petal.Length"
.
Luego, podemos ordenar los elementos de una columna:
# Obtenemos la informacion ordenada de menor a mayor de acuerdo a la columna Sepal.Length
data[order(data$Sepal.Length), ]
o también ordenar de mayor a menor
# Obtenemos la informacion ordenada de mayor a menor de acuerdo a la columna Sepal.Length
data[order(data$Sepal.Length, decreasing = TRUE), ]
El conjunto de datos iris con el cual hemos estado
trabajando tiene almacenada la información en un tabla. Básicamente
podemos entender a los dataframes como datos tabulares o
tablas, de modo que la variable data
es en realidad un
dataframe. Podría pensarse también que un dataframe es como una matriz,
pero en ésta se admiten distintos tipos de datos.
Luego, en la sección pasada estuvimos indagando un poco sobre las
propiedades de un dataframe, vimos como realizar filtros de información
y cómo implementar filtros con condiciones, y vimos como agregar
columnas nuevas. Todo lo anterior lo hicimos cargando el dataset. Ahora
lo que veremos es cómo crear un dataframe desde cero, para lo cual
utilizaremos la función data.frame()
como sigue
# Creamos nuestro primer dataframe
df1 <- data.frame(
# El nombre de las columna ira como cadena de texto. A la primer columna le asigaremos los numeros del 1 al 4
"Columna 1" = 1:4,
"Columna 2" = c("a", "b", "c", "d"),
"columna 3" = c(T, T, F, T)
)
# Veamos el dataframe
df1
Dado un dataframe podemos:
# Ver su dimension (filas x columnas)
dim(df1)
## [1] 4 3
# Ver los nombres las columnas:
# Forma 1
names(df1)
## [1] "Columna.1" "Columna.2" "columna.3"
# Forma 2
colnames(df1)
## [1] "Columna.1" "Columna.2" "columna.3"
Es preciso mencionar que NO podremos realizar operaciones vectorizadas con los dataframes
df1 * 4
## Error in FUN(left, right): argumento no-numérico para operador binario
Luego, podemos importar dataframes de tablas de Excel o de archivos csv (valores separados por comas):
# Para leer documentos de excel necesitamos la siguiente libreria
library(readxl)
# Con la siguiente funcion leemos archivos de Excel
df <- read_excel(<<ruta del archivo>>)
En resumen, sabemos crear dataframes, sabemos obtener datasets de la
librería datasets
de R
, conocemos las
funciones para importar información de archivos Excel y csv. Además,
tenemos las bases para manipular dataframes. Todo lo anterior constituye
un primer, e importante paso, en la manipulación de datos con
R
, donde en clases posteriores iremos indagando en más
técnicas y conociendo más herramientas que nos permitirán realizar una
mejor manipulación de los datos con los que trabajemos.
Crea 4 vectores con 5 entradas, donde dichas entradas sean
números aleatorios entre el 1 y el 10. Luego, a partir de ellos crea dos
matrices de \(2\times 5\) utilizando la
función rbind()
. Con las dos matrices resultantes, calcula:
la suma, resta y producto entre ellas.
Utilizando una matriz que definiste en el punto anterior, obtén su dimensión y define una variable nueva que almacene la transpuesta de dicha matriz.
Utilizando la librería datasets
, carga el conjunto
de datos airquality
.
Temp
hace alusión a la temperatura.
Encuentra el día más caluroso y más frio almacenado en ese conjunto de
datos.Wind
y
Ozone
.ID
que contenga un rango de
números que comience en 1.