library(readr)
## Warning: package 'readr' was built under R version 4.1.3
library(mice)
## Warning: package 'mice' was built under R version 4.1.3
##
## Attaching package: 'mice'
## The following object is masked from 'package:stats':
##
## filter
## The following objects are masked from 'package:base':
##
## cbind, rbind
library(outliers)
## Warning: package 'outliers' was built under R version 4.1.3
library(dplyr)
## Warning: package 'dplyr' was built under R version 4.1.3
##
## 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
library(tidyverse)
## Warning: package 'tidyverse' was built under R version 4.1.3
## Warning: package 'ggplot2' was built under R version 4.1.3
## Warning: package 'tibble' was built under R version 4.1.3
## Warning: package 'tidyr' was built under R version 4.1.3
## Warning: package 'purrr' was built under R version 4.1.3
## Warning: package 'stringr' was built under R version 4.1.3
## Warning: package 'forcats' was built under R version 4.1.3
## Warning: package 'lubridate' was built under R version 4.1.3
## -- Attaching core tidyverse packages ------------------------ tidyverse 2.0.0 --
## v forcats 1.0.0 v stringr 1.5.0
## v ggplot2 3.4.1 v tibble 3.2.1
## v lubridate 1.9.2 v tidyr 1.3.0
## v purrr 1.0.1
## -- Conflicts ------------------------------------------ tidyverse_conflicts() --
## x dplyr::filter() masks mice::filter(), stats::filter()
## x dplyr::lag() masks stats::lag()
## i Use the ]8;;http://conflicted.r-lib.org/conflicted package]8;; to force all conflicts to become errors
library(ggplot2)
library(EnvStats)
##
## Attaching package: 'EnvStats'
##
## The following objects are masked from 'package:stats':
##
## predict, predict.lm
library(GGally)
## Warning: package 'GGally' was built under R version 4.1.3
## Registered S3 method overwritten by 'GGally':
## method from
## +.gg ggplot2
df <- read.csv("C:/Users/pc/Desktop/Universidad/Semestre_VI/VIZ/Tarea2/Errores_comunes/diabetes.csv")
head(df)
## Pregnancies Glucose BloodPressure SkinThickness Insulin BMI
## 1 6 148 72 35 0 33.6
## 2 1 85 66 29 0 26.6
## 3 8 183 64 0 0 23.3
## 4 1 89 66 23 94 28.1
## 5 0 137 40 35 168 43.1
## 6 5 116 74 0 0 25.6
## DiabetesPedigreeFunction Age Outcome
## 1 0.627 50 1
## 2 0.351 31 0
## 3 0.672 32 1
## 4 0.167 21 0
## 5 2.288 33 1
## 6 0.201 30 0
df <- df %>%
mutate(across(c(Glucose, BloodPressure, SkinThickness, Insulin, BMI), ~na_if(.x, 0)))
summarize_na <- sapply(df, function(x) sum(is.na(x)))
summary_stats <- summary(df)
print(summarize_na)
## Pregnancies Glucose BloodPressure
## 0 5 35
## SkinThickness Insulin BMI
## 227 374 11
## DiabetesPedigreeFunction Age Outcome
## 0 0 0
print(summary_stats)
## Pregnancies Glucose BloodPressure SkinThickness
## Min. : 0.000 Min. : 44.0 Min. : 24.00 Min. : 7.00
## 1st Qu.: 1.000 1st Qu.: 99.0 1st Qu.: 64.00 1st Qu.:22.00
## Median : 3.000 Median :117.0 Median : 72.00 Median :29.00
## Mean : 3.845 Mean :121.7 Mean : 72.41 Mean :29.15
## 3rd Qu.: 6.000 3rd Qu.:141.0 3rd Qu.: 80.00 3rd Qu.:36.00
## Max. :17.000 Max. :199.0 Max. :122.00 Max. :99.00
## NA's :5 NA's :35 NA's :227
## Insulin BMI DiabetesPedigreeFunction Age
## Min. : 14.00 Min. :18.20 Min. :0.0780 Min. :21.00
## 1st Qu.: 76.25 1st Qu.:27.50 1st Qu.:0.2437 1st Qu.:24.00
## Median :125.00 Median :32.30 Median :0.3725 Median :29.00
## Mean :155.55 Mean :32.46 Mean :0.4719 Mean :33.24
## 3rd Qu.:190.00 3rd Qu.:36.60 3rd Qu.:0.6262 3rd Qu.:41.00
## Max. :846.00 Max. :67.10 Max. :2.4200 Max. :81.00
## NA's :374 NA's :11
## Outcome
## Min. :0.000
## 1st Qu.:0.000
## Median :0.000
## Mean :0.349
## 3rd Qu.:1.000
## Max. :1.000
##
hist(df$Glucose, main = "Histograma de Glucosa", xlab = "Glucosa", border = "darkblue", col = "lightblue")
boxplot(list(df$Glucose, df$BMI, df$BloodPressure, df$SkinThickness), main = "Boxplot de Variables", col = "lightgreen")
boxplot(df$Insulin, col = "lightblue")
barplot(table(df$Outcome), main = "Distribución de Outcome", xlab = "Outcome", ylab = "Frecuencia", col = "salmon")
correlation_matrix <- cor(df %>% select(-Outcome) %>% na.omit(), use = "complete.obs")
corrplot::corrplot(correlation_matrix, method = "circle")
imputed_data_pmm <- mice(df, method = 'pmm', m=1, maxit = 5)
##
## iter imp variable
## 1 1 Glucose BloodPressure SkinThickness Insulin BMI
## 2 1 Glucose BloodPressure SkinThickness Insulin BMI
## 3 1 Glucose BloodPressure SkinThickness Insulin BMI
## 4 1 Glucose BloodPressure SkinThickness Insulin BMI
## 5 1 Glucose BloodPressure SkinThickness Insulin BMI
# Aplicar imputación por normal prediction
imputed_data_norm_predict <- mice(df, method = 'norm.predict', m=1, maxit = 5)
##
## iter imp variable
## 1 1 Glucose BloodPressure SkinThickness Insulin BMI
## 2 1 Glucose BloodPressure SkinThickness Insulin BMI
## 3 1 Glucose BloodPressure SkinThickness Insulin BMI
## 4 1 Glucose BloodPressure SkinThickness Insulin BMI
## 5 1 Glucose BloodPressure SkinThickness Insulin BMI
# Aplicar imputación por normal con observaciones completas (no bayesiano)
imputed_data_norm_nob <- mice(df, method = 'norm.nob', m=1, maxit = 5)
##
## iter imp variable
## 1 1 Glucose BloodPressure SkinThickness Insulin BMI
## 2 1 Glucose BloodPressure SkinThickness Insulin BMI
## 3 1 Glucose BloodPressure SkinThickness Insulin BMI
## 4 1 Glucose BloodPressure SkinThickness Insulin BMI
## 5 1 Glucose BloodPressure SkinThickness Insulin BMI
# Aplicar imputación por normal (bayesiano)
imputed_data_norm <- mice(df, method = 'norm', m=1, maxit = 5)
##
## iter imp variable
## 1 1 Glucose BloodPressure SkinThickness Insulin BMI
## 2 1 Glucose BloodPressure SkinThickness Insulin BMI
## 3 1 Glucose BloodPressure SkinThickness Insulin BMI
## 4 1 Glucose BloodPressure SkinThickness Insulin BMI
## 5 1 Glucose BloodPressure SkinThickness Insulin BMI
completed_data_pmm <- complete(imputed_data_pmm)
completed_data_norm_predict <- complete(imputed_data_norm_predict)
completed_data_norm_nob <- complete(imputed_data_norm_nob)
completed_data_norm <- complete(imputed_data_norm)
En esta parte se hizo la imputación de datos al dataframe df con los métodos estudiados en clase (pmm, norm predict, norm nob y norm)
Aquí hay algunas interpretaciones clave que podemos inferir del gráfico:
Círculos más grandes y oscuros: Indican una correlación más fuerte entre las variables correspondientes. Un círculo grande y oscuro en la diagonal superior izquierda (como el que aparece en la intersección de Glucose con Insulin) sugeriría una correlación positiva significativa entre estas variables. Esto podría significar que los niveles más altos de glucosa están asociados con niveles más altos de insulina.
Círculos pequeños o ausentes: Indican una correlación débil o inexistente. Por ejemplo, la correlación entre SkinThickness y Pregnancies parece ser muy baja, ya que el círculo es muy pequeño y claro.
Círculos azules claros: En general, los tonos más claros representan valores más bajos de correlación, y los tonos más oscuros indican valores más altos. No parece haber círculos negativos significativos, lo que implicaría una correlación negativa fuerte entre dos variables.
Relación con la variable de resultado: Dado que esta es una matriz de correlación y la variable de resultado Outcome (presencia o ausencia de diabetes) no está incluida, no se puede inferir nada directamente sobre la relación entre estas variables y el riesgo de diabetes.
Diagonal: La diagonal de la matriz de correlación siempre tendrá círculos oscuros y de tamaño máximo, ya que representa la correlación de cada variable consigo misma, lo cual es siempre perfectamente positivo (correlación de 1).
Implicaciones prácticas: En el contexto de la diabetes, se espera que ciertas variables como la glucosa y el IMC tengan una correlación positiva con otras medidas metabólicas. Las fuertes correlaciones positivas podrían ser útiles para predecir el riesgo de diabetes, mientras que las correlaciones débiles indican que las variables proporcionan información más independiente entre sí.
summary(df, na.rm = TRUE)
## Pregnancies Glucose BloodPressure SkinThickness
## Min. : 0.000 Min. : 44.0 Min. : 24.00 Min. : 7.00
## 1st Qu.: 1.000 1st Qu.: 99.0 1st Qu.: 64.00 1st Qu.:22.00
## Median : 3.000 Median :117.0 Median : 72.00 Median :29.00
## Mean : 3.845 Mean :121.7 Mean : 72.41 Mean :29.15
## 3rd Qu.: 6.000 3rd Qu.:141.0 3rd Qu.: 80.00 3rd Qu.:36.00
## Max. :17.000 Max. :199.0 Max. :122.00 Max. :99.00
## NA's :5 NA's :35 NA's :227
## Insulin BMI DiabetesPedigreeFunction Age
## Min. : 14.00 Min. :18.20 Min. :0.0780 Min. :21.00
## 1st Qu.: 76.25 1st Qu.:27.50 1st Qu.:0.2437 1st Qu.:24.00
## Median :125.00 Median :32.30 Median :0.3725 Median :29.00
## Mean :155.55 Mean :32.46 Mean :0.4719 Mean :33.24
## 3rd Qu.:190.00 3rd Qu.:36.60 3rd Qu.:0.6262 3rd Qu.:41.00
## Max. :846.00 Max. :67.10 Max. :2.4200 Max. :81.00
## NA's :374 NA's :11
## Outcome
## Min. :0.000
## 1st Qu.:0.000
## Median :0.000
## Mean :0.349
## 3rd Qu.:1.000
## Max. :1.000
##
Aquí hay algunas observaciones:
Pregnancies: El número de embarazos varía de 0 a 17, con una media de aproximadamente 3.85, lo que indica una distribución con un sesgo hacia las mujeres con menos embarazos.
Glucose: Los niveles de glucosa varían de 44 a 199, con una media alrededor de 121.7, reflejando la importancia de esta medida en la evaluación del riesgo de diabetes.
BloodPressure: La presión arterial tiene una media de 72.41, con valores que van de 24 a 122, lo que sugiere una variación normal en la población.
SkinThickness: El grosor de la piel muestra una amplia gama de valores, desde 7 hasta 99, pero más de 200 registros tienen valores faltantes (NA’s), indicando posibles problemas de datos.
Insulin: Hay un número significativo de valores faltantes (374), y los niveles varían ampliamente, de 14 a 846, lo que podría indicar variaciones en las condiciones de salud de los sujetos.
BMI: El Índice de Masa Corporal (BMI) varía de 18.2 a 67.1, con una mediana cercana a la clasificación de sobrepeso, lo que es relevante para el estudio de la diabetes.
DiabetesPedigreeFunction: Una medida de la predisposición genética a la diabetes, con un rango de -0.078 a 2.420, que parece contener un error dado el valor mínimo negativo.
Age: Las edades van de 21 a 81 años, con la mediana en los 29 años, indicando una población relativamente joven.
Outcome: Es una variable binaria que indica la presencia o ausencia de diabetes, con la mayoría de los sujetos sin diabetes (valor 0).
summary(completed_data_pmm) # Después de la imputación con PMM
## Pregnancies Glucose BloodPressure SkinThickness
## Min. : 0.000 Min. : 44.0 Min. : 24.00 Min. : 7.00
## 1st Qu.: 1.000 1st Qu.: 99.0 1st Qu.: 64.00 1st Qu.:21.00
## Median : 3.000 Median :117.0 Median : 72.00 Median :29.00
## Mean : 3.845 Mean :121.7 Mean : 72.13 Mean :28.94
## 3rd Qu.: 6.000 3rd Qu.:141.0 3rd Qu.: 80.00 3rd Qu.:36.00
## Max. :17.000 Max. :199.0 Max. :122.00 Max. :99.00
## Insulin BMI DiabetesPedigreeFunction Age
## Min. : 14.0 Min. :18.20 Min. :0.0780 Min. :21.00
## 1st Qu.: 75.0 1st Qu.:27.40 1st Qu.:0.2437 1st Qu.:24.00
## Median :119.0 Median :32.15 Median :0.3725 Median :29.00
## Mean :147.5 Mean :32.40 Mean :0.4719 Mean :33.24
## 3rd Qu.:183.0 3rd Qu.:36.60 3rd Qu.:0.6262 3rd Qu.:41.00
## Max. :846.0 Max. :67.10 Max. :2.4200 Max. :81.00
## Outcome
## Min. :0.000
## 1st Qu.:0.000
## Median :0.000
## Mean :0.349
## 3rd Qu.:1.000
## Max. :1.000
Pregnancies: El número de embarazos varía ampliamente (0 a 17), con una mediana de 3, lo que es típico para poblaciones generales.
Glucose: Los valores oscilan entre 44 y 199, con una mediana de 117, lo cual es esperado en un conjunto de datos que incluye individuos con y sin diabetes.
BloodPressure: La presión arterial tiene un mínimo de 24 mm Hg y un máximo de 122 mm Hg, y una mediana de 72 mm Hg, indicando una distribución razonable para un conjunto de datos de adultos.
SkinThickness: El grosor de la piel varía de 7 a 99 mm, aunque con una mediana de 28 mm. Los datos imputados parecen haber llenado los valores previamente ausentes, con una distribución plausible.
Insulin: La imputación de insulina muestra un rango amplio (14 a 846), que puede reflejar tanto variabilidad biológica como la imputación de valores que representan casos de hiperinsulinemia.
BMI: Con valores que van de 18.2 a 67.1, el conjunto de datos cubre desde pesos saludables hasta obesidad severa. La mediana de 32.5 sugiere sobrepeso.
DiabetesPedigreeFunction: Esta función tiene un rango interesante de -0.078 a 2.420. El valor mínimo negativo podría ser un error de datos, ya que se esperaría que este valor siempre fuera positivo.
Age: La edad de los sujetos va de 21 a 81 años, con una mediana de 29, indicando que el conjunto de datos tiende hacia una población más joven.
Outcome: Como variable binaria, muestra que la mayoría de los individuos no tienen diabetes (0). La media (0.349) sugiere que alrededor del 34.9% de los individuos en este conjunto de datos tienen diabetes, lo cual es consistente con la variable siendo binaria y posiblemente desbalanceada hacia el grupo no diabético.
Este resumen nos indica que las técnicas de imputación PMM han sido aplicadas y han rellenado los valores faltantes.
densityplot(imputed_data_pmm)
Glucosa: Las curvas azul y roja muestran una superposición considerable, lo que indica que la imputación PMM ha mantenido la distribución original de los datos con una ligera elevación en la densidad post-imputación. Este cambio leve sugiere un mínimo ajuste en la centralidad de los datos, posiblemente acercando los valores imputados a la media o mediana de los datos observados.
Presión Arterial: La similitud entre las dos curvas es notable, aunque la curva roja presenta un pico ligeramente más pronunciado. Esto podría interpretarse como una tendencia de los valores imputados a agruparse alrededor de una medida central, reduciendo potencialmente la variabilidad en los datos imputados comparados con los originales.
Grosor de la Piel: Las curvas roja y azul aquí también coinciden en gran medida, indicando una preservación efectiva de la distribución original tras la imputación. Esto es indicativo de una buena práctica de imputación, ya que no parece haber un impacto significativo en la forma general de la distribución de los datos.
Insulina: La imputación parece haber generado un leve incremento en la frecuencia de valores más bajos, como se evidencia por la altura aumentada de la curva roja en el extremo izquierdo. Esta observación puede requerir un análisis más detallado para entender cómo la imputación PMM está afectando los valores más bajos de insulina.
BMI: Ambas curvas mantienen una congruencia en su forma, aunque con una densidad ligeramente mayor en la curva roja en torno al centro de la distribución. Este efecto puede ser un reflejo del método PMM, que tiende a seleccionar valores cercanos a los originales, minimizando así la alteración de la distribución.
Conclusión
La técnica de PMM ha mostrado ser efectiva en la conservación de la forma general de las distribuciones de las variables médicas analizadas. A pesar de las leves diferencias en densidad y altura de las curvas, no hay evidencia de distorsiones significativas que pudieran comprometer los análisis subsecuentes.
summary(imputed_data_norm)
## Class: mids
## Number of multiple imputations: 1
## Imputation methods:
## Pregnancies Glucose BloodPressure
## "" "norm" "norm"
## SkinThickness Insulin BMI
## "norm" "norm" "norm"
## DiabetesPedigreeFunction Age Outcome
## "" "" ""
## PredictorMatrix:
## Pregnancies Glucose BloodPressure SkinThickness Insulin BMI
## Pregnancies 0 1 1 1 1 1
## Glucose 1 0 1 1 1 1
## BloodPressure 1 1 0 1 1 1
## SkinThickness 1 1 1 0 1 1
## Insulin 1 1 1 1 0 1
## BMI 1 1 1 1 1 0
## DiabetesPedigreeFunction Age Outcome
## Pregnancies 1 1 1
## Glucose 1 1 1
## BloodPressure 1 1 1
## SkinThickness 1 1 1
## Insulin 1 1 1
## BMI 1 1 1
Las variables SkinThickness, Insulin, y BMI han sido imputadas utilizando métodos basados en la distribución normal (“norm”), lo que sugiere que la imputación para estas variables se hizo asumiendo que seguían una distribución aproximadamente normal.
Las variables Pregnancies, Glucose, BloodPressure, DiabetesPedigreeFunction, Age, y Outcome no han sido imputadas, lo cual está indicado por “” en los métodos de imputación.
La PredictorMatrix muestra con qué variables se ha realizado la imputación para cada variable imputada. Un “1” indica que la variable de esa fila se utilizó como predictor en la imputación de la variable de esa columna. Por ejemplo, Pregnancies fue utilizada como predictor para SkinThickness, Insulin, y BMI, pero no para sí misma (indicado con un “0”).
densityplot(imputed_data_norm)
Las distribuciones pre y post-imputación parecen similares, lo que indicaría que el método de imputación preserva la estructura general de los datos.
No hay cambios drásticos en las formas de las distribuciones, lo que sugiere que no se introducen sesgos significativos.
En la imputación con el método NORM, las curvas de densidad de los datos imputados se alinean estrechamente con los datos originales, lo que sugiere una buena conservación de las propiedades estadísticas de los datos.
summary(imputed_data_norm_nob)
## Class: mids
## Number of multiple imputations: 1
## Imputation methods:
## Pregnancies Glucose BloodPressure
## "" "norm.nob" "norm.nob"
## SkinThickness Insulin BMI
## "norm.nob" "norm.nob" "norm.nob"
## DiabetesPedigreeFunction Age Outcome
## "" "" ""
## PredictorMatrix:
## Pregnancies Glucose BloodPressure SkinThickness Insulin BMI
## Pregnancies 0 1 1 1 1 1
## Glucose 1 0 1 1 1 1
## BloodPressure 1 1 0 1 1 1
## SkinThickness 1 1 1 0 1 1
## Insulin 1 1 1 1 0 1
## BMI 1 1 1 1 1 0
## DiabetesPedigreeFunction Age Outcome
## Pregnancies 1 1 1
## Glucose 1 1 1
## BloodPressure 1 1 1
## SkinThickness 1 1 1
## Insulin 1 1 1
## BMI 1 1 1
Indica que se ha realizado una única imputación y se han utilizado métodos de imputación normal no bayesiana (“norm.nob”) para las variables Glucose, BloodPressure, SkinThickness, y BMI. La matriz predictora revela qué variables se utilizaron como predictores en la imputación de cada una: un “1” indica que la variable de la fila se usó para predecir la variable de la columna, mientras que un “0” indica que no se utilizó.
densityplot(imputed_data_norm_nob)
Las curvas azules y rojas podrían representar los datos antes y después de la imputación, respectivamente. La similitud en la forma de las curvas sugiere que la imputación ha mantenido la distribución general de los datos originales. Además, no se observan cambios significativos en la distribución, lo que indica que el método de imputación ha sido efectivo y no ha introducido distorsiones notables en las variables imputadas.
summary(imputed_data_norm_predict)
## Class: mids
## Number of multiple imputations: 1
## Imputation methods:
## Pregnancies Glucose BloodPressure
## "" "norm.predict" "norm.predict"
## SkinThickness Insulin BMI
## "norm.predict" "norm.predict" "norm.predict"
## DiabetesPedigreeFunction Age Outcome
## "" "" ""
## PredictorMatrix:
## Pregnancies Glucose BloodPressure SkinThickness Insulin BMI
## Pregnancies 0 1 1 1 1 1
## Glucose 1 0 1 1 1 1
## BloodPressure 1 1 0 1 1 1
## SkinThickness 1 1 1 0 1 1
## Insulin 1 1 1 1 0 1
## BMI 1 1 1 1 1 0
## DiabetesPedigreeFunction Age Outcome
## Pregnancies 1 1 1
## Glucose 1 1 1
## BloodPressure 1 1 1
## SkinThickness 1 1 1
## Insulin 1 1 1
## BMI 1 1 1
Se emplearon métodos basados en la predicción normal (“norm.predict”) para las variables Glucose, BloodPressure, SkinThickness, Insulin, y BMI. No se aplicó imputación a Pregnancies, DiabetesPedigreeFunction, Age, y Outcome. La matriz de predictores muestra que todas las variables disponibles fueron utilizadas como predictores en la imputación de cada variable, lo cual es típico para un enfoque de imputación múltiple que intenta aprovechar toda la información disponible en el conjunto de datos.
densityplot(imputed_data_norm_predict)
Las líneas azules representan la distribución original de los datos antes de la imputación, y las rojas después de la imputación.
Para Glucose, BloodPressure, y SkinThickness, las curvas después de la imputación siguen estando muy alineadas con las curvas originales, lo que sugiere que la imputación no ha alterado significativamente la distribución subyacente de estos datos.
Para Insulin y BMI, hay una marcada diferencia entre las curvas pre y post-imputación, particularmente en BMI donde la curva roja post-imputación tiene picos múltiples. Esto podría indicar que la imputación ha introducido o exacerbado ciertas irregularidades en la distribución de estos datos. Sería importante investigar más a fondo por qué ocurre esto, ya que podría deberse a la naturaleza de los valores faltantes o a particularidades en la técnica de imputación utilizada.
Para las pruebas utilizaremos el dataframe completed data norm, para analizar los datos con uno de los métodos de imputación y su comportamiento, se debe tener en cuenta que puede que cambie dependiendo del método seleccionado, para este caso utilizaremos este como ejemplo.
insulin_test <- grubbs.test(completed_data_norm$Insulin, opposite = F)
insulin_test
##
## Grubbs test for one outlier
##
## data: completed_data_norm$Insulin
## G = 5.74304, U = 0.95694, p-value = 2.48e-06
## alternative hypothesis: highest value 846 is an outlier
Al nivel de significancia del 5%, concluimos que el valor más alto 846 es un valor atípico
preg_test <- grubbs.test(completed_data_norm$Pregnancies, opposite = F)
preg_test
##
## Grubbs test for one outlier
##
## data: completed_data_norm$Pregnancies
## G = 3.9040, U = 0.9801, p-value = 0.03367
## alternative hypothesis: highest value 17 is an outlier
Al nivel de significancia del 5%, concluimos que el valor más alto 17 es un valor atípico
glu_test <- grubbs.test(completed_data_norm$Glucose, opposite = F)
glu_test
##
## Grubbs test for one outlier
##
## data: completed_data_norm$Glucose
## G = 2.54972, U = 0.99151, p-value = 1
## alternative hypothesis: lowest value 44 is an outlier
Al nivel de significancia del 5%, concluimos que no tiene un valor atípico
bp_test <- grubbs.test(completed_data_norm$BloodPressure, opposite = T)
bp_test_ <- grubbs.test(completed_data_norm$BloodPressure, opposite = F)
print(list(bp_test, bp_test_))
## [[1]]
##
## Grubbs test for one outlier
##
## data: completed_data_norm$BloodPressure
## G = 3.90490, U = 0.98009, p-value = 0.03355
## alternative hypothesis: lowest value 24 is an outlier
##
##
## [[2]]
##
## Grubbs test for one outlier
##
## data: completed_data_norm$BloodPressure
## G = 4.02776, U = 0.97882, p-value = 0.01984
## alternative hypothesis: highest value 122 is an outlier
Al nivel de significancia del 5%, concluimos que el valor más alto 122 es un valor atípico y el valor más bajo 24 es un valor atípico
st_test <- grubbs.test(completed_data_norm$SkinThickness, opposite = F)
st_test
##
## Grubbs test for one outlier
##
## data: completed_data_norm$SkinThickness
## G = 6.71235, U = 0.94118, p-value = 3.693e-09
## alternative hypothesis: highest value 99 is an outlier
Al nivel de significancia del 5%, concluimos que el valor más alto 99 es un valor atípico
bmi_test <- grubbs.test(completed_data_norm$BMI, opposite = F)
bmi_test
##
## Grubbs test for one outlier
##
## data: completed_data_norm$BMI
## G = 5.00540, U = 0.96729, p-value = 0.0001738
## alternative hypothesis: highest value 67.1 is an outlier
Al nivel de significancia del 5%, concluimos que el valor más alto 67.1 es un valor atípico
dpf_test <- grubbs.test(completed_data_norm$DiabetesPedigreeFunction, opposite = F)
dpf_test
##
## Grubbs test for one outlier
##
## data: completed_data_norm$DiabetesPedigreeFunction
## G = 5.87973, U = 0.95487, p-value = 1.056e-06
## alternative hypothesis: highest value 2.42 is an outlier
Al nivel de significancia del 5%, concluimos que el valor más alto 2.42 es un valor atípico
age_test <- grubbs.test(completed_data_norm$Age, opposite = F)
age_test
##
## Grubbs test for one outlier
##
## data: completed_data_norm$Age
## G = 4.06107, U = 0.97847, p-value = 0.01716
## alternative hypothesis: highest value 81 is an outlier
Al nivel de significancia del 5%, concluimos que el valor más alto 81 es un valor atípico
subdata <- completed_data_norm[1:25,] # Reducir el dataset para hacer la prueba de dixon
preg_test <- dixon.test(subdata$Pregnancies, opposite = F)
preg_test
##
## Dixon test for outliers
##
## data: subdata$Pregnancies
## Q = 0.1, p-value = 0.3494
## alternative hypothesis: highest value 11 is an outlier
Con un nivel de significancia del 5% tenemos no tiene valores atípicos
glu_test <- dixon.test(subdata$Glucose, opposite = F)
glu_test
##
## Dixon test for outliers
##
## data: subdata$Glucose
## Q = 0.074074, p-value = 0.2051
## alternative hypothesis: highest value 197 is an outlier
Con un nivel de significancia del 5% tenemos no tiene valores atípicos
bp_test <- dixon.test(subdata$BloodPressure, opposite = F)
bp_test
##
## Dixon test for outliers
##
## data: subdata$BloodPressure
## Q = 0.32258, p-value = 0.3247
## alternative hypothesis: lowest value 30 is an outlier
Con un nivel de significancia del 5% tenemos no tiene valores atípicos
st_test <- dixon.test(subdata$SkinThickness, opposite = F)
st_test
##
## Dixon test for outliers
##
## data: subdata$SkinThickness
## Q = 0.29664, p-value = 0.4319
## alternative hypothesis: lowest value 8.03438793546078 is an outlier
Con un nivel de significancia del 5% tenemos no tiene valores atípicos
insulin_test <- dixon.test(subdata$Insulin, opposite = F)
insulin_test
##
## Dixon test for outliers
##
## data: subdata$Insulin
## Q = 0.42367, p-value = 0.07381
## alternative hypothesis: highest value 846 is an outlier
Con un nivel de significancia del 5% tenemos que el valor máximo 846 es un valor atípico
bmi_test <- dixon.test(subdata$BMI, opposite = F)
bmi_test
##
## Dixon test for outliers
##
## data: subdata$BMI
## Q = 0.135, p-value = 0.5796
## alternative hypothesis: highest value 45.8 is an outlier
Con un nivel de significancia del 5% tenemos no tiene valores atípicos
dpf_test <- dixon.test(subdata$DiabetesPedigreeFunction, opposite = F)
dpf_test
##
## Dixon test for outliers
##
## data: subdata$DiabetesPedigreeFunction
## Q = 0.74682, p-value < 2.2e-16
## alternative hypothesis: highest value 2.288 is an outlier
Con un nivel de significancia del 5% tenemos que el valor máximo 2.288 es un valor atípico
age_test <- dixon.test(subdata$Age, opposite = F)
age_test
##
## Dixon test for outliers
##
## data: subdata$Age
## Q = 0.15625, p-value = 0.7207
## alternative hypothesis: highest value 59 is an outlier
Con un nivel de significancia del 5% tenemos no tiene valores atípicos
all_stats_results <- list()
for (column_name in names(completed_data_norm)[-which(names(completed_data_norm) == "DiabetesPedigreeFunction")]) {
if (is.numeric(completed_data_norm[[column_name]])) {
test <- tryCatch({
rosnerTest(completed_data_norm[[column_name]], k = 6)
}, error = function(e) {
return(NULL)
})
if (!is.null(test) && !is.null(test$all.stats)) {
all_stats_results[[column_name]] <- test$all.stats
} else {
all_stats_results[[column_name]] <- NA
}
} else {
all_stats_results[[column_name]] <- NA
}
}
print(all_stats_results)
## $Pregnancies
## i Mean.i SD.i Value Obs.Num R.i+1 lambda.i+1 Outlier
## 1 0 3.845052 3.369578 17 160 3.904034 3.974092 FALSE
## 2 1 3.827901 3.338063 15 89 3.346880 3.973762 FALSE
## 3 2 3.813316 3.315699 14 299 3.072258 3.973432 FALSE
## 4 3 3.800000 3.297310 14 456 3.093431 3.973102 FALSE
## 5 4 3.786649 3.278714 13 29 2.810050 3.972771 FALSE
## 6 5 3.774574 3.263821 13 73 2.826572 3.972440 FALSE
##
## $Glucose
## i Mean.i SD.i Value Obs.Num R.i+1 lambda.i+1 Outlier
## 1 0 121.8166 30.51965 44 63 2.549720 3.974092 FALSE
## 2 1 121.9180 30.40969 199 662 2.534784 3.973762 FALSE
## 3 2 121.8174 30.30150 198 562 2.514153 3.973432 FALSE
## 4 3 121.7178 30.19564 197 9 2.493149 3.973102 FALSE
## 5 4 121.6193 30.09209 197 229 2.505002 3.972771 FALSE
## 6 5 121.5205 29.98759 197 409 2.517026 3.972440 FALSE
##
## $BloodPressure
## i Mean.i SD.i Value Obs.Num R.i+1 lambda.i+1 Outlier
## 1 0 72.24111 12.35399 122 107 4.027758 3.974092 TRUE
## 2 1 72.17624 12.23045 24 598 3.939041 3.973762 FALSE
## 3 2 72.23913 12.11369 30 19 3.486892 3.973432 FALSE
## 4 3 72.29434 12.02478 30 126 3.517267 3.973102 FALSE
## 5 4 72.34970 11.93471 114 692 3.489847 3.972771 FALSE
## 6 5 72.29512 11.84671 110 44 3.182730 3.972440 FALSE
##
## $SkinThickness
## i Mean.i SD.i Value Obs.Num R.i+1 lambda.i+1 Outlier
## 1 0 28.88758 10.445283 99.00000000 580 6.712352 3.974092 TRUE
## 2 1 28.79617 10.140048 63.00000000 446 3.373142 3.973762 FALSE
## 3 2 28.75152 10.070934 60.80159303 194 3.182433 3.973432 FALSE
## 4 3 28.70962 10.010504 60.00000000 58 3.125754 3.973102 FALSE
## 5 4 28.66867 9.952720 57.87803163 155 2.934812 3.972771 FALSE
## 6 5 28.63039 9.902803 0.03784939 34 2.887318 3.972440 FALSE
##
## $Insulin
## i Mean.i SD.i Value Obs.Num R.i+1 lambda.i+1 Outlier
## 1 0 150.1245 121.1684 846.0000 14 5.743045 3.974092 TRUE
## 2 1 149.2173 118.6084 744.0000 229 5.014677 3.973762 TRUE
## 3 2 148.4408 116.7189 680.0000 248 4.554184 3.973432 TRUE
## 4 3 147.7459 115.1990 600.0000 585 3.925851 3.973102 FALSE
## 5 4 147.1540 114.1043 588.5249 580 3.868137 3.972771 FALSE
## 6 5 146.5755 113.0526 579.0000 410 3.824986 3.972440 FALSE
##
## $BMI
## i Mean.i SD.i Value Obs.Num R.i+1 lambda.i+1 Outlier
## 1 0 32.46809 6.918916 67.1 178 5.005396 3.974092 TRUE
## 2 1 32.42294 6.809265 59.4 446 3.961817 3.973762 FALSE
## 3 2 32.38772 6.743451 57.3 674 3.694292 3.973432 FALSE
## 4 3 32.35515 6.687321 55.0 126 3.386236 3.973102 FALSE
## 5 4 32.32551 6.641229 53.2 121 3.143166 3.972771 FALSE
## 6 5 32.29816 6.602364 52.9 304 3.120374 3.972440 FALSE
##
## $Age
## i Mean.i SD.i Value Obs.Num R.i+1 lambda.i+1 Outlier
## 1 0 33.24089 11.76023 81 460 4.061069 3.974092 TRUE
## 2 1 33.17862 11.64053 72 454 3.335018 3.973762 FALSE
## 3 2 33.12794 11.56315 70 667 3.188755 3.973432 FALSE
## 4 3 33.07974 11.49346 69 124 3.125278 3.973102 FALSE
## 5 4 33.03272 11.42714 69 685 3.147531 3.972771 FALSE
## 6 5 32.98558 11.36006 68 675 3.082239 3.972440 FALSE
##
## $Outcome
## i Mean.i SD.i Value Obs.Num R.i+1 lambda.i+1 Outlier
## 1 0 0.3489583 0.4769514 1 1 1.365006 3.974092 FALSE
## 2 1 0.3481095 0.4766818 1 3 1.367559 3.973762 FALSE
## 3 2 0.3472585 0.4764098 1 5 1.370126 3.973432 FALSE
## 4 3 0.3464052 0.4761355 1 7 1.372708 3.973102 FALSE
## 5 4 0.3455497 0.4758587 1 9 1.375304 3.972771 FALSE
## 6 5 0.3446920 0.4755795 1 10 1.377915 3.972440 FALSE
Viendo los resultados de la prueba de Rosner podemos observar que las variables Outcome, Pregnancies y Glucose no tienen valores atípicos, el resto podemos ver que si tienene especialmente la variable Insulin con 5 valores atípicos.
rosner_insulin <- rosnerTest(completed_data_norm$DiabetesPedigreeFunction, k = 12)
## Warning in rosnerTest(completed_data_norm$DiabetesPedigreeFunction, k = 12): The true Type I error may be larger than assumed.
## Although the help file for 'rosnerTest' has a table with information
## on the estimated Type I error level,
## simulations were not run for k > 10 or k > floor(n/2).
rosner_insulin$all.stats
## i Mean.i SD.i Value Obs.Num R.i+1 lambda.i+1 Outlier
## 1 0 0.4718763 0.3313286 2.420 446 5.879733 3.974092 TRUE
## 2 1 0.4693364 0.3239768 2.329 229 5.740114 3.973762 TRUE
## 3 2 0.4669086 0.3171301 2.288 5 5.742410 3.973432 TRUE
## 4 3 0.4645281 0.3104137 2.137 371 5.387880 3.973102 TRUE
## 5 4 0.4623390 0.3046509 1.893 46 4.696067 3.972771 TRUE
## 6 5 0.4604640 0.3004070 1.781 59 4.395823 3.972440 TRUE
## 7 6 0.4587310 0.2967633 1.731 372 4.287150 3.972108 TRUE
## 8 7 0.4570591 0.2933457 1.699 594 4.233710 3.971776 TRUE
## 9 8 0.4554250 0.2900522 1.698 622 4.283971 3.971443 TRUE
## 10 9 0.4537879 0.2867083 1.600 396 3.997834 3.971110 TRUE
## 11 10 0.4522757 0.2838528 1.476 331 3.606533 3.970776 FALSE
## 12 11 0.4509234 0.2815864 1.461 623 3.587093 3.970442 FALSE
Y para la variables Insulin podemos ver que es la que tiene mayor datos atípicos con un total de 10.
lower_bound <- median(df$Outcome) - 3 * mad(df$Outcome, constant = 1)
lower_bound
## [1] 0
upper_bound <- median(df$Outcome) + 3 * mad(df$Outcome, constant = 1)
upper_bound
## [1] 0
outlier_ind <- which(df$Outcome < lower_bound | df$Outcome > upper_bound)
outlier_ind
## [1] 1 3 5 7 9 10 12 14 15 16 17 18 20 23 24 25 26 27
## [19] 32 38 39 40 44 46 49 54 57 62 65 67 71 73 79 85 89 94
## [37] 100 101 110 111 112 115 116 117 121 125 126 129 130 131 132 133 144 153
## [55] 155 156 160 165 166 171 172 176 178 180 186 187 188 189 190 193 194 196
## [73] 198 199 200 207 208 210 214 215 216 217 219 220 221 222 228 231 232 236
## [91] 237 238 239 243 244 246 255 256 260 262 265 267 270 271 277 281 284 285
## [109] 288 292 293 294 297 299 301 302 304 307 309 310 313 315 318 320 322 323
## [127] 324 327 329 333 338 339 340 350 356 357 358 360 361 364 367 370 371 376
## [145] 379 387 388 389 392 395 398 400 401 403 405 407 409 410 415 416 418 420
## [163] 425 426 428 430 436 441 444 445 446 449 452 456 459 469 477 481 485 486
## [181] 494 499 503 507 511 516 517 524 536 540 541 542 543 546 547 561 562 570
## [199] 578 580 581 585 587 589 591 593 596 599 604 605 607 612 613 615 619 620
## [217] 631 636 639 643 647 648 649 656 660 662 663 664 665 667 668 676 677 679
## [235] 682 684 690 692 694 696 697 702 703 707 709 710 713 716 717 720 723 731
## [253] 732 733 740 741 744 747 749 750 751 754 755 756 758 760 762 767
boxplot(completed_data_norm$Outcome)
hampel_outliers <- function(x, k = 10) {
mediana <- median(x, na.rm = TRUE)
mad <- mad(x, constant = 1, na.rm = TRUE)
outlier_threshold <- k * mad
lower_bound <- mediana - outlier_threshold
upper_bound <- mediana + outlier_threshold
outlier_ind <- which(x < lower_bound | x > upper_bound)
return(list(lower_bound = lower_bound, upper_bound = upper_bound, outliers = outlier_ind))
}
outliers_hampel <- list()
exclude_columns <- c("Outcome")
for (column_name in setdiff(names(completed_data_norm), exclude_columns)) {
if (is.numeric(completed_data_norm[[column_name]])) {
outliers_hampel[[column_name]] <- hampel_outliers(completed_data_norm[[column_name]], k = 3)
}
}
print(outliers_hampel)
## $Pregnancies
## $Pregnancies$lower_bound
## [1] -3
##
## $Pregnancies$upper_bound
## [1] 9
##
## $Pregnancies$outliers
## [1] 8 12 13 25 26 29 35 37 73 87 89 144 160 194 216 247 255 260 271
## [20] 275 282 299 307 324 328 334 358 359 376 437 456 459 465 506 511 519 543 559
## [39] 560 579 583 591 615 635 636 649 659 661 668 673 692 707 713 718 741 745 746
## [58] 764
##
##
## $Glucose
## $Glucose$lower_bound
## [1] 57
##
## $Glucose$upper_bound
## [1] 177
##
## $Glucose$outliers
## [1] 3 9 14 23 41 46 57 63 155 176 186 187 207 210 213 229 237 238 246
## [20] 259 261 318 320 328 333 340 360 361 400 409 426 428 441 446 490 499 507 546
## [39] 547 550 562 580 596 605 607 623 648 662 676 681 716 749 754 760
##
##
## $BloodPressure
## $BloodPressure$lower_bound
## [1] 48
##
## $BloodPressure$upper_bound
## [1] 96
##
## $BloodPressure$outliers
## [1] 5 19 44 81 85 107 126 178 188 208 304 347 363 370 380 388 441 465 550
## [20] 576 577 598 600 659 663 673 674 692 698 708 742
##
##
## $SkinThickness
## $SkinThickness$lower_bound
## [1] 8
##
## $SkinThickness$upper_bound
## [1] 50
##
## $SkinThickness$outliers
## [1] 34 58 68 87 100 103 117 121 155 194 197 212 255 276 304 379 446 520 533
## [20] 580 700
##
##
## $Insulin
## $Insulin$lower_bound
## [1] -63.49687
##
## $Insulin$upper_bound
## [1] 316.1896
##
## $Insulin$outliers
## [1] 3 9 14 23 27 34 55 56 81 112 124 132 140 154 155 156 184 186 187
## [20] 200 211 221 222 229 232 236 238 248 249 259 263 269 275 281 284 287 297 320
## [39] 361 371 376 379 393 400 410 416 437 438 441 475 481 487 496 506 520 537 575
## [58] 580 585 601 613 623 635 636 646 656 659 676 685 692 696 708 711 713 716 738
## [77] 750 754 758 760 768
##
##
## $BMI
## $BMI$lower_bound
## [1] 18.4
##
## $BMI$upper_bound
## [1] 46.3
##
## $BMI$outliers
## [1] 58 85 93 100 121 126 155 156 178 194 240 248 304 336 379 419 439 446 488
## [20] 527 591 674 682 747 748
##
##
## $DiabetesPedigreeFunction
## $DiabetesPedigreeFunction$lower_bound
## [1] -0.13
##
## $DiabetesPedigreeFunction$upper_bound
## [1] 0.875
##
## $DiabetesPedigreeFunction$outliers
## [1] 5 13 36 40 46 58 59 101 105 132 148 153 180 188 199 219 221 229 244
## [20] 246 255 260 266 267 268 271 280 293 309 315 331 337 339 357 371 372 380 383
## [39] 384 390 396 397 409 413 417 435 444 446 459 465 488 494 509 533 535 540 547
## [58] 575 589 591 594 607 614 619 622 623 658 660 662 674 693 700 703 717 745 748
## [77] 751 756
##
##
## $Age
## $Age$lower_bound
## [1] 8
##
## $Age$upper_bound
## [1] 50
##
## $Age$outliers
## [1] 9 10 13 14 15 25 29 31 40 44 54 68 94 116 124 130 141 149 187
## [20] 205 207 208 213 222 224 237 260 264 275 279 285 286 295 300 320 345 362 363
## [39] 364 376 389 402 454 457 459 460 476 480 488 490 496 499 510 513 517 518 520
## [58] 538 543 547 553 558 561 580 583 585 589 604 659 661 667 675 677 685 703 718
## [77] 720 735 758 760 764
Viendo los resultados de la prueba de Hampel, podemos observar que todas las variables seleccionadas tienen datos atípicos, BMI y Skin Thickness son las que menos tienen. Pero debemos tener en cuenta que esta prueba es muy sensible al basarse en la mediana y el MAD, es sensible a la forma de la distribución de los datos. Para variables con una distribución sesgada o con valores “legítimamente altos” (como podría ser el número de embarazos para algunas mujeres), el método puede identificar incorrectamente estos valores como atípicos.
boxplot(df$Glucose, main = "Boxplot de Glucosa antes del capping", col = "lightblue")
Podemos obeservar hay un valor atípico 0
x <- df$Glucose
qnt <- quantile(x, probs=c(.25, .75), na.rm = T)
caps <- quantile(x, probs=c(.05, .95), na.rm = T)
H <- 1.5 * IQR(x, na.rm = T)
x[x < (qnt[1] - H)] <- caps[1]
x[x > (qnt[2] + H)] <- caps[2]
boxplot(x, col = "salmon")
Con el capping quitamos en valor atípico y queda la grafíca sin estos valores
boxplot(df$Pregnancies, main = "Boxplot de Pregnancies antes del capping", col = "lightblue")
Podemos observar que para pregnancies tenemos 3 valores atípicos
x <- df$Pregnancies
qnt <- quantile(x, probs=c(.25, .75), na.rm = T)
caps <- quantile(x, probs=c(.05, .95), na.rm = T)
H <- 1.5 * IQR(x, na.rm = T)
x[x < (qnt[1] - H)] <- caps[1]
x[x > (qnt[2] + H)] <- caps[2]
boxplot(x, main = "Boxplot de Pregnancies después del capping", col = "salmon")
Con el capping quitamos los valores atípicos del boxplot como se puede
ver en la grafica.
boxplot(df$BloodPressure, main = "Boxplot de Blood Pressure antes del capping", col = "lightblue")
En el boxplot podemos observar que la variable blood pressure tiene
valores atípicos antes y despues de los valores extremos, 3 abajo del
minimo y 4 arriba del maximo
x <- df$BloodPressure
qnt <- quantile(x, probs=c(.25, .75), na.rm = T)
caps <- quantile(x, probs=c(.05, .95), na.rm = T)
H <- 1.5 * IQR(x, na.rm = T)
x[x < (qnt[1] - H)] <- caps[1]
x[x > (qnt[2] + H)] <- caps[2]
boxplot(x, main = "Boxplot de Blood Pressure después del capping", col = "salmon")
Con el capping eliminamos estos valores atípicos, quedando el boxplot sin estos.
boxplot(df$SkinThickness, main = "Boxplot de Skin Thickness antes del capping", col = "lightblue")
para skin thickness podemos observar en el boxplot que tiene solo un
valor atípico
x <- df$SkinThickness
qnt <- quantile(x, probs=c(.25, .75), na.rm = T)
caps <- quantile(x, probs=c(.05, .95), na.rm = T)
H <- 1.5 * IQR(x, na.rm = T)
x[x < (qnt[1] - H)] <- caps[1]
x[x > (qnt[2] + H)] <- caps[2]
boxplot(x, main = "Boxplot de Skin Thickness después del capping", col = "salmon")
Con capping podemos quitar ese unico valor atípico, como podemos ver en
la gráfica
boxplot(df$Insulin, main = "Boxplot de Insluin antes del capping", col = "lightblue")
Podemos observar que la variable insulin es una de las que más tiene
valores atípicos.
x <- df$Insulin
qnt <- quantile(x, probs=c(.25, .75), na.rm = T)
caps <- quantile(x, probs=c(.05, .95), na.rm = T)
H <- 1.5 * IQR(x, na.rm = T)
x[x < (qnt[1] - H)] <- caps[1]
x[x > (qnt[2] + H)] <- caps[2]
boxplot(x, main = "Boxplot de Insulin después del capping", col = "salmon")
Con capping podemos ver que todos los valores atípicos fueron eliminados
de la gráfica, y queda un boxplot más limpio para leer
boxplot(df$BMI, main = "Boxplot de BMI antes del capping", col = "lightblue")
En el boxplot podemos ver que la variable BMI tiene valores atípicos
debajo del mínimo y arriba del máximo
x <- df$BMI
qnt <- quantile(x, probs=c(.25, .75), na.rm = T)
caps <- quantile(x, probs=c(.05, .95), na.rm = T)
H <- 1.5 * IQR(x, na.rm = T)
x[x < (qnt[1] - H)] <- caps[1]
x[x > (qnt[2] + H)] <- caps[2]
boxplot(x, main = "Boxplot de BMI después del capping", col = "salmon")
Con el capping quitamos estos valores atípicos y queda un boxplot más
facil de analizar
boxplot(df$DiabetesPedigreeFunction, main = "Boxplot de Diabetes Pedigree Function antes del capping", col = "lightblue")
Podemos ver en el boxplot que la variable diabetes pedigree function
igual que insulin es la que tiene la gran mayor cantidad de números
atípicos.
x <- df$DiabetesPedigreeFunction
qnt <- quantile(x, probs=c(.25, .75), na.rm = T)
caps <- quantile(x, probs=c(.05, .95), na.rm = T)
H <- 1.5 * IQR(x, na.rm = T)
x[x < (qnt[1] - H)] <- caps[1]
x[x > (qnt[2] + H)] <- caps[2]
boxplot(x, main = "Boxplot de Diabetes Pedigree Function después del capping", col = "salmon")
Con el metodo de capping podemos ver que la gráfica queda mejor para el analisis del boxplot
boxplot(df$Age, main = "Boxplot de Age antes del capping", col = "lightblue")
La variable age es otro que tiene una cantidad considerable de datos
atípicos según el boxplot.
x <- df$Age
qnt <- quantile(x, probs=c(.25, .75), na.rm = T)
caps <- quantile(x, probs=c(.05, .95), na.rm = T)
H <- 1.5 * IQR(x, na.rm = T)
x[x < (qnt[1] - H)] <- caps[1]
x[x > (qnt[2] + H)] <- caps[2]
boxplot(x, main = "Boxplot de Age después del capping", col = "salmon")
Podemos observar con el método de capping que la gráfica queda sin los
valores atípicos.
# Cargar las librerías necesarias
library(plotly)
## Warning: package 'plotly' was built under R version 4.1.3
##
## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2':
##
## last_plot
## The following object is masked from 'package:stats':
##
## filter
## The following object is masked from 'package:graphics':
##
## layout
library(rjson)
library(readr)
library(dplyr)
library(ggplot2)
library(tidyr)
library(quantmod)
## Warning: package 'quantmod' was built under R version 4.1.3
## Loading required package: xts
## Warning: package 'xts' was built under R version 4.1.3
## Loading required package: zoo
## Warning: package 'zoo' was built under R version 4.1.3
##
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
##
## ################################### WARNING ###################################
## # We noticed you have dplyr installed. The dplyr lag() function breaks how #
## # base R's lag() function is supposed to work, which breaks lag(my_xts). #
## # #
## # Calls to lag(my_xts) that you enter or source() into this session won't #
## # work correctly. #
## # #
## # All package code is unaffected because it is protected by the R namespace #
## # mechanism. #
## # #
## # Set `options(xts.warn_dplyr_breaks_lag = FALSE)` to suppress this warning. #
## # #
## # You can use stats::lag() to make sure you're not using dplyr::lag(), or you #
## # can add conflictRules('dplyr', exclude = 'lag') to your .Rprofile to stop #
## # dplyr from breaking base R's lag() function. #
## ################################### WARNING ###################################
##
## Attaching package: 'xts'
## The following objects are masked from 'package:dplyr':
##
## first, last
## Loading required package: TTR
## Warning: package 'TTR' was built under R version 4.1.3
## Registered S3 method overwritten by 'quantmod':
## method from
## as.zoo.data.frame zoo
library(gapminder)
## Warning: package 'gapminder' was built under R version 4.1.3
df_stocks <- read.csv("C:/Users/pc/Desktop/Universidad/Semestre_VI/VIZ/Tarea2/Errores_comunes/stocks.csv")
p <- plot_ly(data = df_stocks, x = ~date, y = ~AMZN, type = 'scatter', mode = 'lines',
line = list(color = 'salmon')) %>%
layout(title = 'Amazon Stock Prices Over Time')
p
Esta gráfica muestra la evolución del precio de las acciones de Amazon a lo largo del tiempo. La gráfica ilustra cómo el precio de las acciones de Amazon ha aumentado significativamente desde sus inicios, lo que refleja el crecimiento y la expansión exitosa de la empresa en el comercio electrónico y otros sectores.
fig <- plot_ly(data = df_stocks) %>%
add_trace(x = ~date, y = ~AAPL, mode = 'lines', name = 'Apple', type = 'scatter') %>%
add_trace(x = ~date, y = ~AMZN, mode = 'lines+markers', name = 'Amazon', type = 'scatter') %>%
add_trace(x = ~date, y = ~FB, mode = 'lines+markers', name = 'Facebook', type = 'scatter') %>%
add_trace(x = ~date, y = ~GOOG, mode = 'lines+markers', name = 'Google', type = 'scatter',
line = list(color = 'red', width = 2, dash = 'dashdot')) %>%
layout(title = 'Stock Price data',
xaxis = list(title = 'Date'),
yaxis = list(title = 'Price'))
fig
Esta gráfica muestra la evolución de los precios de las acciones de cuatro grandes empresas tecnológicas: Apple, Amazon, Facebook y Google, a lo largo de un período de tiempo específico.
Se pueden observar varias tendencias interesantes:
Apple (línea azul) y Amazon (línea naranja) muestran una tendencia general al alza, con períodos de volatilidad. Apple parece haber experimentado un crecimiento más constante, mientras que Amazon exhibe mayores fluctuaciones.
Facebook (línea verde) tuvo un período de crecimiento significativo seguido por una caída sustancial, lo que sugiere posibles desafíos o eventos que afectaron su desempeño.
Google (línea roja) muestra una tendencia ascendente más suave, pero con un crecimiento notable en los últimos períodos de tiempo.
df_gapminder <- read.csv("https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv")
df_pakistan <- subset(df_gapminder, country == "Pakistan")
# Crea un gráfico de barras usando plot_ly
plot_ly(df_pakistan, x = ~year, y = ~pop, type = 'bar', name = 'Population of Pakistan Over the Years', marker = list(color = '#0099ff')) %>%
layout(title = 'Population of Pakistan Over the Years',
xaxis = list(title = 'Year'),
yaxis = list(title = 'Population'),
showlegend = FALSE)
Este gráfico muestra el crecimiento de la población de Pakistán a lo largo de los años, desde 1950 hasta 2000. Las barras representan el tamaño de la población, que ha aumentado constantemente con el tiempo. El gráfico ilustra el rápido crecimiento de la población de Pakistán, que pasó de alrededor de 40 millones en 1950 a más de 160 millones en el año 2000.
df_tips <- read_csv("C:/Users/pc/Desktop/Universidad/Semestre_VI/VIZ/Tarea2/Errores_comunes/tips.csv")
## New names:
## Rows: 244 Columns: 8
## -- Column specification
## -------------------------------------------------------- Delimiter: "," chr
## (4): sex, smoker, day, time dbl (4): ...1, total_bill, tip, size
## i Use `spec()` to retrieve the full column specification for this data. i
## Specify the column types or set `show_col_types = FALSE` to quiet this message.
## * `` -> `...1`
fig <- plot_ly(data = df_tips, x = ~day, y = ~tip, color = ~sex, type = 'bar') %>%
layout(title = 'Tips by Sex on Each Day',
xaxis = list(title = 'Day of the Week'),
yaxis = list(title = 'Tip Amount'))
# Muestra el gráfico
fig
Este gráfico de barras muestra las propinas recibidas por trabajadores de servicios masculinos y femeninos en diferentes días de la semana. Las barras representan los montos de las propinas, con barras azules que indican trabajadores varones y barras verdes para trabajadoras. Parece que los trabajadores tienden a recibir propinas más altas la mayoría de los días, particularmente los jueves, mientras que las trabajadoras reciben propinas más bajas en comparación.
fig <- plot_ly(data = df_tips, x = ~sex, y = ~total_bill, color = ~smoker, type = 'bar', barmode = 'group') %>%
layout(title = 'Total Bill by Sex and Smoker Status',
xaxis = list(title = 'Sex'),
yaxis = list(title = 'Total Bill'))
# Muestra el gráfico
fig
Este gráfico compara los montos totales de las facturas de fumadores y no fumadores, clasificados por género. Las barras representan la factura total, las barras verdes indican no fumadores y las barras azules representan fumadores. Tanto para hombres como para mujeres, la factura total es mayor para los no fumadores que para los fumadores. Además, la factura total de los hombres no fumadores es mayor que la de las mujeres no fumadoras.
df_asia <- subset(df_gapminder, continent == "Asia" & year == 2007 & pop > 2e6)
# Crea el gráfico de barras
plot <- plot_ly(data = df_asia, y = ~pop, x = ~country, text = ~pop, color = ~country, type = 'bar') %>%
layout(title = 'Population of Asian Countries in 2007 (Population > 2 million)',
xaxis = list(title = 'Country', tickangle = -45),
yaxis = list(title = 'Population'),
uniformtext = list(minsize = 8))
# Muestra el gráfico
plot
Esta gráfica de barras muestra la población de varios países asiáticos en 2007, para aquellos con una población superior a 2 millones de personas. Se puede observar que China e India son los países más poblados, seguidos por Indonesia, Pakistán y Bangladesh.
data("iris")
df_iris <- iris
fig <- plot_ly(data = df_iris, x = ~Sepal.Width, y = ~Sepal.Length, color = ~Species,
size = ~Petal.Length, text = ~paste("Petal Width: ", Petal.Width, "cm"),
type = 'scatter', mode = 'markers') %>%
layout(title = 'Sepal Width vs Sepal Length by Species',
xaxis = list(title = 'Sepal Width (cm)'),
yaxis = list(title = 'Sepal Length (cm)'))
fig
Este gráfico de dispersión muestra la relación entre el ancho y la longitud de los sépalos de diferentes especies de flores iris. Los puntos se agrupan por especie y se puede apreciar ciertos patrones y separaciones entre las diferentes especies según estas dos características.
fig <- plot_ly(data = df_iris, x = ~Sepal.Width, y = ~Sepal.Length,
text = ~Species, type = 'scatter', mode = 'markers',
marker = list(color = ~Sepal.Width, size = 10, line = list(width = 2), showscale = TRUE)) %>%
layout(title = 'Sepal Width vs Sepal Length',
xaxis = list(title = 'Sepal Width (cm)'),
yaxis = list(title = 'Sepal Length (cm)'))
fig
Este es otro gráfico de dispersión que muestra la misma relación entre ancho y longitud de sépalos, pero sin distinguir por especie. Se observa una forma general de nube de puntos que sugiere una correlación positiva entre ambas variables.
set.seed(123)
random_data <- data.frame(
x = rnorm(100000),
y = rnorm(100000),
color = rnorm(100000)
)
fig <- plot_ly(data = random_data, x = ~x, y = ~y, type = 'scattergl', mode = 'markers',
marker = list(color = ~color, colorscale = 'Viridis', line = list(width = 1))) %>%
layout(title = 'Random Scatter Plot',
xaxis = list(title = 'X'),
yaxis = list(title = 'Y'))
fig
Esta gráfica muestra una nube de puntos aleatorios dispersos en un plano cartesiano. No parece haber un patrón específico, por lo que podría representar datos o muestras aleatorias.
df_samer <- subset(df_gapminder, year == 2007 & continent == 'Asia')
plot_ly(df_samer, labels = ~country, values = ~pop, type = 'pie',
text = ~paste(country, "<br>", pop),
colors = c('blue', 'red', 'green', 'yellow', 'orange', 'purple')) %>%
layout(title = 'Population of Asian continent')
Esta gráfica circular o pie chart muestra la población relativa de los principales países asiáticos. China e India son los más poblados, seguidos por Indonesia, Pakistán, Bangladesh y otros países de la región.
colors <- c('blue', 'green', 'black', 'purple', 'red', 'brown')
data <- list(
labels = c('Water', 'Grass', 'Normal', 'Psychic', 'Fire', 'Ground'),
values = c(110, 90, 80, 80, 70, 60)
)
fig <- plot_ly(labels = data$labels, values = data$values, type = 'pie') %>%
layout(
hoverinfo = 'label+percent',
textinfo = 'label+percent',
pull = c(0.1, 0, 0.2, 0, 0, 0),
marker = list(colors = colors, line = list(color = '#FFFFFF', width = 2))
)
fig
Este gráfico de barras circular muestra la distribución de diferentes tipos de elementos. El agua representa el 22,4% de la distribución, mientras que la hierba y el tipo normal juntos constituyen alrededor del 35% de los elementos. El psíquico y el fuego tienen porcentajes más pequeños del 14,3% y el 12,2%, respectivamente.
set.seed(123)
dice_1 <- sample(1:6, 5000, replace = TRUE)
dice_2 <- sample(1:6, 5000, replace = TRUE)
dice_sum <- dice_1 + dice_2
# Histograma
histogram <- plot_ly(x = dice_sum, type = 'histogram', nbinsx = 11) %>%
layout(
xaxis = list(title = 'Dice Roll'),
yaxis = list(title = 'Frequency'),
title = '5000 Dice Roll Histogram',
bargap = 0.2,
showlegend = FALSE
)
violin <- plot_ly(x = rep("Dice Sum", length(dice_sum)), y = dice_sum, type = 'violin') %>%
layout(
xaxis = list(title = ''),
yaxis = list(title = 'Dice Roll'),
showlegend = FALSE
)
subplot <- subplot(
histogram, violin,
nrows = 2,
margin = 0.05
)
subplot
Esta es un histograma que muestra los resultados de 5000 lanzamientos de dados. La distribución sigue una forma de campana aproximada, lo que indica que los resultados se distribuyen de manera cercana a la distribución normal esperada. Los valores centrales de 6, 7 y 8 tienen las frecuencias más altas, mientras que los valores extremos de 2 y 12 tienen las frecuencias más bajas.
fig <- plot_ly(data = df_tips, x = ~total_bill, color = ~sex, type = 'histogram') %>%
layout(title = 'Total Bills by Sex',
barmode = 'stack',
barnorm = '')
fig
Este gráfico de barras agrupado muestra el recuento total de facturas para hombres y mujeres. El eje horizontal representa los montos de las facturas, y el eje vertical muestra las frecuencias. La distribución parece sesgada hacia la izquierda, con más facturas de montos más bajos tanto para hombres como para mujeres.
fig <- plot_ly(df_tips, x = ~sex, y = ~tip, type = 'box',
boxpoints = 'all') %>%
layout(title = 'Tip Distribution by Sex',
xaxis = list(title = 'Sex'),
yaxis = list(title = 'Tip'))
fig
Este diagrama de caja muestra la distribución de propinas para hombres y mujeres. Los hombres tienden a dar propinas ligeramente más altas en promedio, con una mediana y un rango intercuartílico más altos. Sin embargo, ambos grupos tienen valores atípicos tanto altos como bajos.
ggplot(df_tips, aes(x = day, y = tip, color = sex)) +
geom_boxplot() +
labs(x = "Day", y = "Tip", color = "Sex") +
theme_minimal()
Este gráfico de cajas y bigotes muestra la distribución de propinas por día de la semana y género. Tanto para hombres como para mujeres, las propinas tienden a ser más altas los fines de semana (sábado y domingo) en comparación con los días de semana. Se observan varios valores atípicos, particularmente en los días de semana.
fig <- plot_ly(df_tips, x = ~sex, y = ~tip, type = 'box', marker = list(color = 'blue'), boxmean = 'sd')
fig
Este gráfico muestra una representación de árbol de decisión para clasificar el sexo (femenino o masculino) en función de ciertas características o variables. Los rectángulos representan nodos de decisión y las ramas que salen muestran los posibles resultados.
fig <- plot_ly() %>%
add_boxplot(data = df_stocks, y = ~GOOG, name = 'Google', boxpoints = 'all', fillcolor = 'blue', jitter = 0.5, whiskerwidth = 0.2) %>%
add_boxplot(data = df_stocks, y = ~AAPL, name = 'Apple', boxpoints = 'all', fillcolor = 'red', jitter = 0.5, whiskerwidth = 0.2)
# Mostrar el diagrama
fig
Es un diagrama de caja que compara la distribución de un conjunto de datos (posiblemente ingresos o valoraciones) para Google y Apple. Se puede ver que la mediana de Google es menor que la de Apple, pero Google tiene más valores atípicos superiores.
fig <- plot_ly(df_tips, y = ~total_bill, type = 'violin', box = list(visible = TRUE), points = 'all')
fig
Es un gráfico de dispersión que muestra una gran cantidad de puntos concentrados formando una distribución similar a una curva normal o gaussiana. Parece representar la distribución de alguna variable o métrica.
fig <- subplot(
plot_ly(df_tips[df_tips$sex == "Male",], y = ~tip, x = ~smoker, type = 'violin', color = I("blue"), box = list(visible = TRUE), points = 'all', name = "Masculino"),
plot_ly(df_tips[df_tips$sex == "Female",], y = ~tip, x = ~smoker, type = 'violin', color = I("red"), box = list(visible = TRUE), points = 'all', name = "Femenino"),
nrows = 2
)
fig
Estas son distribuciones de densidad de kernels que muestran cómo se distribuyen ciertas características o variables para diferentes grupos. Las curvas azules y rojas representan dos grupos distintos, posiblemente sexo masculino y femenino. Los paneles muestran la distribución condicionada a una respuesta “Sí” o “No”.
df_smokers <- df_tips[df_tips$smoker == "Yes", ]
fig <- plot_ly(df_smokers, x = ~day, y = ~total_bill, type = 'violin', legendgroup = 'Yes', scalegroup = 'Yes', name = 'Yes', side = 'negative', line = list(color = 'blue'))
fig
Este gráfico muestra cuatro distribuciones de una variable (posiblemente una métrica o conteo) a lo largo de diferentes días de la semana (viernes, sábado, domingo, jueves). Las distribuciones tienen forma de curva normal con un pico pronunciado, lo que sugiere que la variable tiene valores concentrados alrededor de una media específica cada día.
df_non_smokers <- df_tips[df_tips$smoker == "No", ]
fig <- fig %>%
add_trace(data = df_non_smokers, x = ~day, y = ~total_bill, type = 'violin', legendgroup = 'No', scalegroup = 'Yes', name = 'No', side = 'positive', line = list(color = 'red'))
fig
Este gráfico muestra la distribución del total de facturas en diferentes días de la semana, divididas por una categoría binaria (Sí/No). El ancho de cada ‘violín’ muestra la densidad de puntos de datos en diferentes importes de billetes. Parece que la mediana de la factura total es generalmente más alta el domingo para ambas categorías, con una distribución más amplia el sábado, lo que indica una mayor variabilidad en los montos totales de la factura ese día.
flights <- read.csv("C:/Users/pc/Desktop/Universidad/Semestre_VI/VIZ/Tarea2/Errores_comunes/flights.csv")
fig <- plot_ly(flights, x = ~year, y = ~month, z = ~passengers, type = "heatmap", colors = colorRamp(c("blue", "yellow", "red")))
# Mostrar el gráfico
fig
El mapa de calor muestra el número de pasajeros por mes y año, con colores que indican el volumen de pasajeros. Los colores más cálidos representan un mayor número de pasajeros, mientras que los colores más fríos representan un número menor. Este mapa de calor sugiere una tendencia de aumento del número de pasajeros a lo largo de los años y posiblemente tendencias estacionales con ciertos meses que muestran mayores volúmenes de pasajeros de manera constante.
fig <- plot_ly(flights, x = ~year, y = ~month, z = ~passengers, color = ~year,
type = "scatter3d", mode = "markers", opacity = 0.7)
# Definir el tamaño del gráfico
fig <- layout(fig, width = 800, height = 400)
# Mostrar el gráfico
fig
Este gráfico es una representación 3D del número de pasajeros por mes y año. Cada punto representa el número de pasajeros en un mes y año específico, y el degradado de color muestra el paso del tiempo de 1950 a 1960. La tendencia sugiere un aumento general de pasajeros a lo largo de los años, y también se pueden observar patrones estacionales.
fig <- plot_ly(flights, x = ~year, y = ~month, z = ~passengers, color = ~year, type = "scatter3d", mode = "lines")
# Mostrar el gráfico
fig
El gráfico es similar al gráfico de dispersión 3D pero muestra los datos como una serie de líneas que conectan los puntos del mismo año. Esto ayuda a rastrear el patrón del número de pasajeros a lo largo de cada año, destacando más claramente las tendencias estacionales, así como la tendencia al alza en el número de pasajeros a lo largo del tiempo.
fig <- plot_ly(data = flights, color = ~month) %>%
add_trace(
type = 'splom',
dimensions = list(
list(label = 'year', values = ~year),
list(label = 'month', values = ~month),
list(label = 'passengers', values = ~passengers)
)
)
fig
Año vs. Año (panel superior izquierdo): Dado que las variables son las mismas en ambos ejes, los puntos forman una línea perfecta ascendente, indicando simplemente la progresión temporal de un año a otro.
Mes vs. Año (paneles superiores e inferiores del medio): Estos gráficos muestran la distribución de los vuelos a lo largo de cada mes en diferentes años. No parece haber una tendencia o patrón claro en la variación anual, pero sí se observa la recurrencia estacional por el color de los puntos.
Pasajeros vs. Año (panel superior derecho): Existe una tendencia creciente en el número de pasajeros a lo largo de los años, lo que indica un crecimiento en la industria de vuelos o un aumento en la demanda de viajes aéreos durante este período.
Mes vs. Mes (diagonal central): Al igual que con el año vs. año, estos puntos forman una línea diagonal perfecta, ya que es la misma variable en ambos ejes.
Pasajeros vs. Mes (paneles inferiores a la derecha y superior a la izquierda): Estos paneles muestran variaciones estacionales en el número de pasajeros, con algunos meses teniendo consistentemente más pasajeros que otros, como se puede ver por la concentración de colores. Por ejemplo, hay meses con picos de pasajeros (posiblemente los meses de vacaciones).
Pasajeros vs. Pasajeros (panel inferior derecho): De nuevo, como es la misma variable en ambos ejes, los datos forman una línea perfectamente ascendente.
library(countrycode)
df <- gapminder %>% filter(year == 2007)
df$iso_alpha <- countrycode(df$country, origin = "country.name", destination = "iso3c")
fig <- plot_geo(df, locations = ~iso_alpha,
color = ~continent,
hoverinfo = "text",
text = ~paste("Country: ", country, "<br>Population: ", pop),
size = ~pop,
marker = list(line = list(width = 0.5, color = "black")),
projection = "orthographic")
fig
## No scattergeo mode specifed:
## Setting the mode to markers
## Read more about this attribute -> https://plotly.com/r/reference/#scatter-mode
Este mapa muestra burbujas en varios lugares del mundo, con diferentes colores que representan diferentes continentes. El tamaño de las burbujas probablemente represente una cantidad, como la población, el PIB o alguna otra estadística. La distribución de los tamaños de las burbujas podría indicar que Asia y Europa tienen valores más altos de la cantidad medida, aunque sin una leyenda para los tamaños, es difícil interpretar los valores exactos.
url <- 'https://raw.githubusercontent.com/plotly/datasets/master/geojson-counties-fips.json'
counties <- rjson::fromJSON(file=url)
url2<- "https://raw.githubusercontent.com/plotly/datasets/master/fips-unemp-16.csv"
df <- read.csv(url2, colClasses=c(fips="character"))
g <- list(
scope = 'usa',
projection = list(type = 'albers usa'),
showlakes = TRUE,
lakecolor = toRGB('white')
)
fig <- plot_ly()
fig <- fig %>% add_trace(
type="choropleth",
geojson=counties,
locations=df$fips,
z=df$unemp,
colorscale="Viridis",
zmin=0,
zmax=12,
marker=list(line=list(
width=0)
)
)
fig <- fig %>% colorbar(title = "Unemployment Rate (%)")
fig <- fig %>% layout(
title = "US Unemployment"
)
fig <- fig %>% layout(
geo = g
)
fig
El mapa de coropletas muestra los Estados Unidos con diferentes áreas coloreadas para representar la tasa de desempleo. La escala de colores indica que el verde más oscuro representa tasas de desempleo más bajas, mientras que el amarillo indica tasas más altas. Este mapa permite una comparación rápida del desempleo en diferentes regiones del país.
wind <- read_csv("C:/Users/pc/Desktop/Universidad/Semestre_VI/VIZ/Tarea2/Errores_comunes/wind.csv")
## New names:
## Rows: 128 Columns: 4
## -- Column specification
## -------------------------------------------------------- Delimiter: "," chr
## (2): direction, strength dbl (2): ...1, frequency
## i Use `spec()` to retrieve the full column specification for this data. i
## Specify the column types or set `show_col_types = FALSE` to quiet this message.
## * `` -> `...1`
fig <- plot_ly(data = wind, type = 'scatterpolar', mode = 'markers',
r = ~frequency, theta = ~direction,
color = ~strength, size = ~frequency, symbol = ~strength)
fig <- fig %>% layout(
polar = list(
radialaxis = list(visible = TRUE, range = c(min(wind$frequency), max(wind$frequency))),
angularaxis = list(direction = "clockwise")
)
)
fig
Este gráfico de rosa de los vientos proporciona una descripción general de la dirección del viento y las frecuencias de velocidad. La trama se divide en direcciones cardinales e intercardinales, con diferentes símbolos y colores que representan categorías de velocidad. Vemos que la mayoría de las velocidades del viento caen en las categorías inferiores, con relativamente menos casos de velocidades más altas.
colors <- c('blue', 'cyan', 'green', 'yellow', 'orange', 'red', 'darkred')
p <- plot_ly(wind, type = 'scatterpolar', mode = 'lines',
r = ~frequency, theta = ~direction,
line = list(color = ~as.numeric(strength), width = 2),
color = ~strength, colors = colors,
opacity = 0.7)
p <- p %>% layout(
polar = list(
radialaxis = list(
visible = TRUE,
range = c(0, max(wind$frequency))
),
bgcolor = "black"
),
paper_bgcolor = "black",
plot_bgcolor = "black",
showlegend = TRUE,
width = 800,
height = 400
)
p
El gráfico de radar es una forma de mostrar múltiples puntos de datos y la variación entre ellos. Aquí, parece representar los mismos datos que la rosa de los vientos: dirección del viento y frecuencia de la velocidad. Cada línea conecta puntos de la misma categoría de velocidad en diferentes direcciones, lo que facilita comparar la distribución de las velocidades del viento en cada dirección.
df_exp <- read_csv("C:/Users/pc/Desktop/Universidad/Semestre_VI/VIZ/Tarea2/Errores_comunes/experiment.csv")
## New names:
## Rows: 100 Columns: 6
## -- Column specification
## -------------------------------------------------------- Delimiter: "," chr
## (2): gender, group dbl (4): ...1, experiment_1, experiment_2, experiment_3
## i Use `spec()` to retrieve the full column specification for this data. i
## Specify the column types or set `show_col_types = FALSE` to quiet this message.
## * `` -> `...1`
df_exp <- df_exp %>%
mutate(gender = as.factor(gender))
colors <- c('female' = '#FF69B4', 'male' = '#1E90FF') # Rosa para 'female', Azul para 'male'
fig <- plot_ly(data = df_exp, type = 'scatterternary',
mode = 'markers',
a = ~experiment_1,
b = ~experiment_2,
c = ~experiment_3,
hoverinfo = 'text',
text = ~paste("Group:", group, "<br>Gender:", gender),
marker = list(size = 10,
color = ~I(colors[as.character(gender)])))
fig
Un gráfico ternario muestra las proporciones de tres variables que suman una constante. En este gráfico, el Componente A, el Componente B y el Componente C deben sumar 1 para cualquier punto dado. La agrupación de puntos alrededor del centro sugiere que los valores de estos componentes están relativamente equilibrados para la mayoría de las observaciones.
ggplot(df_tips, aes(x = total_bill, y = tip, color = smoker)) +
geom_point() +
facet_wrap(~sex) +
labs(title = "Scatter plot of Total Bill vs. Tip", x = "Total Bill", y = "Tip") +
theme_minimal()
Este diagrama de dispersión compara la factura total con la propina dada, dividida por género (mujer a la izquierda y hombre a la derecha), con codificación de colores para fumadores y no fumadores. Esto puede proporcionar información sobre el comportamiento de dejar propinas por género y preferencia de fumar, aunque no muestra un patrón claro de correlación a primera vista.
df_att <-read_csv("C:/Users/pc/Desktop/Universidad/Semestre_VI/VIZ/Tarea2/Errores_comunes/att.csv")
## New names:
## Rows: 60 Columns: 6
## -- Column specification
## -------------------------------------------------------- Delimiter: "," chr
## (1): attention dbl (5): ...1, Unnamed: 0, subject, solutions, score
## i Use `spec()` to retrieve the full column specification for this data. i
## Specify the column types or set `show_col_types = FALSE` to quiet this message.
## * `` -> `...1`
p <- ggplot(df_att, aes(x = solutions, y = score)) +
geom_line() +
facet_wrap(~subject, ncol = 5) +
labs(title = 'Scores Based on Attention', x = 'Solutions', y = 'Score')
print(p)
Se utilizan múltiplos pequeños para comparar muchos gráficos que muestran el mismo tipo de datos. Cada minigráfico tiene un título con un número, que sugiere un individuo o una categoría, y traza la ‘Puntuación’ frente a las ‘Soluciones’. Este diseño permite una comparación rápida entre diferentes temas para ver cómo varían sus puntuaciones con la cantidad de soluciones.
df_cnt <-read_csv("C:/Users/pc/Desktop/Universidad/Semestre_VI/VIZ/Tarea2/Errores_comunes/cnt.csv")
## New names:
## Rows: 1704 Columns: 9
## -- Column specification
## -------------------------------------------------------- Delimiter: "," chr
## (3): country, continent, iso_alpha dbl (6): ...1, year, lifeExp, pop,
## gdpPercap, iso_num
## i Use `spec()` to retrieve the full column specification for this data. i
## Specify the column types or set `show_col_types = FALSE` to quiet this message.
## * `` -> `...1`
fig <- df_cnt %>%
plot_ly(
x = ~gdpPercap,
y = ~lifeExp,
size = ~pop,
color = ~continent,
frame = ~year,
text = ~country,
hoverinfo = "text",
type = 'scatter',
mode = 'markers'
)
fig <- fig %>% layout(
xaxis = list(
type = "log"
)
)
fig
El gráfico de burbujas interactivo rastrea la esperanza de vida en comparación con el PIB per cápita, donde el tamaño de la burbuja posiblemente represente el tamaño de la población y los colores representen diferentes continentes. Hay una clara tendencia positiva, que indica que a medida que aumenta el PIB per cápita, la esperanza de vida también tiende a aumentar. El control deslizante en la parte inferior sugiere que puede pasar los años para ver cómo estas variables han cambiado con el tiempo.
fig <- df_cnt %>%
plot_ly(
x = ~continent,
y = ~pop,
color = ~continent,
frame = ~year,
text = ~country,
hoverinfo = "text",
type = 'bar',
marker = list(size = ~pop)
)
fig
Este gráfico de barras animado muestra la población (población) por continente a lo largo del tiempo. El botón “Reproducir” en la parte inferior sugiere que puedes observar cómo cambian las poblaciones a lo largo de los años. En 1952, podemos ver que Asia tenía una población significativamente mayor que otros continentes. Este tipo de gráfico sería útil para observar las tendencias de crecimiento de la población.
library(sf) # para trabajar con datos espaciales
## Linking to GEOS 3.10.2, GDAL 3.4.1, PROJ 7.2.1; sf_use_s2() is TRUE
library(ggplot2)
library(dplyr)
library(plotly)
library(leaflet)
##
## Attaching package: 'leaflet'
## The following object is masked from 'package:xts':
##
## addLegend
library(leaflet.extras)
datos_sf <- st_read("C:/Users/pc/Desktop/factoriesindustrial-sites.geojson")
## Reading layer `factoriesindustrial-sites' from data source
## `C:\Users\pc\Desktop\factoriesindustrial-sites.geojson' using driver `GeoJSON'
## Simple feature collection with 732 features and 7 fields
## Geometry type: POINT
## Dimension: XY
## Bounding box: xmin: 2.730691 ymin: 6.382559 xmax: 4.190527 ymax: 6.687934
## Geodetic CRS: WGS 84
datos_sf <- datos_sf %>%
mutate(lon = st_coordinates(geometry)[,1],
lat = st_coordinates(geometry)[,2])
names(datos_sf)
## [1] "id" "state_code" "source" "name" "status"
## [6] "ward_code" "global_id" "geometry" "lon" "lat"
plot_ly(datos_sf, x = ~lon, y = ~lat, type = "scatter", mode = "markers",
marker = list(color = "blue")) %>%
layout(title = "A Scatter Plot of the Latitude and Longitude of Factories in Lagos",
xaxis = list(title = "Longitude", gridcolor = "lightgrey", showgrid = TRUE),
yaxis = list(title = "Latitude", gridcolor = "lightgrey", showgrid = TRUE),
plot_bgcolor = 'rgba(0,0,0,0)')
Este gráfico muestra la latitud y longitud de las fábricas en Lagos. En el mismo gráfico se superponen dos trazas, que probablemente representan diferentes tipos de fábricas o quizás diferentes épocas. Los grupos pueden indicar áreas industriales dentro de la ciudad.
mark <- leaflet() %>%
addTiles(urlTemplate = "https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png") %>%
setView(lng = 3.3792, lat = 6.5244, zoom = 12)
for(i in 1:nrow(datos_sf)) {
mark <- mark %>%
addMarkers(lng = datos_sf$lon[i], lat = datos_sf$lat[i], popup = datos_sf$name[i])
}
mark
Aquí, las ubicaciones individuales de las fábricas en Lagos están marcadas en un mapa con íconos puntuales, lo que permite una visualización geográfica de la distribución de las fábricas. El mapa está ampliado y muestra una alta densidad de fábricas en ciertas áreas, lo que sugiere que se trata de zonas industriales clave.
bubble <- leaflet() %>%
addProviderTiles(providers$CartoDB.Positron) %>%
setView(lng = 3.3792, lat = 6.5244, zoom = 12)
mc <- markerClusterOptions()
bubble <- bubble %>%
addMarkers(lng = datos_sf$lon, lat = datos_sf$lat, clusterOptions = mc)
bubble
Este mapa representa diferentes áreas de Lagos con burbujas, donde el tamaño de la burbuja probablemente corresponde al número de fábricas en esa área. Las burbujas más grandes representan una mayor concentración de fábricas, lo que proporciona una comparación visual rápida de la actividad industrial en diferentes regiones.
heat <- leaflet() %>%
addProviderTiles(providers$CartoDB.Positron) %>%
setView(lng = 3.3792, lat = 6.5244, zoom = 10)
heat <- heat %>%
addHeatmap(lng = ~lon, lat = ~lat, data = datos_sf, radius = 10, blur = 20, max = 0.05)
heat
Un mapa de calor indica la densidad con color, mostrando cuán concentradas están las fábricas en ciertos lugares. Los colores más cálidos (como el rojo y el amarillo) sugieren mayores concentraciones de fábricas, mientras que los colores más fríos (como el azul) representan densidades más bajas. Este mapa destaca las zonas más industrializadas.
status <- aggregate(cbind(count = status) ~ status, data = datos_sf, FUN = length)
colnames(status)[2] <- "count"
ggplot(status, aes(x = status, y = count, fill = status)) +
geom_bar(stat = "identity") +
scale_fill_manual(values = c("In Use" = "blue", "Unused Good" = "yellow", "Unused Poor" = "purple")) +
labs(title = "Status of Factories and Industrial Sites in Lagos", x = "Status", y = "Count")
El gráfico de barras muestra el estado de las fábricas y sitios industriales en Lagos, clasificados como “En uso”, “Bien no utilizado” y “Pobres no utilizados”. La mayoría de las fábricas están en uso, y un pequeño número se clasifica como sin uso, ya sea en buenas o malas condiciones.
circle <- leaflet() %>%
addProviderTiles(providers$CartoDB.Positron) %>%
setView(lng = 3.3792, lat = 6.5244, zoom = 10)
color_producer <- function(val) {
if (val == 'In Use') {
return('blue')
} else if (val == 'Unused Good') {
return('yellow')
} else {
return('purple')
}
}
for(i in 1:nrow(datos_sf)) {
circle <- circle %>%
addCircles(lng = datos_sf$lon[i], lat = datos_sf$lat[i], radius = 20,
color = color_producer(datos_sf$status[i]), fill = TRUE)
}
circle
fig_scatter <- plot_ly(data = datos_sf, type = 'scattermapbox', mode = 'markers',
lat = ~lat, lon = ~lon,
color = ~status, colors = c('In Use' = 'blue', 'Unused Good' = 'yellow', 'Unused Poor' = 'purple'),
text = ~name, hoverinfo = 'text') %>%
layout(mapbox = list(
style = 'carto-positron',
zoom = 10,
center = list(lat = 6.5244, lon = 3.3792)
)
)
fig_scatter
Al igual que la segunda imagen, este mapa también tiene íconos señalados pero con códigos de colores para diferenciar el estado de las fábricas: “En uso”, “Bueno no usado” o “Pobre no usado”. Esto permite una evaluación del estado operativo de las fábricas de toda la ciudad.
m <- leaflet(datos_sf) %>%
addProviderTiles("CartoDB.Positron") %>%
setView(lng = 3.3792, lat = 6.5244, zoom = 9) %>%
addHeatmap(lng = ~lon, lat = ~lat, blur = 15, max = 0.05, radius = 15)
m
Este mapa de densidad, a menudo denominado “mapa de puntos críticos”, utiliza colores para representar la densidad de las fábricas. Las zonas con mayores concentraciones están en rojo, mientras que las que tienen menos están en azul. Esta visualización ayuda a identificar qué áreas tienen la mayor agregación de sitios industriales.
end_date <- as.Date("2023-12-31")
start_date <- as.Date("2023-01-01")
data <- getSymbols("TGLS", src = "yahoo", from = start_date, to = end_date)
tgls <- as.data.frame(TGLS)
summary(tgls$TGLS.Close)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 29.97 34.24 38.09 39.32 44.17 53.88
frequency(tgls$TGLS.Close)
## [1] 1
Frequency equals 1 so we don’t have to eliminate a tendancy.
plot(tgls$TGLS.Close,
type = "l",
main = "TGLS Closing Price",
ylab = "Price ($)",
xlab = "Date")
acf(tgls$TGLS.Close, lag.max = 300, ylim = c(-1, 1), main = "ACF of the original sery")
We can assume that the time sery follow a tendancy bceause the values go
out of the lines.
tgls_d1 <- diff(tgls$TGLS.Close, lag=1)[-1]
plot(tgls_d1,
type = "l",
main = "TGLS - First Differencing",
ylab = "Price ($)",
xlab = "Date")
acf(tgls_d1, lag.max = 300, ylim = c(-0.5, 0.5), main = "ACF of 1st Differencing")
We can assume that the time sery doesn’t follow a tendancy because the
values mainly stay between the lines.
pacf(tgls$TGLS.Close, lag.max = 300, ylim = c(-0.5, 0.5), main = "Partial ACF of the original sery")
With the partial autocorrelation function, it seems we don’t have a
tendancy.
best_order_arima_aic <- function(input, rge_p, rge_d, rge_q) {
best_aic <- Inf
best_pdq <- NULL
fit <- NULL
for(p in rge_p) {
for(d in rge_d) {
for (q in rge_q) {
tryCatch({
fit <- arima(input, order=c(p, d, q))
aic <- AIC(fit)
if (aic < best_aic) {
best_aic <- aic
best_pdq <- c(p, d, q)
}
}, error=function(e){})
}
}
}
return(best_pdq)
}
best_order_arima_bic <- function(input, rge_p, rge_d, rge_q) {
best_bic <- Inf
best_pdq <- NULL
fit <- NULL
for(p in rge_p) {
for(d in rge_d) {
for (q in rge_q) {
tryCatch({
fit <- arima(input, order=c(p, d, q))
bic <- BIC(fit)
if (bic < best_bic) {
best_bic <- bic
best_pdq <- c(p, d, q)
}
}, error=function(e){})
}
}
}
return(best_pdq)
}
best_order_arima_hqic <- function(input, rge_p, rge_d, rge_q) {
best_hqic <- Inf
best_pdq <- NULL
fit <- NULL
for(p in rge_p) {
for(d in rge_d) {
for (q in rge_q) {
tryCatch({
fit <- arima(input, order=c(p, d, q))
hqic <- AIC(fit)
if (hqic < best_hqic) {
best_hqic <- hqic
best_pdq <- c(p, d, q)
}
}, error=function(e){})
}
}
}
return(best_pdq)
}
MAPE <- function(actual, forecast) {
mean(abs((actual - forecast) / actual)) * 100
}
MAE <- function(actual, forecast) {
mean(abs(actual - forecast))
}
RMSE <- function(actual, forecast) {
sqrt(mean((actual - forecast)^2))
}
MSE <- function(actual, forecast) {
mean((actual - forecast)^2)
}
R2 <- function(actual, forecast) {
cor(actual, forecast)^2
}
rge_p = c(0:7)
rge_d = c(0:1)
rge_q = c(0:7)
best_order_aic = best_order_arima_aic(tgls$TGLS.Close, rge_p, rge_d, rge_q)
best_order_bic = best_order_arima_bic(tgls$TGLS.Close, rge_p, rge_d, rge_q)
best_order_hqic = best_order_arima_hqic(tgls$TGLS.Close, rge_p, rge_d, rge_q)
Best order AIC:
best_order_aic
## [1] 2 1 2
Best order BIC:
best_order_bic
## [1] 0 1 0
Best order HQIC:
best_order_hqic
## [1] 2 1 2
nb_data <- nrow(tgls)
nb_day_predicted = c(14, 21, 28)
train_size = nb_data - max(nb_day_predicted)
train <- tgls$TGLS.Close[1:train_size]
test <- tgls$TGLS.Close[(train_size + 1):(train_size + 14)]
test <- test[complete.cases(test)]
test_dates <- index(tgls)[(train_size + 1):(train_size + 14)]
test_dates <- test_dates[complete.cases(test_dates)]
forecast_aic <- c()
forecast_bic <- c()
forecast_hqic <- c()
for (i in 1:14) {
fit_aic <- arima(train, order = best_order_aic)
fit_bic <- arima(train, order = best_order_bic)
fit_hqic <- arima(train, order = best_order_hqic)
forecast_aic <- c(forecast_aic, predict(fit_aic, n.ahead = 1)$pred)
forecast_bic <- c(forecast_bic, predict(fit_bic, n.ahead = 1)$pred)
forecast_hqic <- c(forecast_hqic, predict(fit_hqic, n.ahead = 1)$pred)
train <- c(train, test[i])
}
n_last = 50
last_dates <- tail(index(tgls), n_last)
last_tgls <- tail(tgls$TGLS.Close, n_last)
last_forecast_aic <- tail(forecast_aic, n_last)
last_forecast_bic <- tail(forecast_bic, n_last)
last_forecast_hqic <- tail(forecast_hqic, n_last)
plot(last_dates, last_tgls, type = "l", col = "black", ylim = range(c(last_tgls, last_forecast_aic, last_forecast_bic, last_forecast_hqic)),
main = "TGLS Closing Price", ylab = "Price ($)", xlab = "Date")
lines(test_dates, forecast_aic, col = "red")
lines(test_dates, forecast_bic, col = "green")
lines(test_dates, forecast_hqic, col = "purple")
legend("topleft", legend = c("Actual", "Forecast AIC", "Forecast BIC", "Forecast HQIC"),
col = c("black", "red", "green", "purple"), lty = c(1, 1, 1, 1))
mape_aic <- MAPE(test, forecast_aic)
mape_bic <- MAPE(test, forecast_bic)
mape_hqic <- MAPE(test, forecast_hqic)
mae_aic <- MAE(test, forecast_aic)
mae_bic <- MAE(test, forecast_bic)
mae_hqic <- MAE(test, forecast_hqic)
rmse_aic <- RMSE(test, forecast_aic)
rmse_bic <- RMSE(test, forecast_bic)
rmse_hqic <- RMSE(test, forecast_hqic)
mse_aic <- MSE(test, forecast_aic)
mse_bic <- MSE(test, forecast_bic)
mse_hqic <- MSE(test, forecast_hqic)
r2_aic <- R2(test, forecast_aic)
r2_bic <- R2(test, forecast_bic)
r2_hqic <- R2(test, forecast_hqic)
metrics_table <- data.frame(
Method = c("AIC", "BIC", "HQIC"),
MAPE = c(mape_aic, mape_bic, mape_hqic),
MAE = c(mae_aic, mae_bic, mae_hqic),
RMSE = c(rmse_aic, rmse_bic, rmse_hqic),
MSE = c(mse_aic, mse_bic, mse_hqic),
R2 = c(r2_aic, r2_bic, r2_hqic)
)
print(metrics_table)
## Method MAPE MAE RMSE MSE R2
## 1 AIC 1.875319 0.6783717 0.8655771 0.7492237 0.7948870
## 2 BIC 1.965542 0.7114285 0.8975364 0.8055715 0.7771502
## 3 HQIC 1.875319 0.6783717 0.8655771 0.7492237 0.7948870
plot(test, forecast_aic, main="AIC", xlab="Observed", ylab="Predicted", col="blue")
abline(0,1)
plot(test, forecast_bic, main="BIC", xlab="Observed", ylab="Predicted", col="blue")
abline(0,1)
plot(test, forecast_hqic, main="HQIC", xlab="Observed", ylab="Predicted", col="blue")
abline(0,1)
residuals_aic <- test - forecast_aic
residuals_bic <- test - forecast_bic
residuals_hqic <- test - forecast_hqic
plot(residuals_aic, main="AIC Residuals", ylab="Residuals", col="blue")
abline(0,0)
plot(residuals_bic, main="BIC Residuals", ylab="Residuals", col="blue")
abline(0,0)
plot(residuals_hqic, main="HQIC Residuals", ylab="Residuals", col="blue")
abline(0,0)
shapiro.test(residuals_aic)
##
## Shapiro-Wilk normality test
##
## data: residuals_aic
## W = 0.96072, p-value = 0.7349
shapiro.test(residuals_bic)
##
## Shapiro-Wilk normality test
##
## data: residuals_bic
## W = 0.96032, p-value = 0.7283
shapiro.test(residuals_hqic)
##
## Shapiro-Wilk normality test
##
## data: residuals_hqic
## W = 0.96072, p-value = 0.7349
nb_data <- nrow(tgls)
nb_day_predicted = c(14, 21, 28)
train_size = nb_data - max(nb_day_predicted)
train <- tgls$TGLS.Close[1:train_size]
test <- tgls$TGLS.Close[(train_size + 1):(train_size + 21)]
test <- test[complete.cases(test)]
test_dates <- index(tgls)[(train_size + 1):(train_size + 21)]
test_dates <- test_dates[complete.cases(test_dates)]
forecast_aic <- c()
forecast_bic <- c()
forecast_hqic <- c()
for (i in 1:21) {
fit_aic <- arima(train, order = best_order_aic)
fit_bic <- arima(train, order = best_order_bic)
fit_hqic <- arima(train, order = best_order_hqic)
forecast_aic <- c(forecast_aic, predict(fit_aic, n.ahead = 1)$pred)
forecast_bic <- c(forecast_bic, predict(fit_bic, n.ahead = 1)$pred)
forecast_hqic <- c(forecast_hqic, predict(fit_hqic, n.ahead = 1)$pred)
train <- c(train, test[i])
}
n_last = 50
last_dates <- tail(index(tgls), n_last)
last_tgls <- tail(tgls$TGLS.Close, n_last)
last_forecast_aic <- tail(forecast_aic, n_last)
last_forecast_bic <- tail(forecast_bic, n_last)
last_forecast_hqic <- tail(forecast_hqic, n_last)
plot(last_dates, last_tgls, type = "l", col = "black", ylim = range(c(last_tgls, last_forecast_aic, last_forecast_bic, last_forecast_hqic)),
main = "TGLS Closing Price", ylab = "Price ($)", xlab = "Date")
lines(test_dates, forecast_aic, col = "red")
lines(test_dates, forecast_bic, col = "green")
lines(test_dates, forecast_hqic, col = "purple")
legend("topleft", legend = c("Actual", "Forecast AIC", "Forecast BIC", "Forecast HQIC"),
col = c("black", "red", "green", "purple"), lty = c(1, 1, 1, 1))
mape_aic <- MAPE(test, forecast_aic)
mape_bic <- MAPE(test, forecast_bic)
mape_hqic <- MAPE(test, forecast_hqic)
mae_aic <- MAE(test, forecast_aic)
mae_bic <- MAE(test, forecast_bic)
mae_hqic <- MAE(test, forecast_hqic)
rmse_aic <- RMSE(test, forecast_aic)
rmse_bic <- RMSE(test, forecast_bic)
rmse_hqic <- RMSE(test, forecast_hqic)
mse_aic <- MSE(test, forecast_aic)
mse_bic <- MSE(test, forecast_bic)
mse_hqic <- MSE(test, forecast_hqic)
r2_aic <- R2(test, forecast_aic)
r2_bic <- R2(test, forecast_bic)
r2_hqic <- R2(test, forecast_hqic)
metrics_table <- data.frame(
Method = c("AIC", "BIC", "HQIC"),
MAPE = c(mape_aic, mape_bic, mape_hqic),
MAE = c(mae_aic, mae_bic, mae_hqic),
RMSE = c(rmse_aic, rmse_bic, rmse_hqic),
MSE = c(mse_aic, mse_bic, mse_hqic),
R2 = c(r2_aic, r2_bic, r2_hqic)
)
print(metrics_table)
## Method MAPE MAE RMSE MSE R2
## 1 AIC 1.947686 0.7535679 1.078031 1.162151 0.9249987
## 2 BIC 2.016224 0.7780951 1.085067 1.177371 0.9254211
## 3 HQIC 1.947686 0.7535679 1.078031 1.162151 0.9249987
plot(test, forecast_aic, main="AIC", xlab="Observed", ylab="Predicted", col="blue")
abline(0,1)
plot(test, forecast_bic, main="BIC", xlab="Observed", ylab="Predicted", col="blue")
abline(0,1)
plot(test, forecast_hqic, main="HQIC", xlab="Observed", ylab="Predicted", col="blue")
abline(0,1)
residuals_aic <- test - forecast_aic
residuals_bic <- test - forecast_bic
residuals_hqic <- test - forecast_hqic
plot(residuals_aic, main="AIC Residuals", ylab="Residuals", col="blue")
abline(0,0)
plot(residuals_bic, main="BIC Residuals", ylab="Residuals", col="blue")
abline(0,0)
plot(residuals_hqic, main="HQIC Residuals", ylab="Residuals", col="blue")
abline(0,0)
shapiro.test(residuals_aic)
##
## Shapiro-Wilk normality test
##
## data: residuals_aic
## W = 0.89981, p-value = 0.0347
shapiro.test(residuals_bic)
##
## Shapiro-Wilk normality test
##
## data: residuals_bic
## W = 0.91446, p-value = 0.06728
shapiro.test(residuals_hqic)
##
## Shapiro-Wilk normality test
##
## data: residuals_hqic
## W = 0.89981, p-value = 0.0347
nb_data <- nrow(tgls)
nb_day_predicted = c(14, 21, 28)
train_size = nb_data - max(nb_day_predicted)
train <- tgls$TGLS.Close[1:train_size]
test <- tgls$TGLS.Close[(train_size + 1):(train_size + 28)]
test <- test[complete.cases(test)]
test_dates <- index(tgls)[(train_size + 1):(train_size + 28)]
test_dates <- test_dates[complete.cases(test_dates)]
forecast_aic <- c()
forecast_bic <- c()
forecast_hqic <- c()
for (i in 1:28) {
fit_aic <- arima(train, order = best_order_aic)
fit_bic <- arima(train, order = best_order_bic)
fit_hqic <- arima(train, order = best_order_hqic)
forecast_aic <- c(forecast_aic, predict(fit_aic, n.ahead = 1)$pred)
forecast_bic <- c(forecast_bic, predict(fit_bic, n.ahead = 1)$pred)
forecast_hqic <- c(forecast_hqic, predict(fit_hqic, n.ahead = 1)$pred)
train <- c(train, test[i])
}
n_last = 50
last_dates <- tail(index(tgls), n_last)
last_tgls <- tail(tgls$TGLS.Close, n_last)
last_forecast_aic <- tail(forecast_aic, n_last)
last_forecast_bic <- tail(forecast_bic, n_last)
last_forecast_hqic <- tail(forecast_hqic, n_last)
plot(last_dates, last_tgls, type = "l", col = "black", ylim = range(c(last_tgls, last_forecast_aic, last_forecast_bic, last_forecast_hqic)),
main = "TGLS Closing Price", ylab = "Price ($)", xlab = "Date")
lines(test_dates, forecast_aic, col = "red")
lines(test_dates, forecast_bic, col = "green")
lines(test_dates, forecast_hqic, col = "purple")
legend("topleft", legend = c("Actual", "Forecast AIC", "Forecast BIC", "Forecast HQIC"),
col = c("black", "red", "green", "purple"), lty = c(1, 1, 1, 1))
mape_aic <- MAPE(test, forecast_aic)
mape_bic <- MAPE(test, forecast_bic)
mape_hqic <- MAPE(test, forecast_hqic)
mae_aic <- MAE(test, forecast_aic)
mae_bic <- MAE(test, forecast_bic)
mae_hqic <- MAE(test, forecast_hqic)
rmse_aic <- RMSE(test, forecast_aic)
rmse_bic <- RMSE(test, forecast_bic)
rmse_hqic <- RMSE(test, forecast_hqic)
mse_aic <- MSE(test, forecast_aic)
mse_bic <- MSE(test, forecast_bic)
mse_hqic <- MSE(test, forecast_hqic)
r2_aic <- R2(test, forecast_aic)
r2_bic <- R2(test, forecast_bic)
r2_hqic <- R2(test, forecast_hqic)
metrics_table <- data.frame(
Method = c("AIC", "BIC", "HQIC"),
MAPE = c(mape_aic, mape_bic, mape_hqic),
MAE = c(mae_aic, mae_bic, mae_hqic),
RMSE = c(rmse_aic, rmse_bic, rmse_hqic),
MSE = c(mse_aic, mse_bic, mse_hqic),
R2 = c(r2_aic, r2_bic, r2_hqic)
)
print(metrics_table)
## Method MAPE MAE RMSE MSE R2
## 1 AIC 1.906612 0.7641704 1.038412 1.078300 0.9495750
## 2 BIC 1.957943 0.7821428 1.057291 1.117864 0.9478544
## 3 HQIC 1.906612 0.7641704 1.038412 1.078300 0.9495750
plot(test, forecast_aic, main="AIC", xlab="Observed", ylab="Predicted", col="blue")
abline(0,1)
plot(test, forecast_bic, main="BIC", xlab="Observed", ylab="Predicted", col="blue")
abline(0,1)
plot(test, forecast_hqic, main="HQIC", xlab="Observed", ylab="Predicted", col="blue")
abline(0,1)
residuals_aic <- test - forecast_aic
residuals_bic <- test - forecast_bic
residuals_hqic <- test - forecast_hqic
plot(residuals_aic, main="AIC Residuals", ylab="Residuals", col="blue")
abline(0,0)
plot(residuals_bic, main="BIC Residuals", ylab="Residuals", col="blue")
abline(0,0)
plot(residuals_hqic, main="HQIC Residuals", ylab="Residuals", col="blue")
abline(0,0)
shapiro.test(residuals_aic)
##
## Shapiro-Wilk normality test
##
## data: residuals_aic
## W = 0.92826, p-value = 0.05574
shapiro.test(residuals_bic)
##
## Shapiro-Wilk normality test
##
## data: residuals_bic
## W = 0.94246, p-value = 0.1276
shapiro.test(residuals_hqic)
##
## Shapiro-Wilk normality test
##
## data: residuals_hqic
## W = 0.92826, p-value = 0.05574
With more values predicted, we obtain better r2 and a low p-value for normality test so we can assume with a good confidence thqt the residuals follow a normal distribution.
nb_data <- nrow(tgls)
nb_day_predicted = c(14, 21, 28)
train_size = nb_data - max(nb_day_predicted)
train <- tgls$TGLS.Close[1:train_size]
test <- tgls$TGLS.Close[(train_size + 1):(train_size + 14)]
test <- test[complete.cases(test)]
test_dates <- index(tgls)[(train_size + 1):(train_size + 14)]
test_dates <- test_dates[complete.cases(test_dates)]
fit_aic <- arima(train, order = best_order_aic)
fit_bic <- arima(train, order = best_order_bic)
fit_hqic <- arima(train, order = best_order_hqic)
forecast_aic <- predict(fit_aic, n.ahead = 14)$pred
forecast_bic <- predict(fit_bic, n.ahead = 14)$pred
forecast_hqic <- predict(fit_hqic, n.ahead = 14)$pred
n_last = 50
last_dates <- tail(index(tgls), n_last)
last_tgls <- tail(tgls$TGLS.Close, n_last)
last_forecast_aic <- tail(forecast_aic, n_last)
last_forecast_bic <- tail(forecast_bic, n_last)
last_forecast_hqic <- tail(forecast_hqic, n_last)
plot(last_dates, last_tgls, type = "l", col = "black", ylim = range(c(last_tgls, last_forecast_aic, last_forecast_bic, last_forecast_hqic)),
main = "TGLS Closing Price", ylab = "Price ($)", xlab = "Date")
lines(test_dates, forecast_aic, col = "red")
lines(test_dates, forecast_bic, col = "green")
lines(test_dates, forecast_hqic, col = "purple")
legend("topleft", legend = c("Actual", "Forecast AIC", "Forecast BIC", "Forecast HQIC"),
col = c("black", "red", "green", "purple"), lty = c(1, 1, 1, 1))
mape_aic <- MAPE(test, forecast_aic)
mape_bic <- MAPE(test, forecast_bic)
mape_hqic <- MAPE(test, forecast_hqic)
mae_aic <- MAE(test, forecast_aic)
mae_bic <- MAE(test, forecast_bic)
mae_hqic <- MAE(test, forecast_hqic)
rmse_aic <- RMSE(test, forecast_aic)
rmse_bic <- RMSE(test, forecast_bic)
rmse_hqic <- RMSE(test, forecast_hqic)
mse_aic <- MSE(test, forecast_aic)
mse_bic <- MSE(test, forecast_bic)
mse_hqic <- MSE(test, forecast_hqic)
r2_aic <- R2(test, forecast_aic)
r2_bic <- R2(test, forecast_bic)
r2_hqic <- R2(test, forecast_hqic)
metrics_table <- data.frame(
Method = c("AIC", "BIC", "HQIC"),
MAPE = c(mape_aic, mape_bic, mape_hqic),
MAE = c(mae_aic, mae_bic, mae_hqic),
RMSE = c(rmse_aic, rmse_bic, rmse_hqic),
MSE = c(mse_aic, mse_bic, mse_hqic),
R2 = c(r2_aic, r2_bic, r2_hqic)
)
print(metrics_table)
## Method MAPE MAE RMSE MSE R2
## 1 AIC 4.377584 1.606444 1.838467 3.379960 0.01850756
## 2 BIC 4.407885 1.615714 1.834709 3.366157 NA
## 3 HQIC 4.377584 1.606444 1.838467 3.379960 0.01850756
plot(test, forecast_aic, main="AIC", xlab="Observed", ylab="Predicted", col="blue")
abline(0,1)
plot(test, forecast_bic, main="BIC", xlab="Observed", ylab="Predicted", col="blue")
abline(0,1)
plot(test, forecast_hqic, main="HQIC", xlab="Observed", ylab="Predicted", col="blue")
abline(0,1)
nb_data <- nrow(tgls)
nb_day_predicted = c(14, 21, 28)
train_size = nb_data - max(nb_day_predicted)
train <- tgls$TGLS.Close[1:train_size]
test <- tgls$TGLS.Close[(train_size + 1):(train_size + 21)]
test <- test[complete.cases(test)]
test_dates <- index(tgls)[(train_size + 1):(train_size + 21)]
test_dates <- test_dates[complete.cases(test_dates)]
fit_aic <- arima(train, order = best_order_aic)
fit_bic <- arima(train, order = best_order_bic)
fit_hqic <- arima(train, order = best_order_hqic)
forecast_aic <- predict(fit_aic, n.ahead = 21)$pred
forecast_bic <- predict(fit_bic, n.ahead = 21)$pred
forecast_hqic <- predict(fit_hqic, n.ahead = 21)$pred
n_last = 50
last_dates <- tail(index(tgls), n_last)
last_tgls <- tail(tgls$TGLS.Close, n_last)
last_forecast_aic <- tail(forecast_aic, n_last)
last_forecast_bic <- tail(forecast_bic, n_last)
last_forecast_hqic <- tail(forecast_hqic, n_last)
plot(last_dates, last_tgls, type = "l", col = "black", ylim = range(c(last_tgls, last_forecast_aic, last_forecast_bic, last_forecast_hqic)),
main = "TGLS Closing Price", ylab = "Price ($)", xlab = "Date")
lines(test_dates, forecast_aic, col = "red")
lines(test_dates, forecast_bic, col = "green")
lines(test_dates, forecast_hqic, col = "purple")
legend("topleft", legend = c("Actual", "Forecast AIC", "Forecast BIC", "Forecast HQIC"),
col = c("black", "red", "green", "purple"), lty = c(1, 1, 1, 1))
mape_aic <- MAPE(test, forecast_aic)
mape_bic <- MAPE(test, forecast_bic)
mape_hqic <- MAPE(test, forecast_hqic)
mae_aic <- MAE(test, forecast_aic)
mae_bic <- MAE(test, forecast_bic)
mae_hqic <- MAE(test, forecast_hqic)
rmse_aic <- RMSE(test, forecast_aic)
rmse_bic <- RMSE(test, forecast_bic)
rmse_hqic <- RMSE(test, forecast_hqic)
mse_aic <- MSE(test, forecast_aic)
mse_bic <- MSE(test, forecast_bic)
mse_hqic <- MSE(test, forecast_hqic)
r2_aic <- R2(test, forecast_aic)
r2_bic <- R2(test, forecast_bic)
r2_hqic <- R2(test, forecast_hqic)
metrics_table <- data.frame(
Method = c("AIC", "BIC", "HQIC"),
MAPE = c(mape_aic, mape_bic, mape_hqic),
MAE = c(mae_aic, mae_bic, mae_hqic),
RMSE = c(rmse_aic, rmse_bic, rmse_hqic),
MSE = c(mse_aic, mse_bic, mse_hqic),
R2 = c(r2_aic, r2_bic, r2_hqic)
)
print(metrics_table)
## Method MAPE MAE RMSE MSE R2
## 1 AIC 8.098980 3.297485 4.333084 18.77562 0.008232079
## 2 BIC 8.091165 3.291905 4.314561 18.61544 NA
## 3 HQIC 8.098980 3.297485 4.333084 18.77562 0.008232079
plot(test, forecast_aic, main="AIC", xlab="Observed", ylab="Predicted", col="blue")
abline(0,1)
plot(test, forecast_bic, main="BIC", xlab="Observed", ylab="Predicted", col="blue")
abline(0,1)
plot(test, forecast_hqic, main="HQIC", xlab="Observed", ylab="Predicted", col="blue")
abline(0,1)
nb_data <- nrow(tgls)
nb_day_predicted = c(14, 21, 28)
train_size = nb_data - max(nb_day_predicted)
train <- tgls$TGLS.Close[1:train_size]
test <- tgls$TGLS.Close[(train_size + 1):(train_size + 28)]
test <- test[complete.cases(test)]
test_dates <- index(tgls)[(train_size + 1):(train_size + 28)]
test_dates <- test_dates[complete.cases(test_dates)]
fit_aic <- arima(train, order = best_order_aic)
fit_bic <- arima(train, order = best_order_bic)
fit_hqic <- arima(train, order = best_order_hqic)
forecast_aic <- predict(fit_aic, n.ahead = 28)$pred
forecast_bic <- predict(fit_bic, n.ahead = 28)$pred
forecast_hqic <- predict(fit_hqic, n.ahead = 28)$pred
n_last = 50
last_dates <- tail(index(tgls), n_last)
last_tgls <- tail(tgls$TGLS.Close, n_last)
last_forecast_aic <- tail(forecast_aic, n_last)
last_forecast_bic <- tail(forecast_bic, n_last)
last_forecast_hqic <- tail(forecast_hqic, n_last)
plot(last_dates, last_tgls, type = "l", col = "black", ylim = range(c(last_tgls, last_forecast_aic, last_forecast_bic, last_forecast_hqic)),
main = "TGLS Closing Price", ylab = "Price ($)", xlab = "Date")
lines(test_dates, forecast_aic, col = "red")
lines(test_dates, forecast_bic, col = "green")
lines(test_dates, forecast_hqic, col = "purple")
legend("topleft", legend = c("Actual", "Forecast AIC", "Forecast BIC", "Forecast HQIC"),
col = c("black", "red", "green", "purple"), lty = c(1, 1, 1, 1))
mape_aic <- MAPE(test, forecast_aic)
mape_bic <- MAPE(test, forecast_bic)
mape_hqic <- MAPE(test, forecast_hqic)
mae_aic <- MAE(test, forecast_aic)
mae_bic <- MAE(test, forecast_bic)
mae_hqic <- MAE(test, forecast_hqic)
rmse_aic <- RMSE(test, forecast_aic)
rmse_bic <- RMSE(test, forecast_bic)
rmse_hqic <- RMSE(test, forecast_hqic)
mse_aic <- MSE(test, forecast_aic)
mse_bic <- MSE(test, forecast_bic)
mse_hqic <- MSE(test, forecast_hqic)
r2_aic <- R2(test, forecast_aic)
r2_bic <- R2(test, forecast_bic)
r2_hqic <- R2(test, forecast_hqic)
metrics_table <- data.frame(
Method = c("AIC", "BIC", "HQIC"),
MAPE = c(mape_aic, mape_bic, mape_hqic),
MAE = c(mae_aic, mae_bic, mae_hqic),
RMSE = c(rmse_aic, rmse_bic, rmse_hqic),
MSE = c(mse_aic, mse_bic, mse_hqic),
R2 = c(r2_aic, r2_bic, r2_hqic)
)
print(metrics_table)
## Method MAPE MAE RMSE MSE R2
## 1 AIC 11.30916 4.840822 6.067108 36.80981 0.004342446
## 2 BIC 11.28383 4.827857 6.043484 36.52369 NA
## 3 HQIC 11.30916 4.840822 6.067108 36.80981 0.004342446
plot(test, forecast_aic, main="AIC", xlab="Observed", ylab="Predicted", col="blue")
abline(0,1)
plot(test, forecast_bic, main="BIC", xlab="Observed", ylab="Predicted", col="blue")
abline(0,1)
plot(test, forecast_hqic, main="HQIC", xlab="Observed", ylab="Predicted", col="blue")
abline(0,1)
Without rolling forecast, the model doesn’t manage to predict the price as we can see with the graphics. Consequently we won’t do the analysis of the residuals.