Para poder realizar operaciones con diferentes variables, es importante conocer el tipo de dato de cada variable, puesto que no todos los tipos de dato son compatibles para realizar una operaición. En la clase previa, obervaciones como la cunfión class() nos ayuda a conocer el tipo variable, por ejemplo:
v1<-array(c(1,2,3,4,4,5,6))
class(v1)
## [1] "array"
v1
## [1] 1 2 3 4 4 5 6
Sin embargo, en ocasiones tendremos que modificar la naturaleza de alguna variable para poder ser compatible con otra y entonces por llevar a cabo alguna operación. Esre proceso se conoce como coercionar, que es transformar un tipo de variable a otro que sea de nuestra utilidad, compatible con nuestras operaciones.
v2 <- as.data.frame(v1)
class(v2)
## [1] "data.frame"
v2
## v1
## 1 1
## 2 2
## 3 3
## 4 4
## 5 4
## 6 5
## 7 6
En este curso utilizaremos principalmente las siguientes:
#as.matrix()
#as.data.frame()
#as.list()
#as.vector()
#as.Date()
En la sesión previa, se demostró como llevar información de un archivo con extensión .csv a una variable, de manera similar es posible extraer información de una archivo en formato de Excel, a una variable en R, sin embargo hay que instalar una librería adicional para este propósito
library(readxl)
alfa <- read_xlsx('Alfa.xlsx')
str(alfa)
## tibble [373 × 8] (S3: tbl_df/tbl/data.frame)
## $ Fecha : chr [1:373] "2020-01-02" "2020-01-03" "2020-01-06" "2020-01-07" ...
## $ ALFAA.MX.Open : num [1:373] 15.8 16.2 16.3 16.6 16.1 ...
## $ ALFAA.MX.High : num [1:373] 16.3 16.4 16.6 16.6 16.5 ...
## $ ALFAA.MX.Low : num [1:373] 15.8 16.1 16.3 16 16 ...
## $ ALFAA.MX.Close : num [1:373] 16.2 16.4 16.5 16.1 16.4 ...
## $ ALFAA.MX.Volume : num [1:373] 3605877 4177223 2999994 3496828 4687691 ...
## $ ALFAA.MX.Adjusted: num [1:373] 16.1 16.3 16.5 16.1 16.4 ...
## $ Dia : chr [1:373] "Lunes" "Martes" "Miercoles" "Jueves" ...
summary(alfa)
## Fecha ALFAA.MX.Open ALFAA.MX.High ALFAA.MX.Low
## Length:373 Min. : 6.30 Min. : 6.74 Min. : 6.12
## Class :character 1st Qu.:12.01 1st Qu.:12.22 1st Qu.:11.80
## Mode :character Median :13.50 Median :13.75 Median :13.20
## Mean :13.07 Mean :13.32 Mean :12.79
## 3rd Qu.:14.36 3rd Qu.:14.62 3rd Qu.:14.11
## Max. :17.10 Max. :17.49 Max. :16.74
##
## ALFAA.MX.Close ALFAA.MX.Volume ALFAA.MX.Adjusted Dia
## Min. : 6.40 Min. : 348799 Min. : 6.387 Length:373
## 1st Qu.:12.03 1st Qu.: 5026148 1st Qu.:12.010 Class :character
## Median :13.47 Median : 7751798 Median :13.442 Mode :character
## Mean :13.06 Mean : 11286706 Mean :13.033
## 3rd Qu.:14.34 3rd Qu.: 11154689 3rd Qu.:14.336
## Max. :16.99 Max. :538464233 Max. :16.955
## NA's :3
Antes de continuar...
#Con estas líneas cambiamos el nombre de las columnas (variables) del Data Frame
colnames(alfa) <- gsub('ALFAA.MX.', '', colnames(alfa))
summary(alfa)
## Fecha Open High Low
## Length:373 Min. : 6.30 Min. : 6.74 Min. : 6.12
## Class :character 1st Qu.:12.01 1st Qu.:12.22 1st Qu.:11.80
## Mode :character Median :13.50 Median :13.75 Median :13.20
## Mean :13.07 Mean :13.32 Mean :12.79
## 3rd Qu.:14.36 3rd Qu.:14.62 3rd Qu.:14.11
## Max. :17.10 Max. :17.49 Max. :16.74
##
## Close Volume Adjusted Dia
## Min. : 6.40 Min. : 348799 Min. : 6.387 Length:373
## 1st Qu.:12.03 1st Qu.: 5026148 1st Qu.:12.010 Class :character
## Median :13.47 Median : 7751798 Median :13.442 Mode :character
## Mean :13.06 Mean : 11286706 Mean :13.033
## 3rd Qu.:14.34 3rd Qu.: 11154689 3rd Qu.:14.336
## Max. :16.99 Max. :538464233 Max. :16.955
## NA's :3
fecha_texto <- "09-09-2021"
class(fecha_texto)
## [1] "character"
fecha_date <- as.Date(fecha_texto)
class(fecha_date)
## [1] "Date"
Preguntamos el año de la variable fecha_date
# Cargamospreviamente la librería lubridate para analizar las fechas
library('lubridate')
##
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
##
## date, intersect, setdiff, union
year(fecha_date)
## [1] 9
La variable fecha_date regresa un año un poco extraño
fecha_date
## [1] "0009-09-20"
El error deriva del formato de nuestra fecha original dd/mm/yyyy, cuando as.Date lo lee por defacult como yyyy/mm/dd. Por lo tanto hay que parametrizar la transformación de la variable
fecha_date <- as.Date(fecha_texto, format='%d-%m-%Y')
class(fecha_date)
## [1] "Date"
year(fecha_date)
## [1] 2021
fecha_date
## [1] "2021-09-09"
El formato de la variable fecha_date ya es el correcto
alfa$Fecha <- as.Date(alfa$Fecha, format='%Y-%m-%d')
str(alfa)
## tibble [373 × 8] (S3: tbl_df/tbl/data.frame)
## $ Fecha : Date[1:373], format: "2020-01-02" "2020-01-03" ...
## $ Open : num [1:373] 15.8 16.2 16.3 16.6 16.1 ...
## $ High : num [1:373] 16.3 16.4 16.6 16.6 16.5 ...
## $ Low : num [1:373] 15.8 16.1 16.3 16 16 ...
## $ Close : num [1:373] 16.2 16.4 16.5 16.1 16.4 ...
## $ Volume : num [1:373] 3605877 4177223 2999994 3496828 4687691 ...
## $ Adjusted: num [1:373] 16.1 16.3 16.5 16.1 16.4 ...
## $ Dia : chr [1:373] "Lunes" "Martes" "Miercoles" "Jueves" ...
No olvidemos que hay NA's en Close Si la información se trata de un precio, ¿qué valores podemos usar para sustituir los NA's? Podemos apoyarnos en una gráfica para tomar la mejor decisión
library('ggplot2')
ggplot(data=alfa, mapping = aes(x=Fecha, y=Close, group=1)) + geom_line()
library('ggplot2')
ggplot(data=alfa[1:100,], mapping = aes(x=Fecha, y=Close, group=1)) + geom_line()
- ¿Qué pasa si usamos 0's? - ¿Qué pasa si usamos la media? - ¿Qué pasa si eliminamos los valores?
1. Podemos incluir otro valor de nuestro conjunto de datos como el precio ajustado 2. Podemos incluir el último valor conocido
Antes, cargamos la librería dplyr
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
# Podemos generar datos ajustados utilizando alguno de los siguientes dos procesos
# 1. Incluimos el ajustado
alfa <- alfa %>% mutate(Close_adj = ifelse(is.na(Close), Adjusted, Close))
# 2. Incluimos el último conocido
library('zoo')
##
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
alfa <- alfa %>% mutate(Close_ult_conocido = na.locf(Close))
summary(alfa)
## Fecha Open High Low
## Min. :2020-01-02 Min. : 6.30 Min. : 6.74 Min. : 6.12
## 1st Qu.:2020-05-19 1st Qu.:12.01 1st Qu.:12.22 1st Qu.:11.80
## Median :2020-09-28 Median :13.50 Median :13.75 Median :13.20
## Mean :2020-09-28 Mean :13.07 Mean :13.32 Mean :12.79
## 3rd Qu.:2021-02-11 3rd Qu.:14.36 3rd Qu.:14.62 3rd Qu.:14.11
## Max. :2021-06-25 Max. :17.10 Max. :17.49 Max. :16.74
##
## Close Volume Adjusted Dia
## Min. : 6.40 Min. : 348799 Min. : 6.387 Length:373
## 1st Qu.:12.03 1st Qu.: 5026148 1st Qu.:12.010 Class :character
## Median :13.47 Median : 7751798 Median :13.442 Mode :character
## Mean :13.06 Mean : 11286706 Mean :13.033
## 3rd Qu.:14.34 3rd Qu.: 11154689 3rd Qu.:14.336
## Max. :16.99 Max. :538464233 Max. :16.955
## NA's :3
## Close_adj Close_ult_conocido
## Min. : 6.40 Min. : 6.40
## 1st Qu.:12.03 1st Qu.:12.03
## Median :13.47 Median :13.47
## Mean :13.06 Mean :13.06
## 3rd Qu.:14.36 3rd Qu.:14.36
## Max. :16.99 Max. :16.99
##
ggplot(alfa[1:80,], aes(x=Fecha, group=1)) + geom_line(aes(y=Close_adj), color='blue') + geom_line(aes(y=Close), color='black', size=1)
ggplot(alfa[1:80,], aes(x=Fecha, group=1)) + geom_line(aes(y=Close_ult_conocido), color='red') + geom_line(aes(y=Close), color='black', size=1)
La naturaleza de la fuente de información es de una Serie de Tiempo. Para manipular Series de Tiempo haremos uso de la librería xts
library('xts')
##
## Attaching package: 'xts'
## The following objects are masked from 'package:dplyr':
##
## first, last
# creamos un nuevo conjunto de de datos que no tenga la columna dia (es un valor de texto)
alfa$Dia <- NULL
# Solo incluimos las columnas numéricas y ordenamos por la Fecha del registro
alfa_st <- xts(alfa[,2:9], order.by = as.Date(alfa$Fecha))
El ya clásico summary() y head() para analizar nuestros datos
summary(alfa_st)
## Index Open High Low
## Min. :2020-01-02 Min. : 6.30 Min. : 6.74 Min. : 6.12
## 1st Qu.:2020-05-19 1st Qu.:12.01 1st Qu.:12.22 1st Qu.:11.80
## Median :2020-09-28 Median :13.50 Median :13.75 Median :13.20
## Mean :2020-09-28 Mean :13.07 Mean :13.32 Mean :12.79
## 3rd Qu.:2021-02-11 3rd Qu.:14.36 3rd Qu.:14.62 3rd Qu.:14.11
## Max. :2021-06-25 Max. :17.10 Max. :17.49 Max. :16.74
##
## Close Volume Adjusted Close_adj
## Min. : 6.40 Min. : 348799 Min. : 6.387 Min. : 6.40
## 1st Qu.:12.03 1st Qu.: 5026148 1st Qu.:12.010 1st Qu.:12.03
## Median :13.47 Median : 7751798 Median :13.442 Median :13.47
## Mean :13.06 Mean : 11286706 Mean :13.033 Mean :13.06
## 3rd Qu.:14.34 3rd Qu.: 11154689 3rd Qu.:14.336 3rd Qu.:14.36
## Max. :16.99 Max. :538464233 Max. :16.955 Max. :16.99
## NA's :3
## Close_ult_conocido
## Min. : 6.40
## 1st Qu.:12.03
## Median :13.47
## Mean :13.06
## 3rd Qu.:14.36
## Max. :16.99
##
head(alfa_st)
## Open High Low Close Volume Adjusted Close_adj
## 2020-01-02 15.82 16.26 15.81 16.160 3605877 16.10172 16.160
## 2020-01-03 16.16 16.40 16.09 16.360 4177223 16.30100 16.360
## 2020-01-06 16.30 16.61 16.30 16.535 2999994 16.47537 16.535
## 2020-01-07 16.62 16.62 15.96 16.130 3496828 16.07184 16.130
## 2020-01-08 16.13 16.49 15.96 16.440 4687691 16.38072 16.440
## 2020-01-09 16.48 16.48 16.06 16.400 6024214 16.34086 16.400
## Close_ult_conocido
## 2020-01-02 16.160
## 2020-01-03 16.360
## 2020-01-06 16.535
## 2020-01-07 16.130
## 2020-01-08 16.440
## 2020-01-09 16.400
Como la fecha ahora es el índice, podemos acceder a los renglones mediante intervalos de tiempo
alfa_st['2020-01',]
## Open High Low Close Volume Adjusted Close_adj
## 2020-01-02 15.82 16.26 15.81 16.160 3605877 16.10172 16.16000
## 2020-01-03 16.16 16.40 16.09 16.360 4177223 16.30100 16.36000
## 2020-01-06 16.30 16.61 16.30 16.535 2999994 16.47537 16.53500
## 2020-01-07 16.62 16.62 15.96 16.130 3496828 16.07184 16.13000
## 2020-01-08 16.13 16.49 15.96 16.440 4687691 16.38072 16.44000
## 2020-01-09 16.48 16.48 16.06 16.400 6024214 16.34086 16.40000
## 2020-01-10 16.36 16.42 16.00 16.020 22456679 15.96223 16.02000
## 2020-01-13 16.01 16.13 15.86 16.100 6471527 16.04194 16.10000
## 2020-01-14 16.09 16.09 15.74 NA 5061703 15.77291 15.77291
## 2020-01-15 15.80 15.87 15.15 NA 9739995 15.15515 15.15515
## 2020-01-16 15.32 15.69 15.32 15.600 6423771 15.54375 15.60000
## 2020-01-17 15.68 15.93 15.41 15.840 5391571 15.78288 15.84000
## 2020-01-20 15.72 15.93 15.72 15.850 2521043 15.79284 15.85000
## 2020-01-21 15.76 15.76 15.51 15.650 2192267 15.59356 15.65000
## 2020-01-22 15.69 15.82 15.36 15.560 3848436 15.50389 15.56000
## 2020-01-23 15.52 15.52 15.30 15.390 3798998 15.33450 15.39000
## 2020-01-24 15.39 15.56 15.11 15.140 5018638 15.08540 15.14000
## 2020-01-27 14.96 14.96 14.38 14.415 7913313 14.36302 14.41500
## 2020-01-28 14.55 14.75 14.25 14.330 4023380 14.27832 14.33000
## 2020-01-29 14.36 14.45 14.12 14.220 2697000 14.16872 14.22000
## 2020-01-30 14.25 14.35 14.11 14.250 6553877 14.19861 14.25000
## 2020-01-31 14.19 14.37 14.05 14.190 15015856 14.13883 14.19000
## Close_ult_conocido
## 2020-01-02 16.160
## 2020-01-03 16.360
## 2020-01-06 16.535
## 2020-01-07 16.130
## 2020-01-08 16.440
## 2020-01-09 16.400
## 2020-01-10 16.020
## 2020-01-13 16.100
## 2020-01-14 16.100
## 2020-01-15 16.100
## 2020-01-16 15.600
## 2020-01-17 15.840
## 2020-01-20 15.850
## 2020-01-21 15.650
## 2020-01-22 15.560
## 2020-01-23 15.390
## 2020-01-24 15.140
## 2020-01-27 14.415
## 2020-01-28 14.330
## 2020-01-29 14.220
## 2020-01-30 14.250
## 2020-01-31 14.190
Graficamos con ggplot. La variable x es el índice de nuestra Serie de Tiempo
ggplot(alfa_st, aes(Index, Close)) + geom_line() + xlab('Fecha') + ylab('Open')
Como nuestros datos contienen el formato OHLC, podemos usar el paquete quantmod para obtener una gráfica de velas.
library('quantmod')
## Loading required package: TTR
## Registered S3 method overwritten by 'quantmod':
## method from
## as.zoo.data.frame zoo
chartSeries(alfa_st['2020-01',])
Calculamos los retornos de la Serie de Tiempo
alfa_returns <- diff(alfa_st, arithmetic=FALSE) - 1
summary(alfa_returns)
## Index Open High
## Min. :2020-01-02 Min. :-0.1601445 Min. :-0.1722846
## 1st Qu.:2020-05-19 1st Qu.:-0.0148910 1st Qu.:-0.0124943
## Median :2020-09-28 Median :-0.0003519 Median :-0.0012492
## Mean :2020-09-28 Mean : 0.0003888 Mean : 0.0002919
## 3rd Qu.:2021-02-11 3rd Qu.: 0.0133891 3rd Qu.: 0.0101420
## Max. :2021-06-25 Max. : 0.2595041 Max. : 0.2219178
## NA's :1 NA's :1
## Low Close Volume
## Min. :-0.1937075 Min. :-0.204614 Min. :-0.96007
## 1st Qu.:-0.0123638 1st Qu.:-0.012467 1st Qu.:-0.31615
## Median : 0.0016331 Median : 0.000000 Median :-0.01542
## Mean : 0.0003709 Mean : 0.000942 Mean : 0.43585
## 3rd Qu.: 0.0129001 3rd Qu.: 0.012271 3rd Qu.: 0.51096
## Max. : 0.2173554 Max. : 0.275748 Max. :16.52490
## NA's :1 NA's :6 NA's :1
## Adjusted Close_adj Close_ult_conocido
## Min. :-0.2046145 Min. :-0.2046144 Min. :-0.2046144
## 1st Qu.:-0.0133143 1st Qu.:-0.0133143 1st Qu.:-0.0126775
## Median : 0.0000000 Median : 0.0000000 Median : 0.0000000
## Mean : 0.0004583 Mean : 0.0004491 Mean : 0.0004613
## 3rd Qu.: 0.0122182 3rd Qu.: 0.0122181 3rd Qu.: 0.0119824
## Max. : 0.2757474 Max. : 0.2757475 Max. : 0.2757475
## NA's :1 NA's :1 NA's :1
head(alfa_returns)
## Open High Low Close Volume
## 2020-01-02 NA NA NA NA NA
## 2020-01-03 0.021491783 0.0086100861 0.017710310 0.012376300 0.1584486
## 2020-01-06 0.008663304 0.0128049390 0.013051523 0.010696760 -0.2818210
## 2020-01-07 0.019632026 0.0006020469 -0.020858836 -0.024493559 0.1656117
## 2020-01-08 -0.029482670 -0.0078219610 0.000000000 0.019218972 0.3405552
## 2020-01-09 0.021698761 -0.0006064281 0.006265602 -0.002433151 0.2851133
## Adjusted Close_adj Close_ult_conocido
## 2020-01-02 NA NA NA
## 2020-01-03 0.012376252 0.012376300 0.012376300
## 2020-01-06 0.010696764 0.010696760 0.010696760
## 2020-01-07 -0.024493347 -0.024493559 -0.024493559
## 2020-01-08 0.019218776 0.019218972 0.019218972
## 2020-01-09 -0.002433105 -0.002433151 -0.002433151
Encontramos NA's en el primer renglon, en este caso lo podemos borrar. ¿Por qué el primer registro es NA?
alfa_returns <- na.omit(alfa_returns)
head(alfa_returns)
## Open High Low Close Volume
## 2020-01-03 0.021491783 0.0086100861 0.017710310 0.012376300 0.1584486
## 2020-01-06 0.008663304 0.0128049390 0.013051523 0.010696760 -0.2818210
## 2020-01-07 0.019632026 0.0006020469 -0.020858836 -0.024493559 0.1656117
## 2020-01-08 -0.029482670 -0.0078219610 0.000000000 0.019218972 0.3405552
## 2020-01-09 0.021698761 -0.0006064281 0.006265602 -0.002433151 0.2851133
## 2020-01-10 -0.007281493 -0.0036407767 -0.003735928 -0.023170732 2.7277359
## Adjusted Close_adj Close_ult_conocido
## 2020-01-03 0.012376252 0.012376300 0.012376300
## 2020-01-06 0.010696764 0.010696760 0.010696760
## 2020-01-07 -0.024493347 -0.024493559 -0.024493559
## 2020-01-08 0.019218776 0.019218972 0.019218972
## 2020-01-09 -0.002433105 -0.002433151 -0.002433151
## 2020-01-10 -0.023170690 -0.023170732 -0.023170732
Creamos el histograma para tener una primera apreciación de la distribución de los retornos
ggplot(alfa_returns, aes(Close_ult_conocido)) + geom_histogram(bins = 40)
Con una inspección visual, encontramos valores extremos. Graficamos un box plot para corroborar nuestra observación.
#ggplot(alfa_returns, aes(ALFAA.MX.Close_alt_ult_conocido)) + geom_boxplot() + coord_flip()
boxplot(alfa_returns$Close_ult_conocido)
# Otro método para graficar, sin outliers
boxplot(alfa_returns$Close_ult_conocido, outline=FALSE)
# Con Out podemos obtener todos los outliers, debemos indicar el parámetro plot=FALSE para que no regrese la gráfica
outliers <- boxplot(alfa_returns$ALFAA.MX.Close_alt_ult_conocido, plot=FALSE)$Out
Como ejercicio de este punto: - ¿Cómo podemos quitar los outliers de nuestra series de datos? - ¿Tienen algún valor los outliers? - ¿Qué podemos hacer con los outliers?
Por último:
Con la función arrange() podemos ordenar los valores que le especifiquemos de menor a mayor, o bien podemos incluir la función desc() con el nombre de la variable para que los ordene de mayor a menor.
data_arranged <- as.data.frame(alfa_returns) %>% arrange(Open)
head(data_arranged)
## Open High Low Close Volume
## 2020-12-14 -0.16014454 -0.127031961 -0.19370754 -0.20461440 1.50426953
## 2020-03-19 -0.15096154 -0.172284644 -0.06159420 -0.09534620 -0.09760923
## 2020-03-24 -0.12609238 -0.001248439 0.02958580 0.08526012 0.34583065
## 2020-03-20 -0.09399773 -0.062217195 -0.09137709 0.01380176 3.09857766
## 2020-04-01 -0.09221902 -0.089189189 -0.01923077 0.03750000 -0.48471162
## 2021-02-02 -0.07163743 -0.070021882 -0.15559030 -0.06744186 8.86714205
## Adjusted Close_adj Close_ult_conocido
## 2020-12-14 -0.20461454 -0.20461440 -0.20461440
## 2020-03-19 -0.09534623 -0.09534620 -0.09534620
## 2020-03-24 0.08526011 0.08526012 0.08526012
## 2020-03-20 0.01380168 0.01380176 0.01380176
## 2020-04-01 0.03749997 0.03750000 0.03750000
## 2021-02-02 -0.06744183 -0.06744186 -0.06744186