En R, toda la información se almacena en objetos. Dependiendo de cómo estén organizados los datos, estos objetos pueden adoptar distintas estructuras. Existen cuatro estructuras principales en R:
Continuamos con nuestro estudio de las matrices.
Una matriz en R es una estructura de datos bidimensional para almacenar objetos del mismo tipo.
Para crear una matriz se utiliza la función matrix()
cuyos argumentos son:
A <- matrix(1:10, nrow = 5)
A
## [,1] [,2]
## [1,] 1 6
## [2,] 2 7
## [3,] 3 8
## [4,] 4 9
## [5,] 5 10
B <- matrix(21:40, nrow = 2)
B
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
## [1,] 21 23 25 27 29 31 33 35 37 39
## [2,] 22 24 26 28 30 32 34 36 38 40
C <- matrix(14:25, nrow = 5)
## Warning in matrix(14:25, nrow = 5): data length [12] is not a sub-multiple or
## multiple of the number of rows [5]
C
## [,1] [,2] [,3]
## [1,] 14 19 24
## [2,] 15 20 25
## [3,] 16 21 14
## [4,] 17 22 15
## [5,] 18 23 16
nrow(A)
## [1] 5
nrow(B)
## [1] 2
nrow(C)
## [1] 5
ncol(A)
## [1] 2
ncol(B)
## [1] 10
ncol(C)
## [1] 3
dim(A)
## [1] 5 2
is.vector(dim(A))
## [1] TRUE
secuencia <- seq(1,12,2)
length(secuencia)
## [1] 6
secuencia
## [1] 1 3 5 7 9 11
matriz1 <- matrix(secuencia, nrow= 3, ncol= 2)
matriz1
## [,1] [,2]
## [1,] 1 7
## [2,] 3 9
## [3,] 5 11
matriz2 <- matrix(secuencia, nrow= 2)
matriz2
## [,1] [,2] [,3]
## [1,] 1 5 9
## [2,] 3 7 11
matriz3 <- matrix(secuencia, ncol = 3)
matriz2; matriz3
## [,1] [,2] [,3]
## [1,] 1 5 9
## [2,] 3 7 11
## [,1] [,2] [,3]
## [1,] 1 5 9
## [2,] 3 7 11
matriz4 <- matrix(secuencia, ncol=3, byrow= TRUE)
matriz3; matriz4
## [,1] [,2] [,3]
## [1,] 1 5 9
## [2,] 3 7 11
## [,1] [,2] [,3]
## [1,] 1 3 5
## [2,] 7 9 11
matriz5 <- matrix(secuencia,
ncol=3,
byrow= TRUE,
dimnames = list(c("F1","F2"),c("C1","C2","C3")) # necesitamos usar una lista
)
matriz5
## C1 C2 C3
## F1 1 3 5
## F2 7 9 11
| Operación | Código en R |
|---|---|
| Sumar dos matrices | matriz_a + matriz_b |
| Restar dos matrices | matriz_a - matriz_b |
| Multiplicar una matriz por un escalar | matriz_a * 2 |
| Multiplicar dos matrices | matriz_a %*% matriz_b |
| Transponer una matriz | t(matriz_a) |
| Determinante de una matriz cuadrada | det(matriz_a) |
| Inversa de una matriz | solve(matriz_a) |
| Diagonal principal de una matriz | diag(matriz_a) |
| Producto cruzado de dos matrices | crossprod(matriz_a, matriz_b) |
| Media de filas o columnas | rowMeans(matriz_a) /
colMeans(matriz_a) |
| Extraer fila o columna | matriz_a[1, ] / matriz_a[, 2] |
| Calcular los eigenvalores de una matriz simétrica | eigen(matriz_a) |
Nota: Los eigenvalores indican cuánto escala la matriz en determinadas direcciones privilegiadas (sus eigenvectores). Por ejemplo, en PCA, los eigenvalores de la matriz de covarianzas representan la cantidad de varianza explicada por cada componente principal.
matrizA <- matrix(1:4, 2, 2)
matrizB <- matrix(5:8, 2, 2)
matrizA; matrizB
## [,1] [,2]
## [1,] 1 3
## [2,] 2 4
## [,1] [,2]
## [1,] 5 7
## [2,] 6 8
# Suma de matrices
matriz_suma <- matrizA + matrizB
matriz_suma
## [,1] [,2]
## [1,] 6 10
## [2,] 8 12
# Resta de matrices
matriz_resta <- matrizB - matrizA
matriz_resta
## [,1] [,2]
## [1,] 4 4
## [2,] 4 4
Producto de matrices: Diferencia entre multiplicación elemento a elemento y multiplicación matricial.
matrizA; matrizB
## [,1] [,2]
## [1,] 1 3
## [2,] 2 4
## [,1] [,2]
## [1,] 5 7
## [2,] 6 8
multiplicacion_elemento <- matrizA * matrizB
multiplicacion_elemento
## [,1] [,2]
## [1,] 5 21
## [2,] 12 32
multiplicacion_matricial <- matrizA %*% matrizB
multiplicacion_matricial
## [,1] [,2]
## [1,] 23 31
## [2,] 34 46
Transpuesta, Determinante e Inversa de una Matriz
matrizA
## [,1] [,2]
## [1,] 1 3
## [2,] 2 4
# Transpuesta
# La transpuesta de una matriz se obtiene intercambiando sus filas por columnas.
matriz_transpuesta <- t(matrizA)
matriz_transpuesta
## [,1] [,2]
## [1,] 1 2
## [2,] 3 4
# Determinante de la matriz
# Solo para matrices cuadradas (mismo num de rows y col)
# Indica si una matriz tiene inversa
# Más adelante, servirá para medir la dispersión conjunta de variables aleatorias.
det_A <- det(matrizA)
det_A
## [1] -2
# Inversa de la matriz
# Si det(A) ≠ 0, la inversa es la matriz que, al multiplicarse
# por la matriz original resulta en la identidad
inversa_A <- solve(matrizA)
inversa_A
## [,1] [,2]
## [1,] -2 1.5
## [2,] 1 -0.5
Uso de las funciones rowSums(), colSums(), rowMeans() y colMeans() para obtener estadísticas de filas y columnas.
matrizA
## [,1] [,2]
## [1,] 1 3
## [2,] 2 4
suma_filas <- rowSums(matrizA)
suma_filas
## [1] 4 6
suma_columnas <- colSums(matrizA)
suma_columnas
## [1] 3 7
promedio_filas <- rowMeans(matrizA)
promedio_filas
## [1] 2 3
promedio_col <- colMeans(matrizA)
promedio_col
## [1] 1.5 3.5
Eres un analista en una compañía de seguros y debes evaluar la rentabilidad de dos productos de inversión.
Productos:
Producto A: Tasa de interés anual del 1.5%, 2% y 2.5% para los años 1, 3 y 5 respectivamente. Producto B: Tasa de interés anual fija del 3%, 3.5% y 4% para los años 1, 3 y 5 respectivamente.
Plazos de Inversión:
1 año, 3 años y 5 años.
Objetivo:
tasas_interes <- matrix(c(1.5,2,2.5,3,3.5,4),
nrow=3,
ncol=2,
byrow=FALSE,
dimnames=list(c("1 año","3 años","5 años"),c("Producto A","Producto B")))
tasas_interes
## Producto A Producto B
## 1 año 1.5 3.0
## 3 años 2.0 3.5
## 5 años 2.5 4.0
capital_inicial <- 10000
valor_futuro <- capital_inicial * (1 + tasas_interes/100) ^ c(1,3,5)
# R aplica la potencia elemento a elemento y recicla el vector c(1,3,5)
# para que coincida con la estructura por columnas de la matriz.
# R sigue column-major order.
tasas_interes; valor_futuro
## Producto A Producto B
## 1 año 1.5 3.0
## 3 años 2.0 3.5
## 5 años 2.5 4.0
## Producto A Producto B
## 1 año 10150.00 10300.00
## 3 años 10612.08 11087.18
## 5 años 11314.08 12166.53
Otra propuesta de solución es:
tasas_interes <- matrix(c(1.5,2,2.5,3,3.5,4),
nrow=2,
ncol=3,
byrow=TRUE,
dimnames=list(c("Producto A","Producto B"),c("1 año","3 años","5 años")))
tasas_interes
## 1 año 3 años 5 años
## Producto A 1.5 2.0 2.5
## Producto B 3.0 3.5 4.0
capital_inicial <- 10000
plazos <- matrix(rep(c(1,3,5),2),nrow=2,byrow=2)
plazos
## [,1] [,2] [,3]
## [1,] 1 3 5
## [2,] 1 3 5
valor_futuro <- capital_inicial * (1 + tasas_interes/100) ^ plazos
# R aplica la potencia elemento a elemento y recicla el vector c(1,3,5)
# para que coincida con la estructura por columnas de la matriz.
tasas_interes; valor_futuro
## 1 año 3 años 5 años
## Producto A 1.5 2.0 2.5
## Producto B 3.0 3.5 4.0
## 1 año 3 años 5 años
## Producto A 10150 10612.08 11314.08
## Producto B 10300 11087.18 12166.53
Eres un analista financiero de una concesionaria de autos y te han solicitado realizar un análisis detallado de los pagos mensuales de diferentes modelos de autos bajo diversos planes de financiamiento. La concesionaria ofrece financiamientos a plazos de 36, 48, 60 y 72 meses, con tasas de interés anuales que varían según el modelo de auto.
Se tiene tres modelos con los siguientes precios: Modelo A $250,000 Modelo B $350,000 Modelo C $450,000
Tasas de interés anual nominal (capitalizables mensualmente) por modelo: Modelo A 7.5% Modelo B 6.5% Modelo C 5.5%
Plazos de financiamiento 36 meses 48 meses 60 meses 72 meses
Objetivos:
| Modelo A | Modelo B | Modelo C | |
|---|---|---|---|
| 36 m | |||
| 48 m | |||
| 60 m | |||
| 72 m |
precios <- c(250000,350000,450000)
tasas_nom <- c(7.5,6.5,5.5)
plazos <- c(36,48,60,72)
tasas_mensuales <- round(tasas_nom/100/12,4)
tasas_matriz <- matrix(rep(tasas_mensuales,4), nrow= 4, byrow=T)
precios_matriz <- matrix(rep(precios,4), nrow = 4, byrow = T)
plazos_matriz <- matrix(rep(plazos, 3), nrow = 4)
Nota: La fórmula del valor presente de una anualidad vencida es:
\[ VP = R \cdot \frac{1 - (1+i)^{-n}}{i} \]
donde:
- \(VP\) = valor presente de la anualidad
- \(R\) = pago periódico
- \(i\) = tasa de interés por periodo
- \(n\) = número de periodosEn una anualidad vencida, los pagos se realizan al final de cada periodo.
pagos_mensuales <- precios_matriz * tasas_matriz / (1 -(1+tasas_matriz)^(-plazos_matriz))
pagos_mensuales
## [,1] [,2] [,3]
## [1,] 7769.667 10723.965 13592.216
## [2,] 6037.728 8297.005 10469.516
## [3,] 5002.362 6844.874 8599.678
## [4,] 4315.268 5880.143 7356.262
rownames(pagos_mensuales) <- c("36 m","48 m","60 m", "72 m")
colnames(pagos_mensuales) <- c("Modelo A", "Modelo B", "Modelo C")
pagos_mensuales
## Modelo A Modelo B Modelo C
## 36 m 7769.667 10723.965 13592.216
## 48 m 6037.728 8297.005 10469.516
## 60 m 5002.362 6844.874 8599.678
## 72 m 4315.268 5880.143 7356.262
dimnames(pagos_mensuales) <- list(1:4,1:3) # primero renglones
pagos_mensuales
## 1 2 3
## 1 7769.667 10723.965 13592.216
## 2 6037.728 8297.005 10469.516
## 3 5002.362 6844.874 8599.678
## 4 4315.268 5880.143 7356.262
dimnames(pagos_mensuales) <- list(c("36 m","48 m","60 m", "72 m"),
c("Modelo A", "Modelo B", "Modelo C")) # primero renglones
pagos_mensuales; t(pagos_mensuales)
## Modelo A Modelo B Modelo C
## 36 m 7769.667 10723.965 13592.216
## 48 m 6037.728 8297.005 10469.516
## 60 m 5002.362 6844.874 8599.678
## 72 m 4315.268 5880.143 7356.262
## 36 m 48 m 60 m 72 m
## Modelo A 7769.667 6037.728 5002.362 4315.268
## Modelo B 10723.965 8297.005 6844.874 5880.143
## Modelo C 13592.216 10469.516 8599.678 7356.262
Aprovechamos esta actividad para presentar un par de gráficos interesantes:
Emplearemos matplot(), función diseñada para graficar
todas las columnas de una matriz al mismo tiempo.
matplot(pagos_mensuales,
type = "b", # puntos + líneas
pch = 1:3, # tipo de punto distinto
lty = 1:3, # tipo de línea distinto
col = 1:3,
xaxt = "n", # quitar eje x automático
xlab = "Plazo",
ylab = "Pago",
main = "Comparación de pagos por modelo")
axis(1, at = 1:nrow(pagos_mensuales), labels = rownames(pagos_mensuales))
legend("topright",
legend = colnames(pagos_mensuales),
col = 1:3,
lty = 1:3,
pch = 1:3)
La gráfica de líneas resulta más adecuada cuando se desea analizar la tendencia de los pagos en función del plazo, ya que permite observar con mayor claridad la evolución entre 36, 48, 60 y 72 meses.
barplot(t(pagos_mensuales),
beside = TRUE, # barras separadas
col = c("skyblue", "salmon", "lightgreen"),
legend = colnames(pagos_mensuales),
main = "Pagos por modelo y plazo",
xlab = "Plazo",
ylab = "Pago")
La gráfica de barras facilita la comparación directa de los montos específicos entre los distintos modelos en cada plazo, permitiendo identificar diferencias puntuales de manera más visual.
Los índices en matrices son utilizados para acceder, modificar, o extraer elementos específicos dentro de la matriz. Los índices en R funcionan de la siguiente manera:
Para acceder a un elemento específico de una matriz, se usa la notación [fila, columna].
# Seleccionamos el dato de la primera fila y segunda columna
pagos_mensuales
## Modelo A Modelo B Modelo C
## 36 m 7769.667 10723.965 13592.216
## 48 m 6037.728 8297.005 10469.516
## 60 m 5002.362 6844.874 8599.678
## 72 m 4315.268 5880.143 7356.262
pagos_mensuales[1,2]
## [1] 10723.97
# pago mensual en financiamiento a 36 m de Modelo B
Para acceder a toda una fila, se deja en blanco la parte del índice de la columna:
# Seleccionamos todos los pagos mensuales del
# financiamiento a 60 meses
pagos_mensuales
## Modelo A Modelo B Modelo C
## 36 m 7769.667 10723.965 13592.216
## 48 m 6037.728 8297.005 10469.516
## 60 m 5002.362 6844.874 8599.678
## 72 m 4315.268 5880.143 7356.262
pagos_mensuales[3,]
## Modelo A Modelo B Modelo C
## 5002.362 6844.874 8599.678
Para acceder a toda una columna, se deja en blanco la parte del índice de la fila:
# Selccionamos todos los pagos para
# financiar el Modelo B
pagos_mensuales
## Modelo A Modelo B Modelo C
## 36 m 7769.667 10723.965 13592.216
## 48 m 6037.728 8297.005 10469.516
## 60 m 5002.362 6844.874 8599.678
## 72 m 4315.268 5880.143 7356.262
pagos_mensuales[,2]
## 36 m 48 m 60 m 72 m
## 10723.965 8297.005 6844.874 5880.143
Imaginemos que después de calcular los pagos mensuales, la gerencia quiere responder algunas preguntas específicas:
pagos_mensuales; pagos_mensuales[2,2]
## Modelo A Modelo B Modelo C
## 36 m 7769.667 10723.965 13592.216
## 48 m 6037.728 8297.005 10469.516
## 60 m 5002.362 6844.874 8599.678
## 72 m 4315.268 5880.143 7356.262
## [1] 8297.005
pagos_mensuales; pagos_mensuales[c(3,4),]
## Modelo A Modelo B Modelo C
## 36 m 7769.667 10723.965 13592.216
## 48 m 6037.728 8297.005 10469.516
## 60 m 5002.362 6844.874 8599.678
## 72 m 4315.268 5880.143 7356.262
## Modelo A Modelo B Modelo C
## 60 m 5002.362 6844.874 8599.678
## 72 m 4315.268 5880.143 7356.262
pagos_mensuales; min(pagos_mensuales)
## Modelo A Modelo B Modelo C
## 36 m 7769.667 10723.965 13592.216
## 48 m 6037.728 8297.005 10469.516
## 60 m 5002.362 6844.874 8599.678
## 72 m 4315.268 5880.143 7356.262
## [1] 4315.268
minimo <- min(pagos_mensuales)
posicion <- which(pagos_mensuales == minimo, arr.ind = TRUE)
?which
## starting httpd help server ... done
modelo <- colnames(pagos_mensuales)[posicion[2]]
plazo <- rownames(pagos_mensuales)[posicion[1]]
minimo
## [1] 4315.268
modelo
## [1] "Modelo A"
plazo
## [1] "72 m"
cat("El menor pago mensual es de $",
round(minimo, 2),
", correspondiente al",
modelo,
"en el plazo de",
plazo, ".")
## El menor pago mensual es de $ 4315.27 , correspondiente al Modelo A en el plazo de 72 m .
* # Data frames**
Los data frames son estructuras de datos bidimensionales en R, similares a una tabla de base de datos o una hoja de cálculo. La gran ventaja de los data frames es que permiten almacenar columnas con diferentes tipos de datos (números, caracteres, factores, etc.), siempre y cuando cada columna contenga un único tipo de dato.
Algunas características clave de los data frames son:
Mi primer Data Frame
Para crear un data frame se utiliza la función
data.frame().
A continuación se muestra un ejemplo de cómo crear un data frame con datos aleatorios de estudiantes, que incluye nombres, sexo, edades, estados de procedencia e ingresos.
Agregar nuevas columnas
Una vez creado el data frame, puedes agregar más columnas como estatura, peso y calificaciones:
Operaciones entre columnas
La función attach() nos permite tener acceso a las columnas del data frame para poder operar entre ellas. Mientras, que la función detach() es utíl para cerrar el data frame cuando ya no queremos tener acceso a las columnas.
Alternativamente, puedes operar directamente sobre las columnas sin usar attach() y detach():
Puedes exportar el data frame a un archivo Excel usando el paquete openxlsx: