Recursos/Librerías

library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.5.1     ✔ tibble    3.2.1
## ✔ lubridate 1.9.3     ✔ tidyr     1.3.1
## ✔ purrr     1.0.2     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(ggplot2)
library(readxl)
require(tibble)
library(readr)
library(dplyr)
library(Amelia)
## Cargando paquete requerido: Rcpp
## ## 
## ## Amelia II: Multiple Imputation
## ## (Version 1.8.2, built: 2024-04-10)
## ## Copyright (C) 2005-2024 James Honaker, Gary King and Matthew Blackwell
## ## Refer to http://gking.harvard.edu/amelia/ for more information
## ##
library(Rcpp)
library(knitr)
library(kableExtra)
## 
## Adjuntando el paquete: 'kableExtra'
## 
## The following object is masked from 'package:dplyr':
## 
##     group_rows
library(scales) 
## 
## Adjuntando el paquete: 'scales'
## 
## The following object is masked from 'package:purrr':
## 
##     discard
## 
## The following object is masked from 'package:readr':
## 
##     col_factor
library(viridis)
## Cargando paquete requerido: viridisLite
## 
## Adjuntando el paquete: 'viridis'
## 
## The following object is masked from 'package:scales':
## 
##     viridis_pal
library(nortest)

##Importar base de datos

#Cargar la base de datos en la variable "bd"
bd <- read.csv(file.choose(), 
        sep=",", 
        header=TRUE, 
        fileEncoding = "UTF-8")

##Visualización del data frame:

kable(bd[1:20, ], caption = "Tabla 1: Colombianos en el exterior") %>%
  kable_styling(full_width = F) %>%
  column_spec(2, width = "20em") %>%
  scroll_box(width = "900px", height = "450px")
Tabla 1: Colombianos en el exterior
País Código.ISO.país Oficina.de.registro Grupo.edad Edad..años. Área.Conocimiento Sub.Area.Conocimiento Nivel.Académico Estado.civil Género Etnia.de.la.persona Estatura..CM. Localización Cantidad.de.personas
ARGENTINA ARG C. BUENOS AIRES ADOLESCENTE 14 INGENIERÍA, ARQUITECTURA Y AFINES INGENIERÍA ELÉCTRICA Y AFINES NO INDICA SOLTERO FEMENINO NINGUNA -1 (-38.416097, -63.616672) 1
ECUADOR ECU C. QUITO ADULTO 57 CIENCIAS DE LA SALUD INSTRUMENTACIÓN QUIRÚRGICA PREGRADO - TECNOLÓGICO CASADO FEMENINO OTRO -1 (-1.831239, -78.183406) 1
ESPAÑA ESP C. LAS PALMAS DE G.C ADULTO JOVEN 28 NO INDICA NO INDICA BACHILLERATO SOLTERO MASCULINO NINGUNA 164 (40.463667, -3.74922) 1
ESTADOS UNIDOS USA C. ORLANDO ADULTO MAYOR 66 ECONOMÍA, ADMINISTRACIÓN CONTADURIA Y AFINES ADMINISTRACIÓN PREGRADO - PROFESIONAL CASADO FEMENINO OTRO -1 (37.09024, -95.712891) 1
CHILE CHL C. ANTOFAGASTA ADULTO 57 NINGUNA NINGUNA PRIMARIA SOLTERO FEMENINO AFRODESCENDIENTE 159 (-35.675147, -71.542969) 1
REPUBLICA DOMINICANA DOM C. SANTO DOMINGO ADULTO 43 ECONOMÍA, ADMINISTRACIÓN CONTADURIA Y AFINES ADMINISTRACIÓN NO INDICA CASADO FEMENINO NINGUNA -1 (18.735693, -70.162651) 1
DINAMARCA DNK C. ESTOCOLMO ADULTO JOVEN 27 CIENCIAS DE LA EDUCACIÓN EDUCACIÓN NO INDICA SOLTERO MASCULINO NINGUNA -1 (56.26392, 9.501785) 1
CANADA CAN C. MONTREAL ADULTO 51 NO INDICA NO INDICA PREGRADO - PROFESIONAL VIUDO FEMENINO NINGUNA 154 (56.130366, -106.346771) 1
VENEZUELA VEN C. BARINAS ADULTO 39 NO INDICA NO INDICA PRIMARIA CASADO MASCULINO NINGUNA 185 (6.42375, -66.58973) 1
VENEZUELA VEN C. MERIDA VEN ADULTO MAYOR 94 NO INDICA NO INDICA PRIMARIA CASADO MASCULINO OTRO -1 (6.42375, -66.58973) 1
AUSTRALIA AUS C. SYDNEY ADULTO 35 CIENCIAS DE LA EDUCACIÓN EDUCACIÓN PREGRADO - TÉCNICO PROFESIONAL DESCONOCIDO MASCULINO OTRO -1 (-25.274398, 133.775136) 1
AUSTRIA AUT C. VIENA ADULTO 46 MATEMÁTICAS Y CIENCIAS NATURALES BIOLOGÍA, MICROBIOLOGÍA Y AFINES NO INDICA CASADO MASCULINO OTRO -1 (47.516231, 14.550072) 1
ESPAÑA ESP C. VALENCIA ESP ADULTO 56 NO INDICA NO INDICA PREGRADO - PROFESIONAL CASADO MASCULINO NINGUNA 170 (40.463667, -3.74922) 1
VENEZUELA VEN C. VALENCIA VEN ADULTO 43 CIENCIAS SOCIALES Y HUMANAS PERIODISMO, COMUNICACIÓN SOCIAL Y AFINES PREGRADO - TECNOLÓGICO SOLTERO FEMENINO NINGUNA 158 (6.42375, -66.58973) 1
SINGAPUR SGP C. SINGAPUR ADULTO 56 INGENIERÍA, ARQUITECTURA Y AFINES INGENIERÍA EN SISTEMAS, TELEMÁTICA Y AFINES POSTGRADO - MAESTRIA CASADO MASCULINO NINGUNA -1 (1.352083, 103.819836) 1
ESTADOS UNIDOS USA C. ORLANDO ADULTO MAYOR 85 NO INDICA NO INDICA PRIMARIA SOLTERO FEMENINO OTRO 148 (37.09024, -95.712891) 1
SUIZA CHE C. BERNA ADULTO 54 NINGUNA NINGUNA BACHILLERATO DIVORCIADO MASCULINO NINGUNA 163 (46.818188, 8.227512) 1
ESTADOS UNIDOS USA C. HOUSTON ADULTO 42 BELLAS ARTES DISEÑO NO INDICA UNION_LIBRE FEMENINO NINGUNA -1 (37.09024, -95.712891) 1
REINO UNIDO GBR C. LONDRES ADULTO 40 INGENIERÍA, ARQUITECTURA Y AFINES INGENIERÍA ELÉCTRICA Y AFINES NO INDICA SOLTERO MASCULINO OTRO -1 (55.378051, -3.435973) 1
REINO UNIDO GBR C. LONDRES ADULTO 44 NO INDICA NO INDICA POSTGRADO - MAESTRIA CASADO MASCULINO NINGUNA 194 (55.378051, -3.435973) 1

CONTENIDO

1. Contextualización:

Descripción de la Base de Datos: La base de datos “Colombianos registrados en el exterior” es un conjunto de datos abiertos, suministrado por el Ministerio de relaciones exteriores y publicado a través del portal de datos abiertos de Colombia (datos.gov.co). Este dataset recoge información detallada acerca de la población colombiana residente y registrada en las diferentes misiones consulares en el exterior que incluye el género, la edad, el nivel de estudios, la ocupación, lugar de residencia, el consulado de la circunscripción que lo atiende, entre otros.

Estos datos son recolectados con el propósito de mantener un registro actualizado de los colombianos que residen fuera del país, siendo útil para entender la distribución geográfica de la diáspora colombiana y para asuntos electorales y de servicios consulares. Además, el registro en consulados permite a los ciudadanos acceder a diversos servicios, como la renovación de documentos de identidad y la realización de trámites legales.

Es importante destacar que la base de datos solo incluye a aquellos ciudadanos que se han registrado voluntariamente en los consulados, por lo que no refleja la totalidad de la población colombiana en el exterior. Sin embargo, proporciona una valiosa fuente de información para estudios sobre la diáspora colombiana y su impacto en la política y la economía del país.

Las variables descritas son:

País:Indica el país en el cual se encuentra registrado y reside el ciudadano colombiano. Cuando no se tienen datos registrados se presenta el texto (NO REGISTRA).
Código ISO país: Es el código alfanumérico de tres letras que representa el país según el estándar ISO 3166-1. Cuando no se tienen datos registrados se presenta el texto (NO REGISTRA).
Oficina de resgistro:Especifica el consulado o embajada donde el ciudadano realizó su registro. Cuando no se tienen datos registrados se presenta el texto (NO REGISTRA).
Grupo de edad:Categorización de la edad de los ciudadanos registrados en intervalos.Primera infancia: Entre 0 y 5 años; Infante: Entre 6 y 11 años; Adolescente: Entre 12 y 18 años; Adulto joven: Entre 19 y 28 años; Adulto: Entre 29 y 59 años; Adulto mayor: Entre 60 en adelante.
Edad (años):La edad exacta del ciudadano al momento del registro. Cuando no se tienen datos registrados se el valor -1.
Área de conocimiento:Indica la disciplina o campo principal en el que la persona tiene formación o experiencia. Cuando no se tienen datos registrados se presenta el texto (NO REGISTRA).
Sub área de conocimiento:Es una categoría más específica dentro del área de conocimiento, que detalla la especialización del individuo. Cuando no se tienen datos registrados se presenta el texto (NO REGISTRA).
Nivel académico:Representa el grado máximo de educación alcanzado por el ciudadano. Cuando no se tienen datos registrados se presenta el texto (NO REGISTRA).
Estado civil: Indica el estado civil del ciudadano en el momento del registro. Cuando no se tienen datos registrados se presenta el texto (NO REGISTRA).
Género:Especifica el género del ciudadano, generalmente categorizado como masculino o femenino. Cuando no se tienen datos registrados se presenta el texto (DESCONOCIDO).
Etnia de la persona:Clasifica al ciudadano según su pertenencia a grupos étnicos reconocidos en Colombia. Cuando no se tienen datos registrados se presenta el texto (NO REGISTRA).
Estatura (CM):Altura del ciudadano en centímetros. El valor -1 indica que no se encuentra una estatura registrada.
Localización:Detalla la ubicación geográfica específica dentro del país de residencia, como ciudad o región. • Cantidad de personas:Indica la cantidad de personas residentes en el exterior que cumplen con las condiciones demográficas.

2.Características de la base de datos

Dimensiones:

dim(bd)
## [1] 782250     14
  • Número de filas: 782250
  • Número de columnas: 14

Nombres de las variables:

names(bd)
##  [1] "País"                  "Código.ISO.país"       "Oficina.de.registro"  
##  [4] "Grupo.edad"            "Edad..años."           "Área.Conocimiento"    
##  [7] "Sub.Area.Conocimiento" "Nivel.Académico"       "Estado.civil"         
## [10] "Género"                "Etnia.de.la.persona"   "Estatura..CM."        
## [13] "Localización"          "Cantidad.de.personas"

Tipo de dato(estructura):

sapply(bd, class)
##                  País       Código.ISO.país   Oficina.de.registro 
##           "character"           "character"           "character" 
##            Grupo.edad           Edad..años.     Área.Conocimiento 
##           "character"             "integer"           "character" 
## Sub.Area.Conocimiento       Nivel.Académico          Estado.civil 
##           "character"           "character"           "character" 
##                Género   Etnia.de.la.persona         Estatura..CM. 
##           "character"           "character"             "integer" 
##          Localización  Cantidad.de.personas 
##           "character"             "integer"
table(str(bd))
## 'data.frame':    782250 obs. of  14 variables:
##  $ País                 : chr  "ARGENTINA" "ECUADOR" "ESPAÑA" "ESTADOS UNIDOS" ...
##  $ Código.ISO.país      : chr  "ARG" "ECU" "ESP" "USA" ...
##  $ Oficina.de.registro  : chr  "C. BUENOS AIRES" "C. QUITO" "C. LAS PALMAS DE G.C" "C. ORLANDO" ...
##  $ Grupo.edad           : chr  "ADOLESCENTE" "ADULTO" "ADULTO JOVEN" "ADULTO MAYOR" ...
##  $ Edad..años.          : int  14 57 28 66 57 43 27 51 39 94 ...
##  $ Área.Conocimiento    : chr  "INGENIERÍA, ARQUITECTURA Y AFINES" "CIENCIAS DE LA SALUD" "NO INDICA" "ECONOMÍA, ADMINISTRACIÓN CONTADURIA Y AFINES" ...
##  $ Sub.Area.Conocimiento: chr  "INGENIERÍA ELÉCTRICA Y AFINES" "INSTRUMENTACIÓN QUIRÚRGICA" "NO INDICA" "ADMINISTRACIÓN" ...
##  $ Nivel.Académico      : chr  "NO INDICA" "PREGRADO - TECNOLÓGICO" "BACHILLERATO" "PREGRADO - PROFESIONAL" ...
##  $ Estado.civil         : chr  "SOLTERO" "CASADO" "SOLTERO" "CASADO" ...
##  $ Género               : chr  "FEMENINO" "FEMENINO" "MASCULINO" "FEMENINO" ...
##  $ Etnia.de.la.persona  : chr  "NINGUNA" "OTRO" "NINGUNA" "OTRO" ...
##  $ Estatura..CM.        : int  -1 -1 164 -1 159 -1 -1 154 185 -1 ...
##  $ Localización         : chr  "(-38.416097, -63.616672)" "(-1.831239, -78.183406)" "(40.463667, -3.74922)" "(37.09024, -95.712891)" ...
##  $ Cantidad.de.personas : int  1 1 1 1 1 1 1 1 1 1 ...
## < table of extent 0 >

#En esta subsección, se realiza un cambio en el formato de dos variables para cumplir con los lineamientos y mejorar la coherencia del análisis. La variable “Estatura (CM)”, originalmente registrada en centimetros, se cambiará a metros para convertise en cuantitativa-continua. De manera similar, la variable “Localización”, que está registrada como carácter, será transformada a cuantitativa-continua. Tocará especificar que no es necesario el cambio de formato.

3. Análisis detallado de las variables:

Clasificación de las variables:
Categóricas/cualitativas:
• Nominales: País, Código ISO, Oficina de registro, Área de conocimiento, Sub área de conocimiento, Estado civil, Género, Etnia, Localización. • Ordinales: Grupo edad, Nivel académico.

Numéricas/cuantitativas:
• Discretas: Edad(años), Estatura (CM), Cantidad de personas.
• Continuas: NA

A continuación se representa a traves de una tabla utilizando el paquete knitr, que organiza la clasificación de las variables según su tipo y subtipo:

# Creación del data frame
clasificacion_variables <- data.frame(
  Tipo = c("Categóricas/cualitativas", "Categóricas/cualitativas", 
           "Numéricas/cuantitativas", "Numéricas/cuantitativas"),
  Subtipo = c("Nominales", "Ordinales", "Discretas", "Continuas"),
  Variables = c(
    "País, Código ISO, Oficina de registro, Área de conocimiento, Sub área de conocimiento, Estado civil, Género, Etnia, Localización",
    "Grupo edad, Nivel académico",
    "Edad (años), Estatura (CM), Cantidad de personas",
    "NA"
  )
)
# Crear la tabla con kable y mostrar
clasificacion_variables %>%
  kable(col.names = c("Tipo", "Subtipo", "Variables"), 
        caption = "Clasificación de las Variables") %>%
  kable_styling(full_width = FALSE) %>%
  row_spec(0, background = "#DCE6F1")  
Clasificación de las Variables
Tipo Subtipo Variables
Categóricas/cualitativas Nominales País, Código ISO, Oficina de registro, Área de conocimiento, Sub área de conocimiento, Estado civil, Género, Etnia, Localización
Categóricas/cualitativas Ordinales Grupo edad, Nivel académico
Numéricas/cuantitativas Discretas Edad (años), Estatura (CM), Cantidad de personas
Numéricas/cuantitativas Continuas NA

Resumen individual de las variables:
NÚMERICAS/CUANTITATIVAS: Hago uso de la función summary():

##Realizo un vector para listar todas las variables de tipo cuantitativa
  v_n <- c("Edad..años.", "Estatura..CM.", "Cantidad.de.personas")
summary(bd[v_n])
##   Edad..años.     Estatura..CM.    Cantidad.de.personas
##  Min.   : -1.00   Min.   :    -1   Min.   :  1.000     
##  1st Qu.: 34.00   1st Qu.:    -1   1st Qu.:  1.000     
##  Median : 44.00   Median :    -1   Median :  1.000     
##  Mean   : 45.79   Mean   :    59   Mean   :  1.983     
##  3rd Qu.: 57.00   3rd Qu.:   160   3rd Qu.:  1.000     
##  Max.   :140.00   Max.   :163163   Max.   :408.000
bd3 <- bd %>%
  mutate(Edad_Rango = case_when(
    `Edad..años.` >= 0 & `Edad..años.` <= 10 ~ "(0-10)",
    `Edad..años.` >= 11 & `Edad..años.` <= 18 ~ "(11-18)",
    `Edad..años.` >= 19 & `Edad..años.` <= 35 ~ "(19-35)",
    `Edad..años.` >= 36 & `Edad..años.` <= 50 ~ "(36-50)",
    `Edad..años.` > 50 ~ "(50+)",
    TRUE ~ "Desconocido"  
  ))
edad_rango_count <- bd3 %>%
  count(Edad_Rango) %>%
  arrange(Edad_Rango)

ggplot(edad_rango_count, aes(x = reorder(Edad_Rango, n), y = n, fill = Edad_Rango)) +
  geom_bar(stat = "identity", color = "black") +  # Colorear las barras por rango de edad
  labs(title = "Distribución de Edades de Colombianos en el Exterior",
       x = "Rango de Edad",
       y = "Cantidad de Personas") +
  theme_minimal() +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold", size = 16),
    axis.title.x = element_text(face = "bold", size = 14),
    axis.title.y = element_text(face = "bold", size = 14),
    legend.position = "none",  # Eliminar la leyenda
    axis.text.x = element_text(angle = 0, hjust = 1)  # Mejorar la legibilidad de las etiquetas
  ) +
  scale_fill_brewer(palette = "Set3") +  # Usar una paleta de colores con suficiente contraste
  scale_y_continuous(labels = scales::comma)

##Análisis estadístico y pruebas de normalidad:

# Calcular media y mediana para Edad
media_edad <- mean(bd$Edad..años., na.rm = TRUE)
mediana_edad <- median(bd$Edad..años., na.rm = TRUE)
# Calcular media y mediana para Estatura
media_estatura <- mean(bd$Estatura..CM., na.rm = TRUE)
mediana_estatura <- median(bd$Estatura..CM., na.rm = TRUE)
# Calcular media y mediana para Cantidad de personas
media_cantidad_personas <- mean(bd$Cantidad.de.personas, na.rm = TRUE)
mediana_cantidad_personas <- median(bd$Cantidad.de.personas, na.rm = TRUE)
# Crear un data frame con los resultados
resultados <- data.frame(
  Variable = c("Edad", "Estatura (CM)", "Cantidad de Personas"),
  Media = c(media_edad, media_estatura, media_cantidad_personas),
  Mediana = c(mediana_edad, mediana_estatura, mediana_cantidad_personas)
)
# Mostrar la tabla utilizando kableExtra
kable(resultados, col.names = c("Variable", "Media", "Mediana")) %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"), full_width = F) %>%
  row_spec(0, bold = TRUE, color = "white", background = "#4CAF50") %>%
  row_spec(1:3, background = "#f5f5f5")
Variable Media Mediana
Edad 45.790231 44
Estatura (CM) 59.001006 -1
Cantidad de Personas 1.983135 1
# Definir los percentiles que deseas calcular
percentiles <- c(0.25, 0.50, 0.75, 0.90, 0.95)

# Calcular los percentiles para Edad
percentiles_edad <- quantile(bd$Edad..años., percentiles, na.rm = TRUE)
# Calcular los percentiles para Estatura
percentiles_estatura <- quantile(bd$Estatura..CM., percentiles, na.rm = TRUE)
# Calcular los percentiles para Cantidad de Personas
percentiles_cantidad_personas <- quantile(bd$Cantidad.de.personas, percentiles, na.rm = TRUE)
# Crear un data frame con los resultados
percentiles_df <- data.frame(
  Percentil = names(percentiles_edad),
  `Edad (años)` = percentiles_edad,
  `Estatura (CM)` = percentiles_estatura,
  `Cantidad de Personas` = percentiles_cantidad_personas
)
# Mostrar la tabla utilizando kableExtra
kable(percentiles_df, col.names = c("Percentil", "Edad (años)", "Estatura (CM)", "Cantidad de Personas")) %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"), full_width = F) %>%
  row_spec(0, bold = TRUE, color = "white", background = "#2196F3") %>%
  row_spec(1:5, background = "#e0f7fa")
Percentil Edad (años) Estatura (CM) Cantidad de Personas
25% 25% 34 -1 1
50% 50% 44 -1 1
75% 75% 57 160 1
90% 90% 68 170 3
95% 95% 74 175 5
# Calcular desviación estándar y coeficiente de variación
estadisticas <- bd %>%
  summarise(
    `Desviación Estándar (Edad)` = sd(Edad..años., na.rm = TRUE),
    `Coeficiente de Variación (Edad)` = (sd(Edad..años., na.rm = TRUE) / mean(Edad..años., na.rm = TRUE))*100,
    
    `Desviación Estándar (Estatura)` = sd(Estatura..CM., na.rm = TRUE),
    `Coeficiente de Variación (Estatura)` = (sd(Estatura..CM., na.rm = TRUE) / mean(Estatura..CM., na.rm = TRUE))*100,
    
    `Desviación Estándar (Cantidad de Personas)` = sd(Cantidad.de.personas, na.rm = TRUE),
    `Coeficiente de Variación (Cantidad de Personas)` = (sd(Cantidad.de.personas, na.rm = TRUE) / mean(Cantidad.de.personas, na.rm = TRUE))*100
  )

# Convertir los resultados en un data frame para mostrar en tabla
estadisticas_df <- as.data.frame(t(estadisticas))
colnames(estadisticas_df) <- c("Valor")

# Mostrar los resultados en una tabla con kableExtra
kable(estadisticas_df, caption = "Desviación Estándar y Coeficiente de Variación para Variables Cuantitativas") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"))
Desviación Estándar y Coeficiente de Variación para Variables Cuantitativas
Valor
Desviación Estándar (Edad) 16.166519
Coeficiente de Variación (Edad) 35.305606
Desviación Estándar (Estatura) 265.885143
Coeficiente de Variación (Estatura) 450.645101
Desviación Estándar (Cantidad de Personas) 5.938355
Coeficiente de Variación (Cantidad de Personas) 299.442885
# Convertir los resultados en un data frame adecuado para la gráfica
estadisticas_graf <- estadisticas_df %>%
  rownames_to_column("Métrica") %>%
  separate(Métrica, into = c("Métrica", "Variable"), sep = " \\(") %>%
  mutate(Variable = gsub("\\)", "", Variable))

# Crear la gráfica
ggplot(estadisticas_graf, aes(x = Variable, y = Valor, fill = Métrica)) +
  geom_bar(stat = "identity", position = "dodge", color = "black") +
  labs(title = "Desviación Estándar y Coeficiente de Variación",
       x = "Variable",
       y = "Valor") +
  theme_minimal() +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold", size = 16),
    axis.title.x = element_text(face = "bold", size = 14),
    axis.title.y = element_text(face = "bold", size = 14)
  ) +
  scale_fill_brewer(palette = "Set3")

Realización de la prueba de Anderson-Darling:

ad_edad <- ad.test(bd$Edad..años.)
ad_estatura <- ad.test(bd$Estatura..CM.)
ad_cantidad_personas <- ad.test(bd$Cantidad.de.personas)

# Crear una tabla con los resultados
ad_results <- data.frame(
  Variable = c("Edad", "Estatura", "Cantidad de Personas"),
  Statistic = c(ad_edad$statistic, ad_estatura$statistic, ad_cantidad_personas$statistic),
  P_value = c(ad_edad$p.value, ad_estatura$p.value, ad_cantidad_personas$p.value)
)

# Mostrar los resultados en formato kable
kable(ad_results, caption = "Resultados de la Prueba de Normalidad (Anderson-Darling)", col.names = c("Variable", "Estadístico A", "Valor P")) %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
Resultados de la Prueba de Normalidad (Anderson-Darling)
Variable Estadístico A Valor P
Edad 3487.775 0
Estatura 163264.780 0
Cantidad de Personas 230171.745 0

Implicaciones: -Rechazo de la Normalidad: El valor P igual a 0 sugiere que las diferencias entre los datos y una distribución normal son tan grandes que la probabilidad de que los datos sean normales es extremadamente baja.

Análisis de la distribución normal a través de pruebas gráficas: Histogramas:

# Histograma de Edad
hist_edad <- ggplot(bd, aes(x = Edad..años.)) +
  geom_histogram(aes(y = ..density..), binwidth = 5, color = "black", fill = "lightblue") +
  geom_density(color = "red", size = 1) +  # Curva de densidad
  labs(title = "Distribución de Edad", x = "Edad (años)", y = "Densidad") +
  theme_minimal()
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
# Mostrar el histograma de Edad
hist_edad
## Warning: The dot-dot notation (`..density..`) was deprecated in ggplot2 3.4.0.
## ℹ Please use `after_stat(density)` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

# Histograma de Estatura
hist_estatura <- ggplot(bd, aes(x = Estatura..CM.)) +
  geom_histogram(aes(y = ..density..), binwidth = 5, color = "black", fill = "lightgreen") +
  geom_density(color = "blue", size = 1) +  # Curva de densidad
  labs(title = "Distribución de Estatura", x = "Estatura (cm)", y = "Densidad") +
  theme_minimal()
# Mostrar el histograma de Estatura
hist_estatura

Restringimos el rango del eje X, para visualizar mejor la distribución de los datos sin que los valores extremos distorsionen la escala.

# Histograma de Estatura con ajuste del rango del eje X
hist_estatura <- ggplot(bd, aes(x = Estatura..CM.)) +
  geom_histogram(aes(y = ..density..), binwidth = 5, color = "black", fill = "lightgreen") +
  geom_density(color = "blue", size = 1) +  # Curva de densidad
  labs(title = "Distribución de Estatura", x = "Estatura (cm)", y = "Densidad") +
  xlim(140, 200) +  # Ajustar el rango del eje X
  theme_minimal()

# Mostrar el histograma de Estatura
hist_estatura
## Warning: Removed 504880 rows containing non-finite outside the scale range
## (`stat_bin()`).
## Warning: Removed 504880 rows containing non-finite outside the scale range
## (`stat_density()`).
## Warning: Removed 2 rows containing missing values or values outside the scale range
## (`geom_bar()`).

# Histograma de Cantidad de Personas
hist_cantidad <- ggplot(bd, aes(x = Cantidad.de.personas)) +
  geom_histogram(aes(y = ..density..), binwidth = 1, color = "black", fill = "lightcoral") +
  geom_density(color = "purple", size = 1) +  # Curva de densidad
  labs(title = "Distribución de Cantidad de Personas", x = "Cantidad de Personas", y = "Densidad") +
  theme_minimal()
# Mostrar el histograma de Cantidad de Personas
hist_cantidad

Restringimos el rango del eje X, para visualizar mejor la distribución de los datos sin que los valores extremos distorsionen la escala.

# Histograma de Cantidad de Personas con ajuste del rango del eje X
hist_cantidad <- ggplot(bd, aes(x = Cantidad.de.personas)) +
  geom_histogram(aes(y = ..density..), binwidth = 1, color = "black", fill = "lightcoral") +
  geom_density(color = "purple", size = 1) +  # Curva de densidad
  labs(title = "Distribución de Cantidad de Personas", x = "Cantidad de Personas", y = "Densidad") +
  xlim(0, 10) +  # Ajustar el rango del eje X
  theme_minimal()
# Mostrar el histograma de Cantidad de Personas
hist_cantidad
## Warning: Removed 16334 rows containing non-finite outside the scale range
## (`stat_bin()`).
## Warning: Removed 16334 rows containing non-finite outside the scale range
## (`stat_density()`).
## Warning: Removed 2 rows containing missing values or values outside the scale range
## (`geom_bar()`).

Los histogramas de las variables Edad, Estatura y Cantidad de Personas muestran distribuciones claramente sesgadas, con picos concentrados en los valores bajos y una rápida disminución en la frecuencia. Estos patrones indican que las variables no siguen una distribución normal.

Diagrama Q-Q (Quantile-Quantile):

# Crear los diagramas Q-Q
qq_edad <- ggplot(bd, aes(sample = Edad..años.)) +
  stat_qq() +
  stat_qq_line() +
  labs(title = "Diagrama Q-Q para Edad",
       x = "Cuantiles teóricos",
       y = "Cuantiles de la muestra") +
  theme_minimal()

qq_estatura <- ggplot(bd, aes(sample = Estatura..CM.)) +
  stat_qq() +
  stat_qq_line() +
  labs(title = "Diagrama Q-Q para Estatura",
       x = "Cuantiles teóricos",
       y = "Cuantiles de la muestra") +
  theme_minimal()

qq_cantidad_personas <- ggplot(bd, aes(sample = Cantidad.de.personas)) +
  stat_qq() +
  stat_qq_line() +
  labs(title = "Diagrama Q-Q para Cantidad de Personas",
       x = "Cuantiles teóricos",
       y = "Cuantiles de la muestra") +
  theme_minimal()

# Mostrar los diagramas Q-Q por separado
print(qq_edad)

print(qq_estatura)

print(qq_cantidad_personas)

Observamos como las tres variables presentan desviaciones significativas de la línea recta, lo que indica sesgos o kurtosis en los datos.sugeririendo una distribución no normal.

CATEGÓRICAS/CUALITATIVAS: Para hacer las tabla de frecuencias de las variables categóricas es necesario transformar primero las variables en factor:

pa_factor <- as.factor(bd$País)
pa_summary <- summary(pa_factor)
if (length(pa_summary) > 15) {
  pa_summary <- head(sort(pa_summary, decreasing = TRUE), 15)
}
print(pa_summary)
## ESTADOS UNIDOS         ESPAÑA      VENEZUELA        ECUADOR         CANADA 
##         215007         147742         105125          40791          35378 
##          CHILE      ARGENTINA         MEXICO    REINO UNIDO      AUSTRALIA 
##          24012          18100          17031          17017          16782 
##        FRANCIA         PANAMA         ITALIA         BRASIL     COSTA RICA 
##          16391          14148          12955          12572          10639
# Crear un data frame a partir del resumen de frecuencia
pa_df <- data.frame(País = names(pa_summary), Frecuencia = as.numeric(pa_summary))
# Graficar la tabla de frecuencias usando ggplot2
ggplot(pa_df, aes(x = reorder(País, Frecuencia), y = Frecuencia)) +
  geom_bar(stat = "identity", fill = "skyblue", color = "black") +
  coord_flip() +  # Girar el gráfico para que los nombres se lean más fácilmente
  theme_minimal() +  # Tema limpio y minimalista
  labs(title = "Concentración de colomianos por país", 
       x = "País", 
       y = "Concentración") +
  theme(plot.title = element_text(hjust = 0.5),  # Centrar el título
        axis.text.y = element_text(size = 10),  # Ajustar tamaño de los nombres de los países
        axis.text.x = element_text(size = 10))  # Ajustar tamaño de los valores de frecuencia

cod_factor <- as.factor(bd$Código.ISO.país)
cod_summary <- summary(cod_factor)
if (length(cod_summary) > 15) {
  cod_summary <- head(sort(cod_summary, decreasing = TRUE), 15)
}
print(cod_summary)
##    USA    ESP    VEN    ECU    CAN    CHL    ARG    MEX    GBR    AUS    FRA 
## 215007 147742 105125  40791  35378  24012  18100  17031  17017  16782  16391 
##    PAN    ITA    BRA    CRI 
##  14148  12955  12572  10639
of_factor <- as.factor(bd$Oficina.de.registro)
of_summary <- summary(of_factor)
if (length(of_summary) > 15) {
  of_summary <- head(sort(of_summary, decreasing = TRUE), 15)
}
print(of_summary)
##       C. MADRID        C. MIAMI   C. NUEVA YORK    C. BARCELONA      C. ORLANDO 
##           52771           37197           30079           26862           24034 
##       C. NEWARK    C. MARACAIBO      C. HOUSTON      C. SEVILLA C. BUENOS AIRES 
##           23806           20964           20635           19324           18100 
##      C. CARACAS C. VALENCIA ESP      C. ATLANTA      C. LONDRES        C. PARIS 
##           17802           17586           17148           17142           16448
area_factor <- as.factor(bd$Área.Conocimiento)
area_summary <- summary(area_factor)
if (length(area_summary) > 15) {
  area_summary <- head(sort(area_summary, decreasing = TRUE), 15)
}
print(area_summary)
##                                (NO REGISTRA) 
##                                          713 
##              AGRONOMÍA, VETERINARIA Y AFINES 
##                                         5047 
##           AGRONOMÍA, VETERINARIA Y ZOOTECNIA 
##                                         2725 
##                                     AVIACIÓN 
##                                         1892 
##                                 BELLAS ARTES 
##                                        28818 
##                     CIENCIAS DE LA EDUCACIÓN 
##                                        23230 
##                         CIENCIAS DE LA SALUD 
##                                        60672 
##                  CIENCIAS SOCIALES Y HUMANAS 
##                                        60682 
##                           COCINA Y CULINARIA 
##                                         3588 
## ECONOMÍA, ADMINISTRACIÓN CONTADURIA Y AFINES 
##                                        88555 
##            INGENIERÍA, ARQUITECTURA Y AFINES 
##                                        95939 
##             MATEMÁTICAS Y CIENCIAS NATURALES 
##                                        10962 
##                                      NINGUNA 
##                                       190204 
##                                    NO INDICA 
##                                       209223
suba_factor <- as.factor(bd$Sub.Area.Conocimiento)
sarea_summary <- summary (suba_factor)
if (length(sarea_summary) > 15) {
  sarea_summary <- head(sort(sarea_summary, decreasing = TRUE), 15)
}
print(sarea_summary)
##                                   NO INDICA 
##                                      202404 
##                                     NINGUNA 
##                                      190197 
##                              ADMINISTRACIÓN 
##                                       56023 
##                                   EDUCACIÓN 
##                                       23231 
##                          CONTADURÍA PÚBLICA 
##                                       18436 
## INGENIERÍA EN SISTEMAS, TELEMÁTICA Y AFINES 
##                                       17540 
##                                  ENFERMERÍA 
##                                       16205 
##                                    ECONOMÍA 
##                                       14096 
##                            DERECHO Y AFINES 
##                                       13823 
##              INGENIERÍA INDUSTRIAL Y AFINES 
##                                       13567 
##                                    MEDICINA 
##                                       12796 
##                                      DISEÑO 
##                                       11762 
##                      OTRO PROGRAMA DE SALUD 
##                                       10570 
##                INGENIERÍA MECÁNICA Y AFINES 
##                                        9424 
##    PERIODISMO, COMUNICACIÓN SOCIAL Y AFINES 
##                                        9267
ec_factor <- as.factor(bd$Estado.civil)
ec_summary <- summary(ec_factor)
if (length(ec_summary) > 15) {
  ec_summary <- head(sort(ec_summary, decreasing = TRUE), 15)
}
print(ec_summary)
##               CASADO          DESCONOCIDO           DIVORCIADO 
##               265168                56712                48731 
##  SEPARADO_MATRIMONIO SEPARADO_UNION_LIBRE              SOLTERO 
##                 2042                 1014               325863 
##          UNION_LIBRE                VIUDO 
##                65410                17310
# Crear un data frame con los resultados del resumen de Estado civil
ec_bd <- data.frame(Estado_civil = names(ec_summary), Frecuencia = as.numeric(ec_summary))

# Crear la gráfica
ggplot(ec_bd, aes(x = reorder(Estado_civil, Frecuencia), y = Frecuencia, fill = Estado_civil)) +
  geom_bar(stat = "identity", width = 0.7, color = "white") +
  coord_flip() +  # Cambiar la orientación de la gráfica
  scale_fill_brewer(palette = "Set2") +  # Paleta de colores llamativos
  theme_minimal() +
  scale_y_continuous(labels = comma) +  # Mostrar las frecuencias sin notación científica
  labs(title = "Distribución del Estado Civil",
       x = "Estado Civil",
       y = "Frecuencia",
       fill = "Estado Civil") +
  theme(plot.title = element_text(hjust = 0.5, face = "bold", size = 16),
        axis.text.x = element_text(face = "bold", color = "#4f4f4f"),
        axis.text.y = element_text(face = "bold", color = "#4f4f4f"),
        legend.position = "none")  # Ocultar la leyenda

gen_factor <- as.factor(bd$Género)
gen_summary <- summary(gen_factor)
if (length(gen_summary) > 15) {
  gen_summary <- head(sort(gen_summary, decreasing = TRUE), 15)
}
print(gen_summary)
## DESCONOCIDO    FEMENINO   MASCULINO  NO_BINARIO 
##        1613      430898      349732           7
gen_filtered <- gen_summary[names(gen_summary) != "DESCONOCIDO"]
# Crear un data frame con los resultados del resumen de Género filtrado
gen_df <- data.frame(Género = names(gen_filtered), Frecuencia = as.numeric(gen_filtered))
# Crear la gráfica de torta
ggplot(gen_df, aes(x = "", y = Frecuencia, fill = Género)) +
  geom_bar(width = 1, stat = "identity", color = "white") +
  coord_polar(theta = "y") +  
  scale_fill_brewer(palette = "Pastel1") +  
  theme_void() + 
  labs(title = "Distribución de Género",
       fill = "Género") +
  theme(plot.title = element_text(hjust = 0.5, face = "bold", size = 16)) +
  geom_text(aes(label = ifelse(Género == "NO_BINARIO" & Frecuencia/sum(Frecuencia) < 0.01, "",
                               scales::percent(Frecuencia/sum(Frecuencia), accuracy = 0.1))),
            position = position_stack(vjust = 0.5), size = 4, color = "black")

etnia_factor <- as.factor(bd$Etnia.de.la.persona)
etnia_summary <- summary(etnia_factor)
if (length(etnia_summary) > 15) {
  etnia_summary <- head(sort(etnia_summary, decreasing = TRUE), 15)
}
print(etnia_summary)
##                      AFRODESCENDIENTE                                GITANO 
##                                 17162                                   422 
##                              INDÍGENA                               NINGUNA 
##                                  3503                                394827 
##                                  OTRO             PALENQUERO DE SAN BASILIO 
##                                323110                                   149 
## RAIZAL DEL ARCHIPIELAGO DE SAN ANDRES                  SIN ETNIA REGISTRADA 
##                                   435                                 42642
loca_factor <- as.factor(bd$Localización)
loca_summary <- summary(loca_factor)
if (length(loca_summary) > 15) {
  loca_summary <- head(sort(loca_summary, decreasing = TRUE), 15)
}
print(loca_summary)
##   (37.09024, -95.712891)    (40.463667, -3.74922)     (6.42375, -66.58973) 
##                   215007                   147742                   105125 
##  (-1.831239, -78.183406) (56.130366, -106.346771) (-35.675147, -71.542969) 
##                    40791                    35378                    24012 
## (-38.416097, -63.616672) (23.634501, -102.552784)   (55.378051, -3.435973) 
##                    18100                    17031                    17017 
## (-25.274398, 133.775136)    (46.227638, 2.213749)   (8.537981, -80.782127) 
##                    16782                    16391                    14148 
##     (41.87194, 12.56738)  (-14.235004, -51.92528)   (9.748917, -83.753428) 
##                    12955                    12572                    10639
gedad_factor <- as.factor(bd$Grupo.edad)
gedad_summary <- summary(gedad_factor)
if (length(gedad_summary) > 15) {
  gedad_summary <- head(sort(gedad_summary, decreasing = TRUE), 15)
}
print(gedad_summary)
##      ADOLESCENTE           ADULTO     ADULTO JOVEN     ADULTO MAYOR 
##             9780           533179            68714           159445 
##      DESCONOCIDO          INFANTE PRIMERA INFANCIA 
##             1018             7238             2876
naca_factor <- as.factor(bd$Nivel.Académico)
naca_summary <- summary(naca_factor)
if (length(naca_summary) > 15) {
  naca_summary <- head(sort(naca_summary, decreasing = TRUE), 15)
}
print(naca_summary)
##                  (NO REGISTRA)                   BACHILLERATO 
##                            713                         148056 
##                        NINGUNO                      NO INDICA 
##                          17062                         271466 
##          POSTGRADO - DOCTORADO    POSTGRADO - ESPECIALIZACIÓN 
##                           7468                          20619 
##           POSTGRADO - MAESTRIA         PREGRADO - PROFESIONAL 
##                          32865                         137517 
## PREGRADO - TÉCNICO PROFESIONAL         PREGRADO - TECNOLÓGICO 
##                          52792                          28101 
##                       PRIMARIA                  SIN PROFESIÓN 
##                          65411                            180
naca_filtered <- naca_summary[names(naca_summary) != "(NO REGISTRA)"]
naca_df <- data.frame(NivelAcadémico = names(naca_filtered), Frecuencia = as.numeric(naca_filtered))

# Crear la gráfica de barras
ggplot(naca_df, aes(x = reorder(NivelAcadémico, -Frecuencia), y = Frecuencia, fill = NivelAcadémico)) +
  geom_bar(stat = "identity", color = "black", width = 0.7) +
  scale_fill_brewer(palette = "Paired") +  # Usar una paleta vibrante
  labs(title = "Distribución del Nivel Académico",
       x = "Nivel Académico",
       y = "Frecuencia") +
  geom_text(aes(label = Frecuencia), vjust = -0.3, color = "black", size = 4.5) +  # Añadir etiquetas de frecuencia
  scale_y_continuous(labels = comma) +
  theme_minimal(base_size = 15) +  # Tema minimalista con tamaño de texto ajustado
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold", size = 18),  # Centrar y aumentar el tamaño del título
    axis.title.x = element_text(face = "bold", size = 14),
    axis.title.y = element_text(face = "bold", size = 14),
    axis.text.x = element_text(angle = 30, hjust = 1, size = 8),  # Girar etiquetas del eje X a 45 grados
    legend.position = "none",  # Quitar la leyenda
    plot.margin = margin(t = 20, r = 20, b = 20, l = 20, unit = "pt")  # Ajustar los márgenes
  )+
  coord_cartesian(clip = "off")  # Evitar que las etiquetas se corten

4. Aplicación de filtros:

fbd1 <- bd %>% filter(`País` %in% c("CANADA", "FRANCIA", "ALEMANIA", "ITALIA", "JAPON", "REINO UNIDO", "ESTADOS UNIDOS"))
ggplot(fbd1, aes(x = `País`)) +
  geom_bar(aes(fill = `País`), color = "black", width = 0.7) +
  scale_fill_brewer(palette = "Set1") +  # Usar una paleta vibrante como "Set1"
  labs(title = "Concentración de Colombianos en Países del G7",
       x = "País",
       y = "Cantidad") +
  geom_text(stat='count', aes(label=..count..), vjust=-0.5, color="black", size=4.5) +  # Añadir etiquetas
  theme_minimal(base_size = 15) +  # Tema minimalista con tamaño de texto ajustado
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold", size = 18),  # Centrar y aumentar el tamaño del título
    axis.title.x = element_text(face = "bold", size = 14),
    axis.title.y = element_text(face = "bold", size = 14),
    legend.position = "none",  # Quitar la leyenda
    axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1),  # Girar etiquetas del eje X a 45 grados
    plot.margin = margin(t = 20, r = 20, b = 30, l = 20, unit = "pt")  # Aumentar los márgenes superior e inferior
  ) +
  coord_cartesian(clip = "off")  # Evitar que las etiquetas de las barras se corten

fbd5 <- bd %>% filter(`País` %in% c(
  "ARGENTINA", "BOLIVIA", "BRASIL", "CHILE", "ECUADOR",
  "GUYANA", "PARAGUAY", "PERÚ", "SURINAM", "URUGUAY", "VENEZUELA",
  "BELICE", "COSTA RICA", "EL SALVADOR", "GUATEMALA", "HONDURAS",
  "NICARAGUA", "PANAMÁ", "ANTIGUA Y BARBUDA", "BAHAMAS", "BARBADOS",
  "CUBA", "DOMINICA", "GRANADA", "HAITÍ", "JAMAICA",
  "REPÚBLICA DOMINICANA", "SAINT KITTS Y NEVIS", "SANTA LUCÍA",
  "SAN VICENTE Y LAS GRANADINAS", "TRINIDAD Y TOBAGO"
))
# Contar la cantidad de colombianos por país
fbd5_count <- fbd5 %>%
  count(`País`) %>%
  arrange(desc(n))

# Crear la gráfica
ggplot(fbd5_count, aes(x = reorder(`País`, -n), y = n)) +
  geom_bar(stat = "identity", fill = "steelblue", color = "black", width = 0.7) +  # Color único para las barras
  labs(title = "Concentración de Colombianos en Latinoamérica",
       x = "País",
       y = "Cantidad de Colombianos") +
  theme_minimal() +
  theme(
    axis.text.x = element_text(angle = 60, hjust = 1, vjust = 1, size = 8),
    plot.title = element_text(hjust = 0.5, face = "bold", size = 16),
    axis.title.x = element_text(face = "bold", size = 14),
    axis.title.y = element_text(face = "bold", size = 10),
    legend.position = "none",  # Quitar la leyenda
    plot.margin = margin(t = 10, r = 10, b = 10, l = 10)  # Ajustar márgenes
  ) +
  scale_y_continuous(expand = expansion(mult = c(0, 0.1))) 

# Filtrar datos para el rango de edad entre 20 y 35 años
fbd2_20_35 <- bd %>% filter(`Edad..años.` >= 20 & `Edad..años.` <= 35)
# Contar las frecuencias por estado civil
fbd2_20_35_count <- fbd2_20_35 %>%
  count(`Estado.civil`) %>%
  arrange(desc(n))

# Crear la gráfica
ggplot(fbd2_20_35_count, aes(x = reorder(`Estado.civil`, -n), y = n, fill = `Estado.civil`)) +
  geom_bar(stat = "identity", color = "black") +  # Colorear las barras por estado civil
  labs(title = "Estado Civil de Adultos (20-35 años)",
       x = "Estado Civil",
       y = "Cantidad de Personas") +
  theme_minimal() +
  theme(
    axis.text.x = element_blank(),  # Quitar etiquetas del eje X
    axis.title.x = element_blank(),  # Quitar título del eje X
    plot.title = element_text(hjust = 0.5, face = "bold", size = 16),
    axis.title.y = element_text(face = "bold", size = 14),
    legend.position = "right",  # Mantener la leyenda a la derecha
    plot.margin = margin(t = 10, r = 20, b = 10, l = 10)  # Ajustar márgenes para dar espacio a la leyenda
  ) +
  scale_fill_brewer(palette = "Set3") +  # Usar una paleta de colores con suficiente contraste
  scale_y_continuous(labels = scales::comma) 

#Estado civil en Colombianos inmigrantes adultos a partir de los 45+
fbd2<- bd %>%filter(`Edad..años.`>= 45)
fbd2_count <- fbd2 %>%
  count(`Estado.civil`) %>%
  arrange(desc(n))


# Crear la gráfica
ggplot(fbd2_count, aes(x = reorder(`Estado.civil`, -n), y = n, fill = `Estado.civil`)) +
  geom_bar(stat = "identity", color = "black") +  # Colorear las barras por estado civil
  labs(title = "Estado Civil de Adultos (45+)",
       x = "Estado Civil",
       y = "Cantidad de Personas") +
  theme_minimal() +
  theme(
    axis.text.x = element_blank(),  # Quitar etiquetas del eje X
    axis.title.x = element_blank(),  # Quitar título del eje X
    plot.title = element_text(hjust = 0.5, face = "bold", size = 16),
    axis.title.y = element_text(face = "bold", size = 14),
    legend.position = "right",  # Mantener la leyenda a la derecha
    plot.margin = margin(t = 10, r = 20, b = 10, l = 10)  # Ajustar márgenes para dar espacio a la leyenda
  ) +
  scale_fill_brewer(palette = "Set3") +  # Usar una paleta de colores con suficiente contraste
  scale_y_continuous(labels = scales::comma)

# Filtrar los 8 países con mayor concentración de colombianos
top_paises <- c("ESTADOS UNIDOS", "ESPAÑA", "VENEZUELA", "ECUADOR", "CANADA", "CHILE", "ARGENTINA", "MEXICO")

fbd_filtered <- bd %>%
  filter(`País` %in% top_paises)

# Filtrar el nivel académico más predominante, excluyendo "NO INDICA"
fbd_filtered <- fbd_filtered %>%
  filter(`Nivel.Académico` != "NO INDICA") %>%
  count(`País`, `Nivel.Académico`) %>%
  group_by(`País`) %>%
  slice_max(n, n = 1) %>%
  ungroup()

# Crear el gráfico
ggplot(fbd_filtered, aes(x = reorder(`País`, -n), y = n, fill = `Nivel.Académico`)) +
  geom_bar(stat = "identity") +
  labs(title = "Nivel Académico predominante por país",
       x = "País",
       y = "Cantidad de Colombianos") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, size = 10),
        plot.title = element_text(hjust = 0.5, face = "bold", size = 16),
        axis.title.x = element_text(face = "bold", size = 10),
        axis.title.y = element_text(face = "bold", size = 10)) +
  scale_fill_brewer(palette = "Set3") 

areas_interes <- c("INGENIERÍA, ARQUITECTURA Y AFINES", "ECONOMÍA, ADMINISTRACIÓN CONTADURIA Y AFINES", 
                    "CIENCIAS SOCIALES Y HUMANAS", "CIENCIAS DE LA SALUD", "CIENCIAS DE LA EDUCACIÓN", 
                    "BELLAS ARTES")

generos_interes <- c("MASCULINO", "FEMENINO")

bd_filtered_areas_generos <- bd %>%
  filter(`Área.Conocimiento` %in% areas_interes, `Género` %in% generos_interes) %>%
  count(`Área.Conocimiento`, `Género`)

# Crear el gráfico
ggplot(bd_filtered_areas_generos, aes(x = `Área.Conocimiento`, y = n, fill = `Género`)) +
  geom_bar(stat = "identity", position = "stack") +
  labs(title = "Área de Conocimiento y Género",
       x = "Área de Conocimiento",
       y = "Cantidad de Colombianos") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, size = 10),
        plot.title = element_text(hjust = 0.5, face = "bold", size = 16),
        axis.title.x = element_text(face = "bold", size = 14),
        axis.title.y = element_text(face = "bold", size = 14)) +
  scale_fill_viridis_d(option = "plasma") +  # Paleta de colores para distinguir géneros
  coord_flip()

##5. Exploración de la base de datos con la función table:: En este inciso, aplicaré la función table de manera diferente, enfocándome en las frecuencias combinadas para analizar las variables numéricas a través de tablas. Este enfoque me permitirá explorar las relaciones entre las variables categóricas y las numéricas en el conjunto de datos.

PAÍS:

freq_table <- table(bd$País)
# Este bloque de código se aplica para las variables extensas, mostrando solo una cantidad máxima de 15 categorías con mayor frecuencia
if (length(freq_table) > 15) {
  freq_table <- head(sort(freq_table, decreasing = TRUE), 15)
}
print(freq_table)
## 
## ESTADOS UNIDOS         ESPAÑA      VENEZUELA        ECUADOR         CANADA 
##         215007         147742         105125          40791          35378 
##          CHILE      ARGENTINA         MEXICO    REINO UNIDO      AUSTRALIA 
##          24012          18100          17031          17017          16782 
##        FRANCIA         PANAMA         ITALIA         BRASIL     COSTA RICA 
##          16391          14148          12955          12572          10639

CÓDIGO ISO:

freq_table <- table(bd$Código.ISO.país)
# Este bloque de código se aplica para las variables extensas, mostrando solo una cantidad máxima de 15 categorías con mayor frecuencia
if (length(freq_table) > 15) {
  freq_table <- head(sort(freq_table, decreasing = TRUE), 15)
}
print(freq_table)
## 
##    USA    ESP    VEN    ECU    CAN    CHL    ARG    MEX    GBR    AUS    FRA 
## 215007 147742 105125  40791  35378  24012  18100  17031  17017  16782  16391 
##    PAN    ITA    BRA    CRI 
##  14148  12955  12572  10639

OFICINA DE REGISTRO:

freq_table <- table(bd$Oficina.de.registro)
# Este bloque de código se aplica para las variables extensas, mostrando solo una cantidad máxima de 15 categorías con mayor frecuencia
if (length(freq_table) > 15) {
  freq_table <- head(sort(freq_table, decreasing = TRUE), 15)
}
print(freq_table)
## 
##       C. MADRID        C. MIAMI   C. NUEVA YORK    C. BARCELONA      C. ORLANDO 
##           52771           37197           30079           26862           24034 
##       C. NEWARK    C. MARACAIBO      C. HOUSTON      C. SEVILLA C. BUENOS AIRES 
##           23806           20964           20635           19324           18100 
##      C. CARACAS C. VALENCIA ESP      C. ATLANTA      C. LONDRES        C. PARIS 
##           17802           17586           17148           17142           16448

ÁREA DE CONOCIMIENTO:

freq_table <- table(bd$Área.Conocimiento)
# Este bloque de código se aplica para las variables extensas, mostrando solo una cantidad máxima de 15 categorías con mayor frecuencia
if (length(freq_table) > 15) {
  freq_table <- head(sort(freq_table, decreasing = TRUE), 15)
}
print(freq_table)
## 
##                                (NO REGISTRA) 
##                                          713 
##              AGRONOMÍA, VETERINARIA Y AFINES 
##                                         5047 
##           AGRONOMÍA, VETERINARIA Y ZOOTECNIA 
##                                         2725 
##                                     AVIACIÓN 
##                                         1892 
##                                 BELLAS ARTES 
##                                        28818 
##                     CIENCIAS DE LA EDUCACIÓN 
##                                        23230 
##                         CIENCIAS DE LA SALUD 
##                                        60672 
##                  CIENCIAS SOCIALES Y HUMANAS 
##                                        60682 
##                           COCINA Y CULINARIA 
##                                         3588 
## ECONOMÍA, ADMINISTRACIÓN CONTADURIA Y AFINES 
##                                        88555 
##            INGENIERÍA, ARQUITECTURA Y AFINES 
##                                        95939 
##             MATEMÁTICAS Y CIENCIAS NATURALES 
##                                        10962 
##                                      NINGUNA 
##                                       190204 
##                                    NO INDICA 
##                                       209223

SUB-ÁREA:

freq_table <- table(bd$Sub.Area.Conocimiento)
# Este bloque de código se aplica para las variables extensas, mostrando solo una cantidad máxima de 15 categorías con mayor frecuencia
if (length(freq_table) > 15) {
  freq_table <- head(sort(freq_table, decreasing = TRUE), 15)
}
print(freq_table)
## 
##                                   NO INDICA 
##                                      202404 
##                                     NINGUNA 
##                                      190197 
##                              ADMINISTRACIÓN 
##                                       56023 
##                                   EDUCACIÓN 
##                                       23231 
##                          CONTADURÍA PÚBLICA 
##                                       18436 
## INGENIERÍA EN SISTEMAS, TELEMÁTICA Y AFINES 
##                                       17540 
##                                  ENFERMERÍA 
##                                       16205 
##                                    ECONOMÍA 
##                                       14096 
##                            DERECHO Y AFINES 
##                                       13823 
##              INGENIERÍA INDUSTRIAL Y AFINES 
##                                       13567 
##                                    MEDICINA 
##                                       12796 
##                                      DISEÑO 
##                                       11762 
##                      OTRO PROGRAMA DE SALUD 
##                                       10570 
##                INGENIERÍA MECÁNICA Y AFINES 
##                                        9424 
##    PERIODISMO, COMUNICACIÓN SOCIAL Y AFINES 
##                                        9267

ESTADO CIVIL:

table(bd$Estado.civil)
## 
##               CASADO          DESCONOCIDO           DIVORCIADO 
##               265168                56712                48731 
##  SEPARADO_MATRIMONIO SEPARADO_UNION_LIBRE              SOLTERO 
##                 2042                 1014               325863 
##          UNION_LIBRE                VIUDO 
##                65410                17310

GÉNERO:

table(bd$Género)
## 
## DESCONOCIDO    FEMENINO   MASCULINO  NO_BINARIO 
##        1613      430898      349732           7

ETNIA:

table(bd$Etnia.de.la.persona)
## 
##                      AFRODESCENDIENTE                                GITANO 
##                                 17162                                   422 
##                              INDÍGENA                               NINGUNA 
##                                  3503                                394827 
##                                  OTRO             PALENQUERO DE SAN BASILIO 
##                                323110                                   149 
## RAIZAL DEL ARCHIPIELAGO DE SAN ANDRES                  SIN ETNIA REGISTRADA 
##                                   435                                 42642

LOCALIZACIÓN:

freq_table <- table(bd$Localización)
# Este bloque de código se aplica para las variables extensas, mostrando solo una cantidad máxima de 15 categorías con mayor frecuencia
if (length(freq_table) > 15) {
  freq_table <- head(sort(freq_table, decreasing = TRUE), 15)
}
print(freq_table)
## 
##   (37.09024, -95.712891)    (40.463667, -3.74922)     (6.42375, -66.58973) 
##                   215007                   147742                   105125 
##  (-1.831239, -78.183406) (56.130366, -106.346771) (-35.675147, -71.542969) 
##                    40791                    35378                    24012 
## (-38.416097, -63.616672) (23.634501, -102.552784)   (55.378051, -3.435973) 
##                    18100                    17031                    17017 
## (-25.274398, 133.775136)    (46.227638, 2.213749)   (8.537981, -80.782127) 
##                    16782                    16391                    14148 
##     (41.87194, 12.56738)  (-14.235004, -51.92528)   (9.748917, -83.753428) 
##                    12955                    12572                    10639

GRUPO EDAD:

table(bd$Grupo.edad)
## 
##      ADOLESCENTE           ADULTO     ADULTO JOVEN     ADULTO MAYOR 
##             9780           533179            68714           159445 
##      DESCONOCIDO          INFANTE PRIMERA INFANCIA 
##             1018             7238             2876

NIVEL ACADÉMICO:

table(bd$Nivel.Académico)
## 
##                  (NO REGISTRA)                   BACHILLERATO 
##                            713                         148056 
##                        NINGUNO                      NO INDICA 
##                          17062                         271466 
##          POSTGRADO - DOCTORADO    POSTGRADO - ESPECIALIZACIÓN 
##                           7468                          20619 
##           POSTGRADO - MAESTRIA         PREGRADO - PROFESIONAL 
##                          32865                         137517 
## PREGRADO - TÉCNICO PROFESIONAL         PREGRADO - TECNOLÓGICO 
##                          52792                          28101 
##                       PRIMARIA                  SIN PROFESIÓN 
##                          65411                            180

EDAD(AÑOS):

freq_table <- table(bd$Edad..años.)
# Este bloque de código se aplica para las variables extensas, mostrando solo una cantidad máxima de 15 categorías con mayor frecuencia
if (length(freq_table) > 15) {
  freq_table <- head(sort(freq_table, decreasing = TRUE), 15)
}
print(freq_table)
## 
##    35    39    38    37    34    36    40    42    41    43    44    33    45 
## 21054 20832 20600 20529 20305 20259 20247 20207 19998 19983 19899 19858 19184 
##    32    31 
## 19120 18044

ESTATURA(CM):

freq_table <- table(bd$Estatura..CM.)
# Este bloque de código se aplica para las variables extensas, mostrando solo una cantidad máxima de 15 categorías con mayor frecuencia
if (length(freq_table) > 15) {
  freq_table <- head(sort(freq_table, decreasing = TRUE), 15)
}
print(freq_table)
## 
##     -1    160    170    165    155    168    175    158    163    162    167 
## 499997  23751  19815  19769  12247  12052  11034  10204   9948   9909   9289 
##    172    164    156    157 
##   8537   8127   7686   7576

CANTIDAD DE PERSONAS:

freq_table <- table(bd$Cantidad.de.personas)
# Este bloque de código se aplica para las variables extensas, mostrando solo una cantidad máxima de 15 categorías con mayor frecuencia
if (length(freq_table) > 15) {
  freq_table <- head(sort(freq_table, decreasing = TRUE), 15)
}
print(freq_table)
## 
##      1      2      3      4      5      6      7      8      9     10     11 
## 625801  76474  26222  13354   7887   5465   3775   2856   2275   1807   1545 
##     12     13     14     15 
##   1278   1134    936    779

6. Valores NA (Not Available) en la base de datos:

Antes de poderidentificar los datos NA´s se modifican el formato de algunas variables para que sigan un mismo lineamiento:

# Reemplazar "NO REGISTRA" con NA en cada columna individualmente

# País
bd$País[bd$País == "NO REGISTRA"] <- NA
# Código ISO país
bd$Código.ISO.país[bd$Código.ISO.país == "NO REGISTRA"] <- NA
# Oficina de registro
bd$Oficina.de.registro[bd$Oficina.de.registro == "NO REGISTRA"] <- NA
# Área de conocimiento
bd$Área.Conocimiento[bd$Área.Conocimiento == "NO REGISTRA"] <- NA
# Sub área de conocimiento
bd$Sub.Area.Conocimiento[bd$Sub.Area.Conocimiento == "NO REGISTRA"] <- NA
# Nivel académico
bd$Nivel.Académico[bd$Nivel.académico == "NO REGISTRA"] <- NA
# Estado civil
bd$Estado.civil[bd$Estado.civil == "NO REGISTRA"] <- NA
# Etnia de la persona
bd$Etnia.de.la.persona[bd$Etnia.de.la.persona == "NO REGISTRA"] <- NA
# Reemplazar "DESCONOCIDO" con NA en Grupo edad y Género
# Grupo edad
bd$Grupo.edad[bd$Grupo.edad == "DESCONOCIDO"] <- NA
# Género
bd$Género[bd$Género == "DESCONOCIDO"] <- NA
# Reemplazar "-1" con NA en Edad y Estatura
# Edad
bd$Edad..años.[bd$Edad..años. == -1] <- NA
# Estatura
bd$Estatura..CM.[bd$Estatura..CM. == -1] <- NA

Ahora sí podemos identificar los valores NA:

#Identificar cantidad de valores NA en la base de datos
total_na <- sum(is.na(bd))
cat("Cantidad total de valores NA en la base de datos:", total_na, "\n")
## Cantidad total de valores NA en la base de datos: 503646
#Identificar la cantidad de valores NA por cada columna
na_por_columna <- colSums(is.na(bd))
cat("Cantidad de valores NA por columna:\n")
## Cantidad de valores NA por columna:
print(na_por_columna)
##                  País       Código.ISO.país   Oficina.de.registro 
##                     0                     0                     0 
##            Grupo.edad           Edad..años.     Área.Conocimiento 
##                  1018                  1018                     0 
## Sub.Area.Conocimiento       Nivel.Académico          Estado.civil 
##                     0                     0                     0 
##                Género   Etnia.de.la.persona         Estatura..CM. 
##                  1613                     0                499997 
##          Localización  Cantidad.de.personas 
##                     0                     0
#Identificar columnas que contienen valores NA
columnas_con_na <- names(na_por_columna[na_por_columna > 0])
cat("Columnas que contienen valores NA:", paste(columnas_con_na, collapse = ", "), "\n")
## Columnas que contienen valores NA: Grupo.edad, Edad..años., Género, Estatura..CM.

Ahora, creamos un gráficoque nos permita visualizar los valores faltantes(NA):

# Cargar la librería Amelia
suppressWarnings(require(Amelia))

# Crear el gráfico de missmap 
suppressWarnings(missmap(bd))

#7. Analisis de posibles valores atípicos:

Caracterización:

#Función para contar valores atípicos
contar_atipicos <- function(x) {
  iqr <- IQR(x, na.rm = TRUE)
  cuartil1 <- quantile(x, 0.25, na.rm = TRUE)
  cuartil3 <- quantile(x, 0.75, na.rm = TRUE)
  lim_inferior <- cuartil1 - 1.5 * iqr
  lim_superior <- cuartil3 + 1.5 * iqr
  atipicos <- x[x < lim_inferior | x > lim_superior]
  return(length(atipicos))
}

#Contar valores atípicos para cada variable numérica
num_edad <- contar_atipicos(bd$Edad..años.)
num_esta <- contar_atipicos(bd$Estatura..CM.)
num_cp <- contar_atipicos(bd$Cantidad.de.personas)

cat("Cantidad de valores atípicos en la variables Edad es:", num_edad, "\n")
## Cantidad de valores atípicos en la variables Edad es: 4525
cat("Cantidad de valores atípicos en la variable Estatura es:", num_esta, "\n")
## Cantidad de valores atípicos en la variable Estatura es: 505470
cat("Cantidad de valores atípicos en la variables cantidad de personas es:", num_cp, "\n")
## Cantidad de valores atípicos en la variables cantidad de personas es: 156449

A continuación se manejan los valores atípicos, y se visualizan las distribuciones de tres variables específicas(numéricas) a través de diagramas de caja (boxplots).

require(dplyr)
        
        # Visualizar los boxplots
        par(mfrow=c(1,3))
        boxplot(bd$Edad..años., main="Edad(años)")
        boxplot(bd$Estatura..CM., main="Estatura(CM)")
        boxplot(bd$Cantidad.de.personas, main="Cantidad de personas")

Observamos como los tres gráficos evidencian valores atípicos muy altos que deben ser procesados.

Ahora, reemplazamos los valores atípicos por valores NA (lo cual es equivalente a eliminarlos):

        # Reemplazar valores atípicos con NA
        bd$Edad..años.[bd$Edad..años. > 90] <- NA
        bd$Estatura..CM.[bd$Estatura..CM. > 200] <- NA
        bd$Estatura..CM.[bd$Estatura..CM. < 40] <- NA
        bd$Cantidad.de.personas[bd$Cantidad.de.personas > 8 ] <- NA
        # Repetimos los boxplots
        par(mfrow=c(1,3))
        boxplot(bd$Edad..años., main="Edad(años)")
        boxplot(bd$Estatura..CM., main="Estatura(CM)")
        boxplot(bd$Cantidad.de.personas, main="Cantidad de personas")

Debido a que las variables analizadas no siguen una distribución normal, los valores atípicos fueron identificados y posteriormente imputados utilizando la mediana de cada variable, con el fin de reducir el sesgo en los análisis subsecuentes. La mediana es una opción robusta para reemplazar los valores faltantes, ya que no se ve afectada por valores extremos y proporciona una representación central de los datos.

bd$Edad..años.[is.na(bd$Edad..años.)] <- median(bd$Edad..años., na.rm = TRUE)
bd$Estatura..CM.[is.na(bd$Estatura..CM.)] <- median(bd$Estatura..CM., na.rm = TRUE)
bd$Cantidad.de.personas[is.na(bd$Cantidad.de.personas)] <- median(bd$Cantidad.de.personas, na.rm = TRUE)

Finalmente se realiza el esquema de los Datos y se verifica que no se encuentren NAS:

# Cargar el paquete Amelia
suppressWarnings(library(Amelia))
# Crear el gráfico de missmap
suppressWarnings(missmap(bd))