Objetos de datos

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:

I. Vectores

II. Matrices

III. Data frames

IV. Listas

Continuamos con nuestro estudio de las matrices.


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:

  1. data: Datos a incluir en la matriz
  2. nrow: Número de filas
  3. ncol: Número de columnas
  4. byrow: Llenado por filas o columnas TRUE o FALSE respectivamente. Por defecto es FALSE.
  5. dimnames: Nombres de las filas y columnas.
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


Operaciones con matrices

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.


Suma y Resta de Matrices:

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


Funciones aplicadas a matrices

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

Actividad 1

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:

  1. Calcular el valor futuro de una inversión inicial de $10,000 para ambos productos en cada plazo.
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


Actividad 2

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:

  1. Utiliza la fórmula de anualidades para calcular los pagos mensuales.
  2. Crea una matriz que almacene los pagos mensuales calculados para cada modelo de auto y cada plazo.
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 periodos

En 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:

  • Gráfico de líneas

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.

Índices con matrices

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:

  1. ¿Cuál es el pago mensual del Modelo B para un plazo de 48 meses?
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
  1. ¿Cuáles son los pagos mensuales para todos los modelos cuando el plazo es de 60 y 72 meses?
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
  1. ¿Para qué modelo y en qué plazo se registra el pago mensual más bajo?
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:

  1. Dimensiones: Los data frame tienen filas y columnas, donde las columnas representan variables y las filas representan observaciones.
  2. Tipos de Datos: Cada columna debe contener un solo tipo de dato (numérico, texto, lógico, etc.), pero diferentes columnas pueden tener distintos tipos de datos.
  3. Manipulación: Los data frames permiten acceder, modificar, y operar sobre sus elementos de manera eficiente usando diversas funciones en R.


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: