master <- read_csv("master.csv", col_types = cols(sex = col_factor(levels = c("male",
"female")), `country-year` = col_skip()))Actividades prácticas en R
Actividad #3
Análisis de los datos
Veamos cuales son las variables presentes en el DataFrame master.
names(master) [1] "country" "year" "sex"
[4] "age" "suicides_no" "population"
[7] "suicides/100k pop" "HDI for year" "gdp_for_year ($)"
[10] "gdp_per_capita ($)" "generation"
Antes de analizar cada una de las variables por separado, renombremos algunas variables que tienen nombres algo extraños.
colnames(master)[5] <- "suicidesno"
colnames(master)[8] <- "IDH"
colnames(master)[9] <- "PIB"
colnames(master)[10] <- "PIB_PC"
colnames(master)[6] <- "population"
colnames(master)[7] <- "suicides100k"
names(master) [1] "country" "year" "sex" "age" "suicidesno"
[6] "population" "suicides100k" "IDH" "PIB" "PIB_PC"
[11] "generation"
knitr:: kable(head(master),"html", caption = "DataFrame Master") %>%
row_spec(0, bold = TRUE, color = "black", background = "#C1CDCD", extra_css = "text-align: center") %>%
column_spec(1, bold = TRUE) %>%
column_spec(2:5, width = "10em", extra_css = "padding-left: 15px; padding-right: 10px;")| country | year | sex | age | suicidesno | population | suicides100k | IDH | PIB | PIB_PC | generation |
|---|---|---|---|---|---|---|---|---|---|---|
| Albania | 1987 | male | 15-24 years | 21 | 312900 | 6.71 | NA | 2156624900 | 796 | Generation X |
| Albania | 1987 | male | 35-54 years | 16 | 308000 | 5.19 | NA | 2156624900 | 796 | Silent |
| Albania | 1987 | female | 15-24 years | 14 | 289700 | 4.83 | NA | 2156624900 | 796 | Generation X |
| Albania | 1987 | male | 75+ years | 1 | 21800 | 4.59 | NA | 2156624900 | 796 | G.I. Generation |
| Albania | 1987 | male | 25-34 years | 9 | 274300 | 3.28 | NA | 2156624900 | 796 | Boomers |
| Albania | 1987 | female | 75+ years | 1 | 35600 | 2.81 | NA | 2156624900 | 796 | G.I. Generation |
Ahora si pasemos a analizar cada una de las variables de DataFrame.
Country
summary(master$country) Length Class Mode
27820 character character
length(unique(master$country))[1] 101
Vemos que tenemos registros de un total de 101 paises. Indaguemos que pasa con la variable Year
Year
unique(master$year) [1] 1987 1988 1989 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003
[16] 2004 2005 2006 2007 2008 2009 2010 1985 1986 1990 1991 2012 2013 2014 2015
[31] 2011 2016
length(unique(master$year))[1] 32
Por parte de esta variable contamos con un total de 32 años de registros, empezando desde 1987 hasta 2016.
Sex
summary(master$sex) male female
13910 13910
Se evidencia que tenemos la misma cantidad de observaciones tanto de hombres como de mujeres.
Número de suicidios
Como primera variable cuantitativa tenemos es número de suicidios, veremos a continuación que los datos tienen una media de 242.6 (902.04) con una dispersión bastante grande, lo que nos lleva a pensar en la presencia de datos atípicos.
kable(descr(master$suicidesno))| suicidesno | |
|---|---|
| Mean | 242.574407 |
| Std.Dev | 902.047917 |
| Min | 0.000000 |
| Q1 | 3.000000 |
| Median | 25.000000 |
| Q3 | 131.000000 |
| Max | 22338.000000 |
| MAD | 37.065000 |
| IQR | 128.000000 |
| CV | 3.718644 |
| Skewness | 10.351794 |
| SE.Skewness | 0.014685 |
| Kurtosis | 157.128868 |
| N.Valid | 27820.000000 |
| Pct.Valid | 100.000000 |
ggp1 <- ggplot(master,aes(x=master$suicidesno)) +
geom_histogram(bins = 30 ,fill="#548B54") +
xlab("Suicidios por año") +
ylab("")
ggp2 <- ggplot(master, aes(x=master$suicidesno)) +
geom_boxplot(fill="#43B047") +
ggtitle("Numero de suicidios ") +
xlab("Número de suicidios") + ylab("")
grid.arrange(ggp1, ggp2, ncol = 2)
Como era de esperarse, hay una gran cantidad de datos atípicos, detectemos cuantos hay utilizando las puntuaciones de Z. Veamos cuantos datos atipicos existen en la variable Suicidios por año, usando la función detect_outliers_zscore.
detect_outliers_zscore <- function(data) {
thres <- 3
mean_value <- mean(data, na.rm = TRUE)
std_value <- sd(data, na.rm = TRUE)
z_scores <- (data - mean_value) / std_value
outliers <- data[abs(z_scores) > thres]
return(outliers)
}val_atipicos<- detect_outliers_zscore(master$suicidesno)
cat("Los valores atípicos de la variable [Números de suicidios] fueron en total:", length(val_atipicos), "\n")Los valores atípicos de la variable [Números de suicidios] fueron en total: 409
PIB y PIB percapital
knitr::kable(descr(master$PIB))| PIB | |
|---|---|
| Mean | 4.455810e+11 |
| Std.Dev | 1.453610e+12 |
| Min | 4.691962e+07 |
| Q1 | 8.985353e+09 |
| Median | 4.811469e+10 |
| Q3 | 2.602024e+11 |
| Max | 1.812071e+13 |
| MAD | 6.929537e+10 |
| IQR | 2.512171e+11 |
| CV | 3.262280e+00 |
| Skewness | 7.232975e+00 |
| SE.Skewness | 1.468500e-02 |
| Kurtosis | 6.421703e+01 |
| N.Valid | 2.782000e+04 |
| Pct.Valid | 1.000000e+02 |
knitr::kable(descr(master$PIB_PC))| PIB_PC | |
|---|---|
| Mean | 1.686646e+04 |
| Std.Dev | 1.888758e+04 |
| Min | 2.510000e+02 |
| Q1 | 3.447000e+03 |
| Median | 9.372000e+03 |
| Q3 | 2.487400e+04 |
| Max | 1.263520e+05 |
| MAD | 1.087339e+04 |
| IQR | 2.142700e+04 |
| CV | 1.119830e+00 |
| Skewness | 1.963258e+00 |
| SE.Skewness | 1.468500e-02 |
| Kurtosis | 4.936084e+00 |
| N.Valid | 2.782000e+04 |
| Pct.Valid | 1.000000e+02 |
gg1 <- ggplot(master,aes(x=PIB))+ geom_boxplot(fill="#548B54")
gg2 <- ggplot(master,aes(x=PIB_PC))+ geom_boxplot(fill="#548B54")
grid.arrange(gg1, gg2, ncol = 2)
Podemos evidenciar que estas dos variables tienen una gran presecia de datos atípicos, por lo cual la dispersión es bastante grande, aunque vemos que la desviación típica en el PIV_PC es menor.
Veamos cuantos valores atípicos estan presentes en estas variables:
val_atipicosPIB<- detect_outliers_zscore(master$PIB)
val_atipicosPIB_PC<- detect_outliers_zscore(master$PIB_PC)
cat("Los valores atípicos de la variable [PIB] fueron en total:", length(val_atipicosPIB), "\n")Los valores atípicos de la variable [PIB] fueron en total: 492
cat("Los valores atípicos de la variable [PIB_PC] fueron en total:", length(val_atipicosPIB_PC), "\n")Los valores atípicos de la variable [PIB_PC] fueron en total: 492
IDH
summary(master$IDH) Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
0.483 0.713 0.779 0.777 0.855 0.944 19456
Vemos que esta es la variable que presenta datos faltantes (19456), veamos su proporción.
aggr(master, numbers = TRUE, col = c("#548B54", "#43CD80"),
cex.axis = 0.7, gap = 3, ylab = c("Proportion of missingness", "Missingness pattern"))
Con el gráfico anterior no solo vemos que la proporción de los datos faltantes del IDH si no que tambien confirmamos que es la única variable que cuenta con datos faltantes. Veamos la distribución que sigue la variable.
ggplot(master,aes(x=IDH))+ geom_histogram(fill="#548B54")`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
Warning: Removed 19456 rows containing non-finite outside the scale range
(`stat_bin()`).

Para este caso usaremos la técnica te imputación mas simple que es reemplazar los datos faltantes por la mediana, esto es:
mediana_IDH <- median(master$IDH, na.rm = TRUE)
master$IDH[is.na(master$IDH)] <- mediana_IDHsummary(master$IDH) Min. 1st Qu. Median Mean 3rd Qu. Max.
0.4830 0.7790 0.7790 0.7783 0.7790 0.9440
Filtrando el DataFrame
Supongamos que nos interesa estudiar los suicidios que fueron registrados en los 101 paises en el año 2010.
info_2010<-master %>% filter(year =="2010")
knitr:: kable(head(info_2010),"html", caption = "DataFrame Master filtrado para el año 2010") %>%
row_spec(0, bold = TRUE, color = "black", background = "#C1CDCD", extra_css = "text-align: center") %>%
column_spec(1, bold = TRUE) %>%
column_spec(2:5, width = "10em", extra_css = "padding-left: 15px; padding-right: 10px;")| country | year | sex | age | suicidesno | population | suicides100k | IDH | PIB | PIB_PC | generation |
|---|---|---|---|---|---|---|---|---|---|---|
| Albania | 2010 | male | 55-74 years | 20 | 241852 | 8.27 | 0.722 | 11926953259 | 4359 | Silent |
| Albania | 2010 | male | 35-54 years | 20 | 371611 | 5.38 | 0.722 | 11926953259 | 4359 | Generation X |
| Albania | 2010 | male | 25-34 years | 9 | 179720 | 5.01 | 0.722 | 11926953259 | 4359 | Generation X |
| Albania | 2010 | male | 75+ years | 2 | 50767 | 3.94 | 0.722 | 11926953259 | 4359 | Silent |
| Albania | 2010 | male | 15-24 years | 10 | 279508 | 3.58 | 0.722 | 11926953259 | 4359 | Millenials |
| Albania | 2010 | female | 25-34 years | 6 | 183579 | 3.27 | 0.722 | 11926953259 | 4359 | Generation X |
dim(info_2010)[1] 1056 11
Veamos como se comportan las variables en este nuevo DataFrame filtrado por el año 2010.
gg1_10 <- ggplot(info_2010,aes(x=PIB))+ geom_boxplot(fill="#548B54")
gg2_10 <- ggplot(info_2010,aes(x=PIB_PC))+ geom_boxplot(fill="#548B54")
grid.arrange(gg1_10, gg2_10, ncol = 2)
Vemos que en este nuevo DataFrame las variables que anteriormente tenian una gran cantidad de datos atípicos presentan una proporción mas bajas de los mismos. Vemos mas de cerca la distribución de la variable PIB
ggplot(info_2010,aes(x=info_2010$PIB)) +
geom_histogram(bins = 10 ,fill="#548B54") +
xlab("Suicidios por año") +
ylab("") 
summary(info_2010$sex) male female
528 528
Existe la misma proporción de hombres y mujeres.
Veamos que cambios ha sufrido los suicidios reportados en el año 2010.
ggp1 <- ggplot(info_2010,aes(x=info_2010$suicidesno)) +
geom_histogram(bins = 10 ,fill="#548B54") +
xlab("Suicidios por año") +
ylab("")
ggp2 <- ggplot(info_2010, aes(x=info_2010$`suicides100k`)) +
geom_boxplot(fill="#43B047") +
xlab("suicides/100k") + ylab("")
grid.arrange(ggp1, ggp2, ncol = 2)
Analisemos la variable IDH.
summary(info_2010$IDH) Min. 1st Qu. Median Mean 3rd Qu. Max.
0.6110 0.7342 0.7855 0.7932 0.8708 0.9400
ggplot(info_2010, aes(x=info_2010$IDH)) +
geom_boxplot(fill="#43B047") +
xlab("IDH") + ylab("") 
Análisis complementarios:
Veamos cuales son los siete países que cuentan con mayores registros de suicidios en el 2010.
total_suicides <- info_2010 %>%
group_by(country) %>%
summarise(total_suicides = sum(suicidesno)) %>%
arrange(desc(total_suicides)) %>%
slice_head(n = 7)
ggplot(data = total_suicides, aes(x = reorder(country, -total_suicides), y = total_suicides, fill = info_2010$sex)) +
geom_bar(stat = "identity", fill = "#43CD80") +
labs(title = "Top 7 países con mayores registros de suicidios en 2010", x = "País", y = "Total de suicidios") +
theme(axis.text.x = element_text(angle = 90, hjust = 1))
En la siguiente gráfica se muestra los registros de los países con mayores suicidios en 2010 agrupados por el sexo.
top_countries <- info_2010 %>%
group_by(country) %>%
summarise(total_suicides = sum(suicidesno), .groups = 'drop') %>%
arrange(desc(total_suicides)) %>%
slice_head(n = 7) %>%
pull(country)
total_suicides <- info_2010 %>%
filter(country %in% top_countries) %>%
group_by(country, sex) %>%
summarise(total_suicides = sum(suicidesno), .groups = 'drop') %>%
arrange(desc(total_suicides))
ggplot(data = total_suicides, aes(x = reorder(country, -total_suicides), y = total_suicides, fill = sex)) +
geom_bar(stat = "identity", position = "dodge") +
scale_fill_manual(values = c("#2E8B57", "#66CDAA")) +
labs(title = "Top 7 países con mayores registros de suicidios en 2010", x = "País", y = "Total de suicidios") +
theme(axis.text.x = element_text(angle = 90, hjust = 1))
Veamos la cantidad de suicidios registrados por cada generación agrupados por el sexo.
suicides_generation <- info_2010 %>%
group_by(generation,sex) %>%
summarise(total_s = sum(suicidesno), .groups = 'drop')
ggplot(data = suicides_generation, aes(x = generation, y = total_s, fill=sex)) +
geom_bar(stat = "identity", ) +
scale_fill_manual(values = c("#2E8B57", "#66CDAA"))+
labs(title = "Proporción de suicidios registrados por cada generación", x = "Generación", y = "Número de suicidios")
kable(suicides_generation)| generation | sex | total_s |
|---|---|---|
| Generation X | male | 99850 |
| Generation X | female | 25831 |
| Generation Z | male | 1085 |
| Generation Z | female | 675 |
| Millenials | male | 21520 |
| Millenials | female | 6164 |
| Silent | male | 62025 |
| Silent | female | 21552 |
Actividad #4
Considere la base de datos master y realice lo siguiente (utilice los operadores pipe de continuidad y compuesto):
Filtro de los datos de Colombia y EEUU:
Genere dos bases de datos, llamadas master_col y master_eu.
master_col <- master %>% filter(master$country == "Colombia")
knitr:: kable(head(master_col))| country | year | sex | age | suicidesno | population | suicides100k | IDH | PIB | PIB_PC | generation |
|---|---|---|---|---|---|---|---|---|---|---|
| Colombia | 1985 | male | 75+ years | 21 | 123400 | 17.02 | 0.573 | 34894411352 | 1393 | G.I. Generation |
| Colombia | 1985 | male | 55-74 years | 113 | 1015200 | 11.13 | 0.573 | 34894411352 | 1393 | G.I. Generation |
| Colombia | 1985 | male | 25-34 years | 193 | 2323700 | 8.31 | 0.573 | 34894411352 | 1393 | Boomers |
| Colombia | 1985 | male | 15-24 years | 256 | 3190200 | 8.02 | 0.573 | 34894411352 | 1393 | Generation X |
| Colombia | 1985 | male | 35-54 years | 188 | 2451100 | 7.67 | 0.573 | 34894411352 | 1393 | Silent |
| Colombia | 1985 | female | 15-24 years | 117 | 3140700 | 3.73 | 0.573 | 34894411352 | 1393 | Generation X |
master_eu <- master %>% filter(master$country == "United States")
knitr:: kable(head(master_eu))| country | year | sex | age | suicidesno | population | suicides100k | IDH | PIB | PIB_PC | generation |
|---|---|---|---|---|---|---|---|---|---|---|
| United States | 1985 | male | 75+ years | 2177 | 4064000 | 53.57 | 0.841 | 4.346734e+12 | 19693 | G.I. Generation |
| United States | 1985 | male | 55-74 years | 5302 | 17971000 | 29.50 | 0.841 | 4.346734e+12 | 19693 | G.I. Generation |
| United States | 1985 | male | 25-34 years | 5134 | 20986000 | 24.46 | 0.841 | 4.346734e+12 | 19693 | Boomers |
| United States | 1985 | male | 35-54 years | 6053 | 26589000 | 22.77 | 0.841 | 4.346734e+12 | 19693 | Silent |
| United States | 1985 | male | 15-24 years | 4267 | 19962000 | 21.38 | 0.841 | 4.346734e+12 | 19693 | Generation X |
| United States | 1985 | female | 35-54 years | 2105 | 27763000 | 7.58 | 0.841 | 4.346734e+12 | 19693 | Silent |
Análisis de la evolución de los suicidios por cada 100.000 habitantes, del PIB per cápita y del IDH a lo largo de los años.
suicides_100k_col <- master_col %>%
group_by(year) %>%
summarise(total100k = mean(`suicides100k`), .groups = 'drop')
suicides_100k_eu <- master_eu %>%
group_by(year) %>%
summarise(total100k = mean(`suicides100k`), .groups = 'drop')
g1<-ggplot(suicides_100k_col, aes(x=year, y =total100k)) +
geom_line(stat = "identity", color="#4A708B",linewidth = 1.2)+
labs(title = "Evolucion de suicidios/100K en Colombia", x = "Años", y = "Suicidios/100k")
g2<- ggplot(suicides_100k_eu, aes(x=year, y =total100k)) +
geom_line(stat = "identity", color="#4A708B",linewidth = 1.2)+
labs(title = "Evolucion de suicidios/100K en Estados Unidos", x = "Años", y = "Suicidios/100k")
grid.arrange(g1, g2, ncol = 2)
PIB_col <- master_col %>%
group_by(year) %>%
summarise(pib = mean(PIB_PC, na.rm = TRUE), .groups = 'drop')
ggplot(PIB_col, aes(x=year, y =pib)) +
geom_line(color = "#4A708B", linewidth = 1.2, linetype = "solid") +
geom_point(color = "#4A708B", size = 3) +
labs(title = "Evolucion del PIB per capital a traves de los años en Colombia", x = "Años", y = "PIB per capital")
PIB_eu <- master_eu %>%
group_by(year) %>%
summarise(pib = mean(PIB_PC, na.rm = TRUE), .groups = 'drop')
ggplot(PIB_eu, aes(x=year, y =pib)) +
geom_line(color = "#4A708B", linewidth = 1.2, linetype = "solid") +
geom_point(color = "#4A708B", size = 3) +
labs(title = "Evolucion del PIB per capital a traves de los años en Estados Unidos", x = "Años", y = "PIB per capital")
idh_col <- master_col %>%
group_by(year) %>%
summarise(idh = mean(IDH), .groups = 'drop')
idh_eu <- master_eu %>%
group_by(year) %>%
summarise(idh = mean(IDH), .groups = 'drop')
g1<-ggplot(idh_col, aes(x=year, y =idh)) +
geom_line(stat = "identity", color="#4A708B",size = 1.2)+
labs(title = "Evolucion de suicidios/100K en Colombia", x = "Años", y = "Suicidios/100k")Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
ℹ Please use `linewidth` instead.
g2<- ggplot(idh_eu, aes(x=year, y =idh)) +
geom_line(stat = "identity", color="#4A708B",size = 1.2)+
labs(title = "Evolucion de suicidios/100K en Estados Unidos", x = "Años", y = "Suicidios/100k")
grid.arrange(g1, g2, ncol = 2)
Análisis de la evolución de los suicidios por cada 100.000 habitantes, del PIB per cápita y del IDH por género.
suicides_100k_col <- master_col %>%
group_by(year,sex) %>%
summarise(total100k = mean(`suicides100k`), .groups = 'drop')
ggplot(suicides_100k_col, aes(x=year, y =total100k, color=sex)) +
geom_line(stat = "identity")+
geom_line(linewidth = 1)+
scale_color_manual(values = c("#4A708B", "#CD2990"))+
labs(title = "Evolucion de suicidios/100K a traves de los años en Colombia por Sexo", x = "Años", y = "Suicidios/100k")
suicides_100k_eu <- master_eu %>%
group_by(year,sex) %>%
summarise(total100k = mean(`suicides100k`), .groups = 'drop')
ggplot(suicides_100k_eu, aes(x=year, y =total100k, color=sex)) +
geom_line(stat = "identity")+
geom_line(linewidth = 1)+
scale_color_manual(values = c("#4A708B", "#CD2990"))+
labs(title = "Evolucion de suicidios/100K a traves de los años en Estados Unidos por Sexo", x = "Años", y = "Suicidios/100k")
PIB_col <- master_col %>%
group_by(year, sex) %>%
summarise(pib = mean(PIB_PC, na.rm = TRUE), .groups = 'drop')
ggplot(PIB_col, aes(x = year, y = pib, color = sex, linetype = sex)) +
geom_line(linewidth = 1) + # Usar linewidth para el grosor de la línea
geom_point(size = 3) +
labs(title = "Evolución del PIB per cápita a través de los años en Colombia por sexo",
x = "Años", y = "PIB per cápita") +
scale_color_manual(values = c("#CD2990", "#27408B"))
PIB_eu <- master_eu %>%
group_by(year, sex) %>%
summarise(pib = mean(PIB_PC, na.rm = TRUE), .groups = 'drop')
ggplot(PIB_eu, aes(x = year, y = pib, color = sex, linetype = sex)) +
geom_line(linewidth = 1) + # Usar linewidth para el grosor de la línea
geom_point(size = 3) +
labs(title = "Evolución del PIB per cápita a través de los años en Estados Unidos por sexo",
x = "Años", y = "PIB per cápita") +
scale_color_manual(values = c("#CD2990", "#27408B"))
idh_col <- master_col %>%
group_by(year,sex) %>%
summarise(idh = mean(IDH), .groups = 'drop')
idh_eu <- master_eu %>%
group_by(year,sex) %>%
summarise(idh = mean(IDH), .groups = 'drop')
g1<-ggplot(idh_col, aes(x=year, y =idh,color=sex)) +
geom_line(stat = "identity",size = 1.2)+
labs(title = "Evolucion de IDH en Colombia por sexo", x = "Años", y = "IDH")+
scale_color_manual(values = c("#CD2990", "#27408B"))
g2<- ggplot(idh_eu, aes(x=year, y =idh,color=sex)) +
geom_line(stat = "identity",size = 1.2)+
labs(title = "Evolucion deIDH en Estados Unidos por sexo", x = "Años", y = "IDH")+
scale_color_manual(values = c("#CD2990", "#27408B"))
grid.arrange(g1, g2, ncol = 2)
Análisis de la evolución de los suicidios por cada 100.000 habitantes, del PIB per cápita y del IDH por grupo de edad.
suicides_100k_col <- master_col %>%
group_by(year,age) %>%
summarise(total100k = mean(`suicides100k`), .groups = 'drop')
ggplot(suicides_100k_col, aes(x = year, y = total100k, color = age, group = age)) +
geom_line(linewidth = 1) +
scale_color_manual(values = c("#4A708B", "#6A5ACD", "#5CACEE", "#CD2990", "#4169E1", "#27408B")) + # Colores para las líneas
labs(title = "Evolución de suicidios/100k a través de los años en Colombia edad", x = "Años", y = "Suicidios/100k") 
suicides_100k_eu <- master_eu %>%
group_by(year,age) %>%
summarise(total100k = mean(`suicides100k`), .groups = 'drop')
ggplot(suicides_100k_eu, aes(x = year, y = total100k, color = age, group = age)) +
geom_line(size = 1) +
scale_color_manual(values = c("#4A708B", "#6A5ACD", "#5CACEE", "#CD2990", "#4169E1", "#27408B")) +
labs(title = "Evolución de suicidios/100k a través de los años en Estados unidos por edad",
x = "Años", y = "Suicidios/100k")
PIB_col <- master_col %>%
group_by(year, age) %>%
summarise(pib = mean(PIB_PC, na.rm = TRUE), .groups = 'drop')
ggplot(PIB_col, aes(x = year, y = pib, color = age, linetype = age)) +
geom_line(linewidth = 1.2) +
geom_point(size = 3) +
labs(title = "Evolución del PIB per cápita a través de los años en Colombia por edad",
x = "Años", y = "PIB per cápita") +
scale_color_manual(values = c("#4A708B", "#6A5ACD", "#5CACEE", "#CD2990", "#4169E1", "#27408B"))
PIB_eu <- master_eu %>%
group_by(year, age) %>%
summarise(pib = mean(PIB_PC, na.rm = TRUE), .groups = 'drop')
ggplot(PIB_eu, aes(x = year, y = pib, color = age, linetype = age)) +
geom_line(linewidth = 1.2) + # Usar linewidth para el grosor de la línea
geom_point(size = 3) +
labs(title = "Evolución del PIB per cápita a través de los años en Colombia, por edad",
x = "Años", y = "PIB per cápita") +
scale_color_manual(values = c("#4A708B", "#6A5ACD", "#5CACEE", "#CD2990", "#4169E1", "#27408B"))
idh_col <- master_col %>%
group_by(year,age) %>%
summarise(idh = mean(IDH), .groups = 'drop')
idh_eu <- master_eu %>%
group_by(year,age) %>%
summarise(idh = mean(IDH), .groups = 'drop')
g1<-ggplot(idh_col, aes(x=year, y =idh,color=age)) +
geom_line(stat = "identity",size = 1.2)+
geom_point(size = 3)+
labs(title = "Evolucion de IDH en Colombia por edad", x = "Años", y = "IDH")+
scale_color_manual(values = c("#4A708B", "#6A5ACD", "#5CACEE", "#CD2990", "#4169E1", "#27408B"))
g2<- ggplot(idh_eu, aes(x=year, y =idh,color=age)) +
geom_line(stat = "identity",size = 1.2)+
geom_point(size = 3)+
labs(title = "Evolucion de IDH en Estados Unidos por edad", x = "Años", y = "IDH")+
scale_color_manual(values = c("#4A708B", "#6A5ACD", "#5CACEE", "#CD2990", "#4169E1", "#27408B"))
grid.arrange(g1, g2, ncol = 2)
Actividad #5
Parte 1
accidentes_bq <- read_csv("Accidentalidad_en_Barranquilla_20240830.csv", show_col_types = FALSE)Iniciemos analizando la estructura de el DataFrame accidentes_bq
dim(accidentes_bq)[1] 25610 11
glimpse(accidentes_bq)Rows: 25,610
Columns: 11
$ FECHA_ACCIDENTE <dttm> 2018-01-01, 2018-01-01, 2018-01-01…
$ HORA_ACCIDENTE <chr> "01:30:00:am", "02:00:00:pm", "04:0…
$ GRAVEDAD_ACCIDENTE <chr> "Con heridos", "Solo daños", "Solo …
$ CLASE_ACCIDENTE <chr> "Atropello", "Choque", "Choque", "C…
$ SITIO_EXACTO_ACCIDENTE <chr> "CL 87 9H 24", "CL 110 CR 46", "AV …
$ `CANT_HERIDOS_EN _SITIO_ACCIDENTE` <dbl> 1, NA, NA, NA, NA, 3, 1, NA, NA, NA…
$ `CANT_MUERTOS_EN _SITIO_ACCIDENTE` <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ CANTIDAD_ACCIDENTES <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,…
$ AÑO_ACCIDENTE <dbl> 2018, 2018, 2018, 2018, 2018, 2018,…
$ MES_ACCIDENTE <chr> "January", "January", "January", "J…
$ DIA_ACCIDENTE <chr> "Mon", "Mon", "Mon", "Mon", "Mon", …
Veamos cada una de las variables para asegurarnos que no haya un tipo de problema en los datos.
Fechas de registros:
cat("fecha mínima en los registros: \n")fecha mínima en los registros:
print(min(accidentes_bq$FECHA_ACCIDENTE))[1] "2018-01-01 UTC"
cat("fecha máxima en los registros: \n")fecha máxima en los registros:
print(max(accidentes_bq$FECHA_ACCIDENTE))[1] "2024-06-30 UTC"
Nuestro data frame accidentes_bq cuenta con registros desde enero del 2018 hasta junio de 2024. Haremos los análisis pertinentes solo hasta el 2023, puesto que solo tenemos informacion preeliminar del 2024.
accidentes_bq <- accidentes_bq %>%
filter(AÑO_ACCIDENTE != 2024)Gravedad del accidente y clase de accidente:
Veamos la proporción de cada tipo de accidente y su gravedad que fueron registrados en el df.
accidentes_bq$GRAVEDAD_ACCIDENTE<- as.factor(accidentes_bq$GRAVEDAD_ACCIDENTE)
summary(accidentes_bq$GRAVEDAD_ACCIDENTE) Con heridos Con muertos Solo daños
9179 235 15455
accidentes_bq$CLASE_ACCIDENTE<- as.factor(accidentes_bq$CLASE_ACCIDENTE)
summary(accidentes_bq$CLASE_ACCIDENTE) Atropello Caida Ocupante Choque Incendio Otro
1236 181 23214 13 120
Volcamiento
105
ggplot(accidentes_bq, aes(x=GRAVEDAD_ACCIDENTE))+
geom_bar(fill="#7AC5CD")+
labs(x = "Gravedad de Accidente", y = "Frecuencia") +
theme_minimal()
count_acc <- accidentes_bq %>%
count(CLASE_ACCIDENTE) %>%
arrange(desc(n)) # Ordenar de mayor a menor
# Crear el diagrama de barras descendentes
ggplot(count_acc, aes(x = reorder(CLASE_ACCIDENTE, -n), y = n)) +
geom_bar(stat = "identity", fill = "#7AC5CD") +
coord_flip() +
labs(x = "Clase de Accidente", y = "Frecuencia") +
theme_minimal()
Cantidad de accidentes por año:
accidentes_bq$AÑO_ACCIDENTE <- as.factor(accidentes_bq$AÑO_ACCIDENTE)
acc_años<- accidentes_bq %>%
group_by(AÑO_ACCIDENTE)%>%
summarise(total_acc =sum(CANTIDAD_ACCIDENTES))
ggplot(acc_años, aes(reorder(AÑO_ACCIDENTE, -total_acc), y = total_acc)) +
geom_bar(stat = "identity", fill = "#7AC5CD") +
labs(x = "Año de Accidente", y = "Total de Accidentes", title = "Total de Accidentes por Año") +
theme_minimal()
El gráfico anterior es muy sutil, ya que nos muestra que al parecer la cantidad de accidentes ha disminuido desde el 2018 hasta el 2023 de manera proporcional en la ciudad de Barranquilla.
acc_años1<- accidentes_bq %>%
group_by(AÑO_ACCIDENTE,GRAVEDAD_ACCIDENTE)%>%
summarise(total_acc =sum(CANTIDAD_ACCIDENTES), .groups = 'drop')
ggplot(data = acc_años1, aes(x = reorder(AÑO_ACCIDENTE, -total_acc), y = total_acc, fill = GRAVEDAD_ACCIDENTE)) +
geom_bar(stat = "identity", position = "dodge") +
scale_fill_manual(values = c("#53868B","#5F9EA0","#98F5FF")) +
labs(title = "Top 7 países con mayores registros de suicidios en 2010", x = "País", y = "Total de suicidios") +
theme(axis.text.x = element_text(angle = 90, hjust = 1))+
theme_minimal()
En el gráfico anterior se puede notar que la mayoría de los accidentes que se registraron entre 2018 y 2023 solo han presentados daños, mientras que el número de accidentes que solo han tenido heridos se ha mantenido constante durante estos años.
accidentes_bq$MES_ACCIDENTE <- as.factor(accidentes_bq$MES_ACCIDENTE)
acc_mes<- accidentes_bq %>%
group_by(MES_ACCIDENTE)%>%
summarise(total_acc =sum(CANTIDAD_ACCIDENTES))
ggplot(acc_mes, aes(reorder(MES_ACCIDENTE, -total_acc), y = total_acc)) +
geom_bar(stat = "identity", fill = "#7AC5CD") +
scale_y_continuous(limits = c(0, 2500)) + # Ajusta el rango del eje y
labs(x = "Mes de Accidente", y = "Total de Accidentes", title = "Total de Accidentes por Mes") +
theme_minimal()
Según lo que se evidencia en el gráfico anterior podemos ver que la cantidad de los accidentes registrados en cada mes no es muy diferente, los accidentes registrados por mes estan estre 1900 y 2300.
accidentes_bq$DIA_ACCIDENTE <- as.factor(accidentes_bq$DIA_ACCIDENTE)
acc_dia<- accidentes_bq %>%
group_by(DIA_ACCIDENTE,GRAVEDAD_ACCIDENTE)%>%
summarise(total_acc =sum(CANTIDAD_ACCIDENTES), .groups = 'drop')
acc_dia# A tibble: 21 × 3
DIA_ACCIDENTE GRAVEDAD_ACCIDENTE total_acc
<fct> <fct> <dbl>
1 Fri Con heridos 1360
2 Fri Con muertos 32
3 Fri Solo daños 2419
4 Mon Con heridos 1410
5 Mon Con muertos 39
6 Mon Solo daños 2222
7 Sat Con heridos 1358
8 Sat Con muertos 34
9 Sat Solo daños 2228
10 Sun Con heridos 1166
# ℹ 11 more rows
ggplot(acc_dia, aes(x=reorder(DIA_ACCIDENTE, -total_acc), y = total_acc,fill=GRAVEDAD_ACCIDENTE)) +
geom_bar(stat = "identity", position = "dodge") +
scale_fill_manual(values = c("#53868B","#5F9EA0","#98F5FF"))+
labs(x = "Día de accidente", y = "Total de Accidentes", title = "Total de Accidentes por día") +
theme_minimal()
El diagrama anterior nos perimite ver como es la gravedad de accidentes por día, viendo así que se ve la misma tendencia que se veía en las gráficas anteriores, donde la mayor cantidad de accidentes son registrados solo con daños, podemos notar que el sabado es la excepción, parece que el los sabados se registran una cantidad similar de accidentes con muertos y heridos.
Detección de datos faltantes y atípicos.
names(accidentes_bq) <- c("fecha", "hora", "gravedad",
"clase", "sitio", "no_heridos",
"no_muertos", "cantidad",
"año", "mes", "dia")Inicialmente veamos la proporcion de datos faltantes.
aggr(accidentes_bq, numbers = TRUE, col = c("#5F9EA0", "#7AC5CD"),
cex.axis = 0.7, gap = 3, ylab = c("Proportion of missingness", "Missingness pattern"))
missmap(accidentes_bq, col = c("#5F9EA0", "#7AC5CD"), legend = TRUE)Warning: Unknown or uninitialised column: `arguments`.
Unknown or uninitialised column: `arguments`.
Warning: Unknown or uninitialised column: `imputations`.

summary(accidentes_bq$no_heridos) Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
1.000 1.000 1.000 1.474 2.000 42.000 15612
summary(accidentes_bq$no_muertos) Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
1.00 1.00 1.00 1.03 1.00 2.00 24634
Con los análisis anteriores, vemos que los datos faltantes están en las variables no_heridos y no_muertos, donde la proporción en la variable no_muertos es del 99%, por tanto, no es posible hacer la imputación para tratarlos, por otro lado, la variable no_heridos es del 62%.
Si estudiamos bien la variable de no_heridos llegamos a la conclusión de que esta variable puede ser tomada como una variable factor, puesto que las categrías serían la cantidad de heridos en cada accidente, sería erroneo tratarla como una variable numérica continua.
accidentes_bq$no_heridos <- as.factor(accidentes_bq$no_heridos)cate_heridos<- as.data.frame(table(accidentes_bq$no_heridos))
cate_heridos Var1 Freq
1 1 6421
2 2 2106
3 3 443
4 4 147
5 5 52
6 6 29
7 7 13
8 8 9
9 9 6
10 10 7
11 11 5
12 12 7
13 13 2
14 14 1
15 15 1
16 16 1
17 18 1
18 19 1
19 20 1
20 21 1
21 22 1
22 23 1
23 42 1
De esta forma si se puede hacer una mejor interpretación acerca de los registros de los números de heridos registrados en cada accidente.
Filtrando el DataFrame para el año 2023.
accidentes_bq2023 <-accidentes_bq %>%
filter(año == 2023)
head(accidentes_bq2023)# A tibble: 6 × 11
fecha hora gravedad clase sitio no_heridos no_muertos cantidad
<dttm> <chr> <fct> <fct> <chr> <fct> <dbl> <dbl>
1 2023-01-01 00:00:00 07:50… Con her… Choq… CALL… 1 NA 1
2 2023-01-01 00:00:00 11:10… Con her… Choq… CALL… 1 NA 1
3 2023-01-02 00:00:00 02:15… Con her… Choq… CALL… 4 NA 1
4 2023-01-02 00:00:00 07:00… Con her… Atro… CALL… 2 NA 1
5 2023-01-02 00:00:00 09:00… Con her… Choq… CALL… 2 NA 1
6 2023-01-02 00:00:00 10:15… Con her… Choq… CALL… 1 NA 1
# ℹ 3 more variables: año <fct>, mes <fct>, dia <fct>
dim(accidentes_bq2023)[1] 1662 11
accidentes_bq2023$no_heridos <-as.factor(accidentes_bq2023$no_heridos)
cate_heridos2023<- as.data.frame(table(accidentes_bq2023$no_heridos))
cate_heridos2023 Var1 Freq
1 1 1059
2 2 417
3 3 88
4 4 33
5 5 7
6 6 6
7 7 3
8 8 1
9 9 0
10 10 1
11 11 1
12 12 2
13 13 0
14 14 0
15 15 1
16 16 0
17 18 1
18 19 0
19 20 0
20 21 1
21 22 0
22 23 1
23 42 0
num_na <- sum(is.na(accidentes_bq2023$no_heridos))
print(num_na)[1] 40
num_na <- sum(is.na(accidentes_bq2023$no_muertos))
print(num_na)[1] 1613
Vemos que al filtrar la base de datos accidentes_bq solo para el año 2023 accidentes_bq2023 la cantidad de datos faltantes en la variable no_heridos se redujo a solo 40, a diferencia de la variable no_muertos que mantiene una gran cantidad con 1613.
Parte 2
En esta parte del trabajo se hará un análisis de los precios del combustible en colombia en el año 2023.
combustible_1 <- read_csv("2023_I.csv",show_col_types = FALSE)
combustible_2 <- read_csv("2023_II.csv",show_col_types = FALSE)
combustible_3 <- read_csv("2023_III.csv",show_col_types = FALSE)
combustible_4 <- read_csv("2023_IV.csv",show_col_types = FALSE)df_2023 <- rbind( combustible_1, combustible_2, combustible_3, combustible_4)Luego de cargar nuestro dataset y unir toda la información en uno nuevo llamado df_2023 podemos empezar los análisis.
dim(df_2023)[1] 270276 7
glimpse(df_2023)Rows: 270,276
Columns: 7
$ BANDERA <chr> "TERPEL", "TERPEL", "TERPEL", "TERPEL", "TERPEL", "…
$ `NOMBRE COMERCIAL` <chr> "ESTACION DE SERVICIO SERVICENTRO LA PEDRERA", "EST…
$ PRODUCTO <chr> "DIESEL", "GASOLINA MOTOR", "GASOLINA MOTOR", "DIES…
$ `FECHA REGISTRO` <chr> "01-Jan-2023", "01-Jan-2023", "01-Jan-2023", "01-Ja…
$ DEPARTAMENTO <chr> "AMAZONAS", "AMAZONAS", "AMAZONAS", "AMAZONAS", "AM…
$ MUNICIPIO <chr> "LA PEDRERA", "LA PEDRERA", "LETICIA", "LETICIA", "…
$ `VALOR PRECIO` <dbl> 15000, 15500, 11380, 10840, 11380, 11380, 10671, 11…
Se tiene un total de 270.276 observaciones y 7 variables.
names(df_2023)[1] "BANDERA" "NOMBRE COMERCIAL" "PRODUCTO" "FECHA REGISTRO"
[5] "DEPARTAMENTO" "MUNICIPIO" "VALOR PRECIO"
names(df_2023)<- c("bandera", "nombreCo", "producto","fecha","depto","munic","valor")names(df_2023)[1] "bandera" "nombreCo" "producto" "fecha" "depto" "munic" "valor"
Variables:
unique(df_2023$bandera) [1] "TERPEL" "TEXACO" "PRIMAX"
[4] "ZEUSS " "BIOMAX" "PETROMIL "
[7] "PETROBRAS" "ESSO" "BRIO "
[10] "PUMA" "PLUS MAS" "ECOS"
[13] "OCTANO" "AYATAWACOOP" "DISCOWACOOP"
[16] "COOMULPINORT" "DISCOM" "P Y B"
[19] "PETRODECOL" "PETRDECOL" "SAVE"
[22] "PROXXON" "ZAPATA Y VELASQUEZ "
En la variable BANDERA estan guaradas las empresas de distribución del combustible.
head(df_2023$nombreCo)[1] "ESTACION DE SERVICIO SERVICENTRO LA PEDRERA"
[2] "ESTACION DE SERVICIO SERVICENTRO LA PEDRERA"
[3] "BALSA EL CONDOR"
[4] "BALSA EL CONDOR"
[5] "ESTACION DE SERVICIO DISTRIBUIDORA LOS COMUNEROS"
[6] "ESTACION DE SERVICIO DISTRIBUIDORA LOS COMUNEROS"
Se tienen registros del nombre de la estación de distribución en la variable NOMBRE COMERCIAL .
df_2023$PRODUCTO <- as.factor(df_2023$producto)
table(df_2023$producto)
DIESEL EXTRA GASOLINA MOTOR
112801 33357 124118
Se tienen regintros de los 32 departamentos de colombia.
head(unique(df_2023$depto))[1] "AMAZONAS" "ANTIOQUIA" "ARAUCA" "ATLANTICO" "BOGOTA D.C."
[6] "BOLIVAR"
Valor de combustible por producto:
gasolina <- df_2023%>%
filter(producto =="GASOLINA MOTOR")
head(gasolina)# A tibble: 6 × 8
bandera nombreCo producto fecha depto munic valor PRODUCTO
<chr> <chr> <chr> <chr> <chr> <chr> <dbl> <fct>
1 TERPEL ESTACION DE SERVICIO SERVIC… GASOLIN… 01-J… AMAZ… LA P… 15500 GASOLIN…
2 TERPEL BALSA EL CONDOR GASOLIN… 01-J… AMAZ… LETI… 11380 GASOLIN…
3 TERPEL ESTACION DE SERVICIO DISTRI… GASOLIN… 01-J… AMAZ… LETI… 11380 GASOLIN…
4 TERPEL ESTACION DE SERVICIO DISTRI… GASOLIN… 01-J… AMAZ… LETI… 11380 GASOLIN…
5 TEXACO EDS COMDECOM ABRIAQUI GASOLIN… 01-J… ANTI… ABRI… 11870 GASOLIN…
6 TEXACO ESTACIÓN DE SERVICIO Y MALL… GASOLIN… 01-J… ANTI… AMAGÁ 11200 GASOLIN…
diesel <- df_2023 %>%
filter(producto =="DIESEL")
head(diesel)# A tibble: 6 × 8
bandera nombreCo producto fecha depto munic valor PRODUCTO
<chr> <chr> <chr> <chr> <chr> <chr> <dbl> <fct>
1 TERPEL ESTACION DE SERVICIO SERVIC… DIESEL 01-J… AMAZ… LA P… 15000 DIESEL
2 TERPEL BALSA EL CONDOR DIESEL 01-J… AMAZ… LETI… 10840 DIESEL
3 TERPEL ESTACION DE SERVICIO DISTRI… DIESEL 01-J… AMAZ… LETI… 10671 DIESEL
4 TEXACO EDS COMDECOM ABRIAQUI DIESEL 01-J… ANTI… ABRI… 10910 DIESEL
5 TEXACO ESTACIÓN DE SERVICIO Y MALL… DIESEL 01-J… ANTI… AMAGÁ 9610 DIESEL
6 TERPEL ESTACION DE SERVICIO POPALI… DIESEL 01-J… ANTI… BARB… 8950 DIESEL
extra <- df_2023 %>%
filter(producto =="EXTRA")
head(extra)# A tibble: 6 × 8
bandera nombreCo producto fecha depto munic valor PRODUCTO
<chr> <chr> <chr> <chr> <chr> <chr> <dbl> <fct>
1 TERPEL ESTACION DE SERVICIO POPALI… EXTRA 01-J… ANTI… BARB… 18760 EXTRA
2 TERPEL ESTACION DE SERVICIO PUERTA… EXTRA 01-J… ANTI… BARB… 19400 EXTRA
3 PRIMAX ESTACION DE SERVICIO PRIMAX… EXTRA 01-J… ANTI… BELLO 19580 EXTRA
4 TERPEL TERPEL FONTIDUENO EXTRA 01-J… ANTI… BELLO 20520 EXTRA
5 ZEUSS ESTACION DE SERVICIO LA CRI… EXTRA 01-J… ANTI… CISN… 20000 EXTRA
6 TERPEL EDS LA COLINA S.A.S EXTRA 01-J… ANTI… CIUD… 17000 EXTRA
Gasolina
summary(gasolina$valor) Min. 1st Qu. Median Mean 3rd Qu. Max.
1000 9721 11200 11512 13148 26000
# Asegúrate de que los nombres de las columnas no tengan errores de sintaxis
ggplot(gasolina, aes(x =valor)) +
geom_boxplot(fill = "#7AC5CD") +
labs(x = "Producto", y = "Valor Precio") +
theme_minimal()
Detectemos los valores atípicos usando la técnica de z-scores .
detect_outliers_zscore <- function(data) {
thres <- 3
mean_value <- mean(data, na.rm = TRUE)
std_value <- sd(data, na.rm = TRUE)
z_scores <- (data - mean_value) / std_value
outlier_indices <- which(abs(z_scores) > thres) # Obtiene los índices de los outliers
return(outlier_indices)
}out <- detect_outliers_zscore(gasolina$valor)
print(length(out))[1] 194
cat("Indices\n")Indices
print(head(out,10)) [1] 916 7265 7267 9980 10030 10031 16254 17119 17120 19132
Hagamos la respectiva imputación de los datos faltantes con el método de pmm .
gasolina$valor[out] <- NaNimp <- mice(gasolina, m=5, maxit=50, method ='pmm', seed=500, printFlag = FALSE)Warning: Number of logged events: 7
imp_gasolina <- complete(imp)
head(imp_gasolina) bandera nombreCo producto
1 TERPEL ESTACION DE SERVICIO SERVICENTRO LA PEDRERA GASOLINA MOTOR
2 TERPEL BALSA EL CONDOR GASOLINA MOTOR
3 TERPEL ESTACION DE SERVICIO DISTRIBUIDORA LOS COMUNEROS GASOLINA MOTOR
4 TERPEL ESTACION DE SERVICIO DISTRIBUIDORA LOS COMUNEROS GASOLINA MOTOR
5 TEXACO EDS COMDECOM ABRIAQUI GASOLINA MOTOR
6 TEXACO ESTACIÓN DE SERVICIO Y MALL SANTA LUCIA S.A.S. GASOLINA MOTOR
fecha depto munic valor PRODUCTO
1 01-Jan-2023 AMAZONAS LA PEDRERA 15500 GASOLINA MOTOR
2 01-Jan-2023 AMAZONAS LETICIA 11380 GASOLINA MOTOR
3 01-Jan-2023 AMAZONAS LETICIA 11380 GASOLINA MOTOR
4 01-Jan-2023 AMAZONAS LETICIA 11380 GASOLINA MOTOR
5 01-Jan-2023 ANTIOQUIA ABRIAQUÍ 11870 GASOLINA MOTOR
6 01-Jan-2023 ANTIOQUIA AMAGÁ 11200 GASOLINA MOTOR
ggplot(imp_gasolina, aes(x =valor)) +
geom_boxplot(fill = "#7AC5CD") +
labs(x = "Producto", y = "Valor Precio") +
theme_minimal()
Veamos otra grafica importante:
gas_bandera <- imp_gasolina %>%
group_by(bandera) %>%
summarise(valor = mean(valor, na.rm = TRUE)) %>%
arrange(desc(valor)) %>%
slice_head(n = 12)
ggplot(data = gas_bandera, aes(x = reorder(bandera, -valor), y = valor)) +
geom_bar(stat = "identity", fill = "#7AC5CD") +
labs(x = "Bandera", y = "Precio por Bandera") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 90, hjust = 1))
Diesel
summary(diesel$valor) Min. 1st Qu. Median Mean 3rd Qu. Max.
0 8750 9245 9145 9580 71590
plot1 <-ggplot(diesel, aes(x =valor)) +
geom_histogram(fill = "#7AC5CD") +
labs(x = "Producto", y = "Valor Precio") +
theme_minimal()
plot2 <- ggplot(diesel, aes(x =valor)) +
geom_boxplot(fill = "#7AC5CD") +
labs(x = "Producto", y = "Valor Precio") +
theme_minimal()
grid.arrange(plot1, plot2, ncol = 2)`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

La presencia de datos atípicos en el valor de diesel parece ser mayor, veamos la prueba:
out <- detect_outliers_zscore(diesel$valor)
print(length(out))[1] 1058
cat("Indices\n")Indices
print(head(out,10)) [1] 1 941 1281 1820 2676 2750 2751 2813 2814 2817
Procedemos de nuevo a hacer la imputación debida de los datos atípicos.
diesel$valor[out] <- NaNimp <- mice(diesel, m=5, maxit=50, method ='pmm', seed=500, printFlag = FALSE)Warning: Number of logged events: 7
imp_diesel <- complete(imp)
head(imp_diesel) bandera nombreCo producto fecha
1 TERPEL ESTACION DE SERVICIO SERVICENTRO LA PEDRERA DIESEL 01-Jan-2023
2 TERPEL BALSA EL CONDOR DIESEL 01-Jan-2023
3 TERPEL ESTACION DE SERVICIO DISTRIBUIDORA LOS COMUNEROS DIESEL 01-Jan-2023
4 TEXACO EDS COMDECOM ABRIAQUI DIESEL 01-Jan-2023
5 TEXACO ESTACIÓN DE SERVICIO Y MALL SANTA LUCIA S.A.S. DIESEL 01-Jan-2023
6 TERPEL ESTACION DE SERVICIO POPALITO DIESEL 01-Jan-2023
depto munic valor PRODUCTO
1 AMAZONAS LA PEDRERA 9999 DIESEL
2 AMAZONAS LETICIA 10840 DIESEL
3 AMAZONAS LETICIA 10671 DIESEL
4 ANTIOQUIA ABRIAQUÍ 10910 DIESEL
5 ANTIOQUIA AMAGÁ 9610 DIESEL
6 ANTIOQUIA BARBOSA 8950 DIESEL
plot1 <-ggplot(imp_diesel, aes(x =valor)) +
geom_histogram(fill = "#7AC5CD") +
labs(x = "Producto", y = "Valor Precio") +
theme_minimal()
plot2 <- ggplot(imp_diesel, aes(x =valor)) +
geom_boxplot(fill = "#7AC5CD") +
labs(x = "Producto", y = "Valor Precio") +
theme_minimal()
grid.arrange(plot1, plot2, ncol = 2)`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Vemos que en este caso, a diferencia de la gasolina, parece ser que no se detectaron todos los datos, puesto que nuestra función para detectarlos solo está tomando los que están por fuera de 3 veces el RIQ. Pero aun así hubo una gran mejoría con la imputación de los datos más extremos.
Precio del diesel por bandera:
diesel_bandera <- imp_diesel %>%
group_by(bandera) %>%
summarise(valor = mean(valor, na.rm = TRUE)) %>%
arrange(desc(valor)) %>%
slice_head(n = 12)
ggplot(data = diesel_bandera, aes(x = reorder(bandera, -valor), y = valor)) +
geom_bar(stat = "identity", fill = "#7AC5CD") +
labs(x = "Bandera", y = "Precio por Bandera") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 90, hjust = 1))
Vemos con este análisis que el precio del diesel por bandera no cambia mucho, estas 12 empresas con el diesel mas alto tienen precios cercanos a 9.300.
Extra
summary(extra$valor) Min. 1st Qu. Median Mean 3rd Qu. Max.
1000 18890 19490 18819 19980 200000
Desde este punto ya podemos hacernos una idea de que ese valor máximo en el valor del combustible extra puede ser un error de digitación.
ggplot(extra, aes(x =valor)) +
geom_boxplot(fill = "#7AC5CD") +
labs(x = "Producto", y = "Valor Precio") +
theme_minimal()
out <- detect_outliers_zscore(extra$valor)
print(length(out))[1] 897
cat("Indices\n")Indices
print(head(out,10)) [1] 115 120 122 123 138 266 269 695 748 749
extra$valor[out] <- NaNimp <- mice(extra, m=5, maxit=50, method ='pmm', seed=500, printFlag = FALSE)Warning: Number of logged events: 7
imp_extra <- complete(imp)
head(imp_extra) bandera nombreCo producto fecha
1 TERPEL ESTACION DE SERVICIO POPALITO EXTRA 01-Jan-2023
2 TERPEL ESTACION DE SERVICIO PUERTAS DEL NORDESTE EXTRA 01-Jan-2023
3 PRIMAX ESTACION DE SERVICIO PRIMAX AUTOPISTA EXTRA 01-Jan-2023
4 TERPEL TERPEL FONTIDUENO EXTRA 01-Jan-2023
5 ZEUSS ESTACION DE SERVICIO LA CRISTALINA EXTRA 01-Jan-2023
6 TERPEL EDS LA COLINA S.A.S EXTRA 01-Jan-2023
depto munic valor PRODUCTO
1 ANTIOQUIA BARBOSA 18760 EXTRA
2 ANTIOQUIA BARBOSA 19400 EXTRA
3 ANTIOQUIA BELLO 19580 EXTRA
4 ANTIOQUIA BELLO 20520 EXTRA
5 ANTIOQUIA CISNEROS 20000 EXTRA
6 ANTIOQUIA CIUDAD BOLÍVAR 17000 EXTRA
ggplot(imp_extra, aes(x =valor)) +
geom_boxplot(fill = "#7AC5CD") +
labs(x = "Producto", y = "Valor Precio") +
theme_minimal()
En el caso del combustible extra pasó algo similar a con el diesel, con la imputación mejoró la distribución de la variable, aun cuando se siguen presentando datos atípicos, esto es razonable, puesto que el valor del extra varía en gran manera.
extra_bandera <- imp_extra %>%
group_by(bandera) %>%
summarise(valor = mean(valor, na.rm = TRUE)) %>%
arrange(valor) %>%
slice_head(n = 12)
# Crear el gráfico de barras
ggplot(data = extra_bandera, aes(x = reorder(bandera, valor), y = valor)) +
geom_bar(stat = "identity", fill = "#7AC5CD") +
labs(x = "Bandera", y = "Precio por Bandera") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 90, hjust = 1))
Puesto que el combustible “Extra” es el que tiene el precio promedio mas alto, con la grafica anterior vemos que la bandera “SAVE” es el que tiene menor precio promedio 12000, a diferencia de las otras empresas que sus precios ya rodean los 20.000 pesos colombianos.
Precio promedio de la gasolina por departamento.
mapa_col <- st_read("COLOMBIA/COLOMBIA.shp", quiet = FALSE)Reading layer `COLOMBIA' from data source
`C:\Users\fonta\OneDrive\Documentos\CDD\6. Sexto semestre\Visualizacion de datos\Corte 1\Entrega2\Entrega 2\COLOMBIA\COLOMBIA.shp'
using driver `ESRI Shapefile'
Simple feature collection with 33 features and 11 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: -81.73575 ymin: -4.227907 xmax: -66.84735 ymax: 13.39453
Geodetic CRS: WGS 84
mapa_col <- st_make_valid(mapa_col)Habiendo cargado las coordenadas del mapa de Colombia, rectificamos que los nombres de los departamentos en ambos datasets coinciden.
dpto_1 <- tolower(imp_gasolina$depto)
dpto_2 <- tolower(mapa_col$DPTO_CNMBR)
M1 <- which(is.na(match(dpto_1, dpto_2)))
dpto_2 <- str_replace_all(dpto_2, "\\?", "ñ")
dpto_2 <- str_replace_all(dpto_2, "archipielago de san andres",
"archipielago de san andres, santa catalina y providencia")
imp_gasolina$codigo <- dpto_1
mapa_col$codigo <- dpto_2datos_unidos <- merge(st_drop_geometry(mapa_col), imp_gasolina, by = "codigo", all = TRUE, sort = FALSE)Con el proceso anterior listo, pasamos a calcular el precio promedio por departamento y lo guardamos en una nueva columna de nuestro df datos_unidos2.
datos_unidos2 <- datos_unidos %>%
group_by(codigo, DPTO_NANO_, DPTO_NAREA, DPTO_CSMBL, DPTO_NANO, PAIS_PAIS_, SHAPE_Leng, SHAPE_Area) %>%
summarize(precio_prom_dpto = mean(valor)) %>%
ungroup() `summarise()` has grouped output by 'codigo', 'DPTO_NANO_', 'DPTO_NAREA',
'DPTO_CSMBL', 'DPTO_NANO', 'PAIS_PAIS_', 'SHAPE_Leng'. You can override using
the `.groups` argument.
Hallamos el máximo para poder hacer los intervalos de los precios, para así poder graficar mejor en el mapa.
max(datos_unidos2$precio_prom_dpto)[1] 13586.14
precio_fac <- cut(datos_unidos2$precio_prom_dpto,
breaks = c(0, 8000, 9000, 10000, 11000, 13600),
labels = c("a. 0-8.000", "b. 8.000-9.000", "c. 9.000-10.000", "d. 10.000-11.000", "e. 12.000-13.600"))colores <- c("a. 0-8.000" = "#E0FFFF",
"b. 8.000-9.000" = "#FFBBFF",
"c. 9.000-10.000" = "#FF6EB4",
"d. 10.000-11.000" = "#FF4500",
"e. 12.000-13.000" = "#8B1C62")if (length(precio_fac) == nrow(datos_unidos2)) {
datos_unidos2$color <- colores[precio_fac]
cat("Colores asignados correctamente.\n")
} else {
stop("Error: La longitud de precio_fac no coincide con el número de filas en datos_unidos2.")
}Colores asignados correctamente.
En los pasos anteriores se definieron los intervalos de los precios, se eligió la paleta de colores y se guardaron los colores en el df dependiendo de en que intervalo se encontraba el precio promedio de cada departamento. Con esto podemos hacer la última unión de data frames para luego graficar.
datos_unidos_final <- merge(mapa_col, datos_unidos2, by = "codigo")names(datos_unidos_final) [1] "codigo" "OBJECTID" "DPTO_CCDGO" "DPTO_NANO_.x"
[5] "DPTO_CNMBR" "DPTO_CACTO" "DPTO_NAREA.x" "DPTO_CSMBL.x"
[9] "DPTO_NANO.x" "PAIS_PAIS_.x" "SHAPE_Leng.x" "SHAPE_Area.x"
[13] "DPTO_NANO_.y" "DPTO_NAREA.y" "DPTO_CSMBL.y" "DPTO_NANO.y"
[17] "PAIS_PAIS_.y" "SHAPE_Leng.y" "SHAPE_Area.y" "precio_prom_dpto"
[21] "color" "geometry"
leaflet(datos_unidos_final) %>%
addTiles() %>%
addPolygons(popup = ~DPTO_CNMBR, color = "black", fillColor = ~color, weight = 1.1) %>%
addLegend(position = "topright",
pal = colorFactor(palette = c("#E0FFFF", "#FFBBFF", "#FF6EB4", "#FF4500", "#8B1C62"),
domain = levels(precio_fac)),
values = levels(precio_fac),
title = "Precio promedio de gasolina corriente en 2019")