source("C:/Users/user/Downloads/funciones.R")

Descripción General

La base de datos otorgada por el Estado colombiano contiene información sobre la entrada de extranjeros a Colombia desde el año 2012 hasta 2023. Recolectando datos como el sexo, diviendose en masculino, femenino e indefinido; año y mes en el que entraron; nacionalidad, junto con el código ISO; y la totalidad. La última actualización fue el 30 de agosto de 2023.

Las variables son:

  1. Año: Representa el año en el cual se registro la entrada de extranjeros a Colombia.

  2. Mes: Especifica el mes del año en que se registraron las entradas.

  3. Nacionalidad: Indica el país de origen del extranjero que ingresó a Colombia.

  4. Codigo Iso 3166: Muestra el estándar internacional de códigos de cada país.

  5. Femenino: Registra el número de entradas de extranjeros mujeres a Colombia.

  6. Masculino: Registra el número de entradas de extranjeros hombres a Colombia.

  7. Indefinido: Registra el número de entradas de extranjeros cuyo género no se ajusta a las categorías tradicionales.

  8. Total: Especifica el número total de entradas de extranjeros a Colombia, sumando las categorías de género femenina, masculino e indefinido.

  9. Latitud - Longitud: Contiene las coordenadas geográficas asociadas al país de origen de los extranjeros.

summary(Base) #Resumen general de la base de datos.
##       Año           Mes            Nacionalidad       Codigo Iso 3166
##  Min.   :2012   Length:135040      Length:135040      Min.   :    0  
##  1st Qu.:2014   Class :character   Class :character   1st Qu.:  208  
##  Median :2017   Mode  :character   Mode  :character   Median :  392  
##  Mean   :2017                                         Mean   : 1182  
##  3rd Qu.:2020                                         3rd Qu.:  643  
##  Max.   :2023                                         Max.   :99999  
##     Femenino          Masculino       Indefinido         Total      
##  Min.   :    0.00   Min.   :    0.0   Mode:logical   Min.   :    1  
##  1st Qu.:    0.00   1st Qu.:    1.0   NA's:135040    1st Qu.:    2  
##  Median :    2.00   Median :    3.0                  Median :    5  
##  Mean   :   93.86   Mean   :  130.1                  Mean   :  224  
##  3rd Qu.:    9.00   3rd Qu.:   17.0                  3rd Qu.:   26  
##  Max.   :39500.00   Max.   :48041.0                  Max.   :82609  
##  Latitud - Longitud
##  Length:135040     
##  Class :character  
##  Mode  :character  
##                    
##                    
## 

Características generales

La dimensión de la base de datos es:

dim(Base)
## [1] 135040      9

La base de datos tiene 9 columnas y 135.040 filas.

El nombre de las variables son:

colnames(Base) #Nombre de las variables
## [1] "Año"                "Mes"                "Nacionalidad"      
## [4] "Codigo Iso 3166"    "Femenino"           "Masculino"         
## [7] "Indefinido"         "Total"              "Latitud - Longitud"
clasificacion_variables(Base)
##                                 Año                                 Mes 
##               "Año es cuantitativa"                "Mes es cualitativa" 
##                        Nacionalidad                     Codigo Iso 3166 
##       "Nacionalidad es cualitativa"   "Codigo Iso 3166 es cuantitativa" 
##                            Femenino                           Masculino 
##          "Femenino es cuantitativa"         "Masculino es cuantitativa" 
##                          Indefinido                               Total 
##           "Indefinido es otro tipo"             "Total es cuantitativa" 
##                  Latitud - Longitud 
## "Latitud - Longitud es cualitativa"
library(dplyr)
## 
## Adjuntando el paquete: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(kableExtra)
## 
## Adjuntando el paquete: 'kableExtra'
## The following object is masked from 'package:dplyr':
## 
##     group_rows
kable(Base[1:10, ], caption= "Tabla 1: Entrada de Extranjeros en Colombia") %>% 
  kable_styling(full_width = F) %>% 
  column_spec(2, width = "10em") %>%
  scroll_box(width = "900px", height = "450px")
Tabla 1: Entrada de Extranjeros en Colombia
Año Mes Nacionalidad Codigo Iso 3166 Femenino Masculino Indefinido Total Latitud - Longitud
2012 Enero Islas Alboran y Perejil 99999 1 0 NA 1 (4.697144,-74.140516)
2012 Enero Albania 8 1 2 NA 3 (4.697144,-74.140516)
2012 Enero Alemania 276 11 16 NA 27 (-4.197703,-69.941278)
2012 Enero Alemania 276 1 1 NA 2 (0.25129,-76.875963)
2012 Enero Alemania 276 63 102 NA 165 (0.814836,-77.662532)
2012 Enero Alemania 276 22 23 NA 45 (10.408582,-75.538003)
2012 Enero Alemania 276 27 48 NA 75 (10.445761,-75.516429)
2012 Enero Alemania 276 7 4 NA 11 (10.886611,-74.776708)
2012 Enero Alemania 276 1 1 NA 2 (11.247723,-74.213989)
2012 Enero Alemania 276 8 21 NA 29 (11.360009,-72.129330)

Tipos de variable

A continuación, clasificaremos las variables por númericas, catégoricas y lógicas.

library(dplyr)
variables_num <- Base %>% select_if(is.numeric) #Seleccionamos nada más las de tipo númericas.
print(head(variables_num))
## # A tibble: 6 × 5
##     Año `Codigo Iso 3166` Femenino Masculino Total
##   <dbl>             <dbl>    <dbl>     <dbl> <dbl>
## 1  2012             99999        1         0     1
## 2  2012                 8        1         2     3
## 3  2012               276       11        16    27
## 4  2012               276        1         1     2
## 5  2012               276       63       102   165
## 6  2012               276       22        23    45
library(dplyr)
variables_cate <- Base %>% select_if(is.character) #Seleccionamos nada más las de tipo catégoricas.
print(head(variables_cate))
## # A tibble: 6 × 3
##   Mes   Nacionalidad            `Latitud - Longitud`  
##   <chr> <chr>                   <chr>                 
## 1 Enero Islas Alboran y Perejil (4.697144,-74.140516) 
## 2 Enero Albania                 (4.697144,-74.140516) 
## 3 Enero Alemania                (-4.197703,-69.941278)
## 4 Enero Alemania                (0.25129,-76.875963)  
## 5 Enero Alemania                (0.814836,-77.662532) 
## 6 Enero Alemania                (10.408582,-75.538003)
library(dplyr)
variables_logi <- Base %>% select_if(is.logical) #Seleccionamos nada más las de tipo lógicas.
print(head(variables_logi))
## # A tibble: 6 × 1
##   Indefinido
##   <lgl>     
## 1 NA        
## 2 NA        
## 3 NA        
## 4 NA        
## 5 NA        
## 6 NA

Consideremos el resumen individual de las variables númericas con la función summary:

variables_num <- Base %>% select_if(is.numeric)
for (columna in colnames(variables_num)){
  print(paste("Summary para variable", columna))
  print(summary(variables_num[[columna]]))
  cat("\n")
}
## [1] "Summary para variable Año"
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    2012    2014    2017    2017    2020    2023 
## 
## [1] "Summary para variable Codigo Iso 3166"
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##       0     208     392    1182     643   99999 
## 
## [1] "Summary para variable Femenino"
##     Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
##     0.00     0.00     2.00    93.86     9.00 39500.00 
## 
## [1] "Summary para variable Masculino"
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##     0.0     1.0     3.0   130.1    17.0 48041.0 
## 
## [1] "Summary para variable Total"
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##       1       2       5     224      26   82609

Consideremos el resumen individual de las variables catégoricas con la función summary:

library(dplyr)
variables_cate <- Base %>% select_if(is.character)

# Iterar sobre cada columna categórica
for (columna in colnames(variables_cate)) {
  print(paste("Summary para variable", columna))
  
  # Convertir la columna a factor
  factor <- as.factor(variables_cate[[columna]])
  
  # Imprimir el resumen para la variable categórica
  print(summary(factor)[1:12])
  
  cat("\n")
}
## [1] "Summary para variable Mes"
##      Abril     Agosto  Diciembre      Enero    Febrero      Julio      Junio 
##      11245      10352      11597      12603      12239      10555      11181 
##      Marzo       Mayo  Noviembre    Octubre Septiembre 
##      12245      11158      11108      10543      10214 
## 
## [1] "Summary para variable Nacionalidad"
##                                       Venezuela 
##                                            3094 
##                       Estados Unidos de América 
##                                            3045 
##                                          España 
##                                            2925 
## Reino Unido de Gran Bretaña e Irlanda del Norte 
##                                            2738 
##                                    Países Bajos 
##                                            2704 
##                                         Ecuador 
##                                            2678 
##                                            Perú 
##                                            2652 
##                                         Francia 
##                                            2531 
##                                          Italia 
##                                            2522 
##                                        Alemania 
##                                            2498 
##                                          México 
##                                            2491 
##                                       Argentina 
##                                            2414 
## 
## [1] "Summary para variable Latitud - Longitud"
## (-0.193180,-74.784874) (-3.790089,-70.356599) (-4.197703,-69.941278) 
##                    132                     14                   4356 
## (-4.223468,-69.945098)   (0.25129,-76.875963)  (0.812436,-77.847006) 
##                   1661                   2299                    166 
##  (0.814836,-77.662532)  (1.397318,-77.290564)  (1.812361,-78.751529) 
##                   7799                      2                      2 
##  (1.813928,-78.763924) (10.408582,-75.538003) (10.433609,-73.247863) 
##                    823                   7344                     60

Filtros

Aplicaremos varios filtros para analizar más detalladamente las variables y poder descubrir patrones y conclusiones.

Filtro 1: Nacionalidad con Mayor Ingreso de Extranjeros por Año

library(dplyr)
library(ggplot2)
library(scales)
## 
## Adjuntando el paquete: 'scales'
## The following object is masked from 'package:readr':
## 
##     col_factor
base_anios <- Base %>% group_by(Año, Nacionalidad) %>% summarise(Total_Extranjeros = sum(Total, na.rm = TRUE))
## `summarise()` has grouped output by 'Año'. You can override using the `.groups`
## argument.
Mayor_Nacionalidad <- base_anios %>% group_by(Año) %>% slice_max(Total_Extranjeros, n = 1)

head(Mayor_Nacionalidad)
## # A tibble: 6 × 3
## # Groups:   Año [6]
##     Año Nacionalidad              Total_Extranjeros
##   <dbl> <chr>                                 <dbl>
## 1  2012 Estados Unidos de América            327721
## 2  2013 Estados Unidos de América            342680
## 3  2014 Estados Unidos de América            376015
## 4  2015 Estados Unidos de América            445957
## 5  2016 Estados Unidos de América            499338
## 6  2017 Venezuela                            796234
ggplot(Mayor_Nacionalidad, aes(x = factor(Año), y = Total_Extranjeros, fill = Nacionalidad)) + geom_bar(stat = "identity") + labs(title = "Nacionalidad con Mayor Número de Extranjeros por Año", x = "Año", y = "Número de Extranjeros", fill = "Nacionalidad") + scale_y_continuous(breaks = seq(0, max(base_anios$Total_Extranjeros), by = 100000), 
                     labels = scales::comma) + theme_minimal() + theme(axis.text.x = element_text(angle = 45, hjust = 1))

Filtro 2: Género con Mayor Entrada por Año

library(dplyr)
library(ggplot2)
library(tidyr)

filtro_genero <- Base %>%
  group_by(Año) %>%
  summarise(
    Total_Femenino = sum(Femenino, na.rm = TRUE),
    Total_Masculino = sum(Masculino, na.rm = TRUE)
  ) %>%
  pivot_longer(cols = c(Total_Femenino, Total_Masculino), 
               names_to = "Género", 
               values_to = "Total") #Agrupamos por año y sumamos la cantidad de extranjeros femeninos y masculinos.

ggplot(filtro_genero, aes(x = factor(Año), y = Total, fill = Género)) +
  geom_bar(stat = "identity", position = position_dodge(width = 0.9)) +
  labs(title = "Comparación de Ingresos de Mujeres y Hombres por Año",
       x = "Año",
       y = "Número de Extranjeros",
       fill = "Género") +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

print(filtro_genero, width = Inf)
## # A tibble: 24 × 3
##      Año Género            Total
##    <dbl> <chr>             <dbl>
##  1  2012 Total_Femenino   635506
##  2  2012 Total_Masculino 1062860
##  3  2013 Total_Femenino   693953
##  4  2013 Total_Masculino 1138145
##  5  2014 Total_Femenino   797973
##  6  2014 Total_Masculino 1253945
##  7  2015 Total_Femenino   952971
##  8  2015 Total_Masculino 1434492
##  9  2016 Total_Femenino  1109377
## 10  2016 Total_Masculino 1589880
## # ℹ 14 more rows

Filtro 3: Número de extranjeros por mes

orden_meses <- c("Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", 
                 "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre") #Hacemos un vector con los meses ordenados.

meses <- Base %>% group_by(Mes) %>% summarise(Total_Extranjeros = sum(Total, na.rm = TRUE)) #Agrupamos por mes y contamos el total de extranjeros.

ggplot(meses, aes(x = factor(Mes, levels = orden_meses), y = Total_Extranjeros, fill = Mes)) +
  geom_bar(stat = "identity") +
  labs(title = "Número Total de Extranjeros por Mes",
       x = "Mes",
       y = "Número de Extranjeros",
       fill = "Mes") +
  scale_y_continuous(breaks = seq(0, max(meses$Total_Extranjeros), by = 250000)) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Filtro 4: Número de extranjeros por Países Sudamericanos

paises_sur <- c("Argentina", "Bolivia", "Brasil", "Chile", "Colombia", "Ecuador", "Guyana", "Paraguay", "Perú", "Surinam", "Uruguay", "Venezuela")

Base_sur <- Base %>%
  filter(Nacionalidad %in% paises_sur)

Tabla_Suda <- Base_sur %>%
  group_by(Nacionalidad) %>%
  summarise(Total_Extranjeros = sum(Total, na.rm = TRUE)) %>%
  ungroup() %>%
  arrange(desc(Total_Extranjeros))

head(Tabla_Suda)
## # A tibble: 6 × 2
##   Nacionalidad Total_Extranjeros
##   <chr>                    <dbl>
## 1 Venezuela              5895971
## 2 Ecuador                1680447
## 3 Perú                   1487217
## 4 Brasil                 1478807
## 5 Argentina              1465090
## 6 Chile                  1244837
ggplot(Tabla_Suda, aes(x = reorder(Nacionalidad, -Total_Extranjeros), y = Total_Extranjeros, fill = Nacionalidad)) +
  geom_bar(stat = "identity") +
  labs(title = "Total de Extranjeros por País de América del Sur",
       x = "País",
       y = "Número de Extranjeros",
       fill = "País") +
  theme_bw() + scale_y_continuous(breaks = seq(0, max(Tabla_Suda$Total_Extranjeros), by = 500000))+
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Filtro 5: Extranjeros por año 2020-2023

library(dplyr)
library(ggplot2)

# Filtrar y sumar el número de extranjeros para los años 2020 y 2021
num_extranjeros <- Base %>%
  filter(Año %in% c(2020, 2021, 2022, 2023)) %>%        # Filtrar para los años 2020, 2021, 2022 y 2023
  group_by(Año) %>%                         # Agrupar por el año
  summarise(Total_Extranjeros = sum(Total)) # Sumar el total de extranjeros por año

# Mostrar los resultados en la consola
print(num_extranjeros)
## # A tibble: 4 × 2
##     Año Total_Extranjeros
##   <dbl>             <dbl>
## 1  2020           1000560
## 2  2021           1522129
## 3  2022           3511950
## 4  2023           2058289
# Graficar los resultados
ggplot(num_extranjeros, aes(x = as.factor(Año), y = Total_Extranjeros, fill = as.factor(Año))) +
  geom_bar(stat = "identity") +
  labs(title = "Número de Extranjeros en 2020-2023", 
       x = "Año", 
       y = "Número de Extranjeros") + scale_y_continuous(breaks = seq(0, max(num_extranjeros$Total_Extranjeros), by = 280000))+
  theme_minimal() +
  scale_fill_manual(values = c("2020" = "lightblue", "2021" = "lightgreen", "2022" = "pink", "2023" = "purple"))

Filtro 6 - Número de Venezolanos

venezolanos <- Base %>% filter(Nacionalidad == "Venezuela") #Filtramos por nacionalidad venezolana.

head(venezolanos)
## # A tibble: 6 × 9
##     Año Mes   Nacionalidad `Codigo Iso 3166` Femenino Masculino Indefinido Total
##   <dbl> <chr> <chr>                    <dbl>    <dbl>     <dbl> <lgl>      <dbl>
## 1  2012 Enero Venezuela                  862      297       339 NA           636
## 2  2012 Enero Venezuela                  862        7        12 NA            19
## 3  2012 Enero Venezuela                  862       76       133 NA           209
## 4  2012 Enero Venezuela                  862       55        70 NA           125
## 5  2012 Enero Venezuela                  862        0         4 NA             4
## 6  2012 Enero Venezuela                  862     1265      1721 NA          2986
## # ℹ 1 more variable: `Latitud - Longitud` <chr>
base_venezolanos <- venezolanos %>% group_by(Año) %>% summarise(Total_Venezolanos = sum(Total, na.rm = TRUE)) #Agrupamos por año y sumamos el total de extranjeros venezolanos.

print(base_venezolanos, width = Inf)
## # A tibble: 12 × 2
##      Año Total_Venezolanos
##    <dbl>             <dbl>
##  1  2012            251475
##  2  2013            261343
##  3  2014            291539
##  4  2015            329478
##  5  2016            378965
##  6  2017            796234
##  7  2018           1359815
##  8  2019           1095706
##  9  2020            189883
## 10  2021            260628
## 11  2022            453842
## 12  2023            227063
#Graficamos
ggplot(venezolanos, aes(x = factor(Año), y = Total, fill = factor(Año))) +
  geom_bar(stat = "identity") +
  scale_y_continuous(breaks = seq(0, max(base_venezolanos$Total_Venezolanos), by = 260000)) +  
  labs(title = "Total de Extranjeros Venezolanos por Año",
       x = "Año",
       y = "Total de Extranjeros Venezolanos",
       fill = "Año") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Exploración con la función Table

Empezamos a inspeccionar por variables catégoricas:

library(dplyr)

frecuencia_meses <- table(Base$Mes)
print(frecuencia_meses) #Creamos la tabla de frecuencia de los meses
## 
##      Abril     Agosto  Diciembre      Enero    Febrero      Julio      Junio 
##      11245      10352      11597      12603      12239      10555      11181 
##      Marzo       Mayo  Noviembre    Octubre Septiembre 
##      12245      11158      11108      10543      10214
df_frecuencia <- as.data.frame(frecuencia_meses) #Lo pasamos a data frame

orden_meses <- c("Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", 
                 "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre") #Creamos un vector con los meses ordenados

df_frecuencia$Var1 <- factor(df_frecuencia$Var1, levels = orden_meses)
df_frecuencia <- df_frecuencia[order(df_frecuencia$Var1), ] #Organizamos el dataframe por el orden del vector.

print(df_frecuencia)
##          Var1  Freq
## 4       Enero 12603
## 5     Febrero 12239
## 8       Marzo 12245
## 1       Abril 11245
## 9        Mayo 11158
## 7       Junio 11181
## 6       Julio 10555
## 2      Agosto 10352
## 12 Septiembre 10214
## 11    Octubre 10543
## 10  Noviembre 11108
## 3   Diciembre 11597
colores <- rainbow(length(orden_meses))  # Usar la paleta rainbow para asignar un color único a cada mes

# Graficamos usando barplot
barplot(df_frecuencia$Freq,
        names.arg = df_frecuencia$Var1,
        main = "Frecuencia por Mes",
        xlab = "Meses",
        ylab = "Frecuencia",
        col = colores,
        las = 2)  

# Crear la tabla de frecuencia para la variable 'Nacionalidad'
frecuencia_nacionalidad <- table(Base$Nacionalidad)

# Ordenar la tabla de mayor a menor frecuencia
tabla_ord <- sort(frecuencia_nacionalidad, decreasing = TRUE)

# Seleccionar solo las 10 nacionalidades con mayor frecuencia
top_10_nacionalidad <- head(tabla_ord, 10)

# Imprimir la tabla de las 10 principales nacionalidades
print(top_10_nacionalidad)
## 
##                                       Venezuela 
##                                            3094 
##                       Estados Unidos de América 
##                                            3045 
##                                          España 
##                                            2925 
## Reino Unido de Gran Bretaña e Irlanda del Norte 
##                                            2738 
##                                    Países Bajos 
##                                            2704 
##                                         Ecuador 
##                                            2678 
##                                            Perú 
##                                            2652 
##                                         Francia 
##                                            2531 
##                                          Italia 
##                                            2522 
##                                        Alemania 
##                                            2498
colores <- rainbow(10) #Generamos 10 colores al azar

# Graficar solo las 10 nacionalidades más frecuentes
barplot(top_10_nacionalidad, 
        main = "Top 10 Nacionalidades", 
        col = colores, 
        las = 2, 
        cex.names = 0.8)  # Ajustar el tamaño de las etiquetas si es necesario

Ahora, pasemos a ver las númericas:

tabla_año <- table(Base$Año) #Utilizamos la función table

print(tabla_año)
## 
##  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023 
## 11773 11797 11689 12243 12242 13144 13459 13568  5436  8346 13476  7867
plot(names(tabla_año), 
     as.numeric(tabla_año), 
     type = "o", 
     main = "Tendencia de los Años",
     xlab = "Año", 
     ylab = "Frecuencia", 
     col = "blue", 
     pch = 16, 
     lwd = 2)

library(dplyr)
library(tidyr)
library(ggplot2)

Tabla1 <- Base %>% select(Año, Nacionalidad, Femenino, Masculino) %>% pivot_longer(cols = c(Femenino, Masculino), names_to = "Sexo", values_to = "Total") %>% filter(Total > 0) #Convertimos femenino y masculino en una sola columna llamada "Sexo"

Tabla2 <- Tabla1 %>%
  group_by(Sexo) %>%
  summarise(Total = sum(Total)) %>%
  ungroup() %>%
  mutate(Porcentaje = Total / sum(Total)) %>%
  arrange(Porcentaje) %>%
  mutate(etiquetas = scales::percent(Porcentaje)) #Agrupamos y sacamos porcentaje

#Graficamos
ggplot(Tabla2, aes(x = "", y = Porcentaje, fill = Sexo)) +
  geom_col(color = "black") +
  geom_label(aes(label = etiquetas),
             position = position_stack(vjust = 0.5),
             show.legend = FALSE) +
  guides(fill = guide_legend(title = "Distribución de Extranjeros según el Sexo")) +
  coord_polar(theta = "y") +
  ggtitle("Distribución de Extranjeros por Sexo")

Identificación de Valores NA

library(knitr)
library(dplyr)
library(kableExtra)

# Contar valores NA por cada variable en la base de datos
na_counts <- sapply(Base, function(x) sum(is.na(x)))

# Imprimir los resultados en formato de lista
cat("Valores NA por variable:\n\n")
## Valores NA por variable:
for (variable in names(na_counts)) {
  cat(paste0("- ", variable, ": ", na_counts[variable], " valores NA.\n"))
}
## - Año: 0 valores NA.
## - Mes: 0 valores NA.
## - Nacionalidad: 0 valores NA.
## - Codigo Iso 3166: 0 valores NA.
## - Femenino: 0 valores NA.
## - Masculino: 0 valores NA.
## - Indefinido: 135040 valores NA.
## - Total: 0 valores NA.
## - Latitud - Longitud: 0 valores NA.
# Mostrar en una tabla
kable(na_counts, col.names = c("Variable", "NA"), caption = "Cantidad de Valores NA") %>% 
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"), full_width = FALSE)
Cantidad de Valores NA
Variable NA
Año 0
Mes 0
Nacionalidad 0
Codigo Iso 3166 0
Femenino 0
Masculino 0
Indefinido 135040
Total 0
Latitud - Longitud 0
# Verificar NA en columnas
colSums(is.na(Base))
##                Año                Mes       Nacionalidad    Codigo Iso 3166 
##                  0                  0                  0                  0 
##           Femenino          Masculino         Indefinido              Total 
##                  0                  0             135040                  0 
## Latitud - Longitud 
##                  0
suppressWarnings(require(Amelia))
## Cargando paquete requerido: 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
## ##
suppressWarnings(missmap(Base))

Presencia de Valores Atípicos

# Seleccionamos solo las columnas numéricas
numericas <- Base %>% select_if(is.numeric)

# Imprimir un resumen de las columnas numéricas
summary(numericas)
##       Año       Codigo Iso 3166    Femenino          Masculino      
##  Min.   :2012   Min.   :    0   Min.   :    0.00   Min.   :    0.0  
##  1st Qu.:2014   1st Qu.:  208   1st Qu.:    0.00   1st Qu.:    1.0  
##  Median :2017   Median :  392   Median :    2.00   Median :    3.0  
##  Mean   :2017   Mean   : 1182   Mean   :   93.86   Mean   :  130.1  
##  3rd Qu.:2020   3rd Qu.:  643   3rd Qu.:    9.00   3rd Qu.:   17.0  
##  Max.   :2023   Max.   :99999   Max.   :39500.00   Max.   :48041.0  
##      Total      
##  Min.   :    1  
##  1st Qu.:    2  
##  Median :    5  
##  Mean   :  224  
##  3rd Qu.:   26  
##  Max.   :82609
# Configurar la disposición de los gráficos
par(mfrow=c(1,5))  # Cambia la disposición si tienes más o menos gráficos

# Crear diagramas de caja para cada columna numérica
for (columna in names(numericas)) {
  boxplot(numericas[[columna]], main = columna)
}

# Función para detectar valores atípicos usando el método de IQR (Rango Intercuartílico)

# Aplicar la función a cada variable numérica en la base de datos
outliers_count <- sapply(Base, function(x) if (is.numeric(x)) detectar_atipicos(x) else NA)

# Imprimir los resultados en formato de lista
cat("Análisis de posibles valores atípicos por variable:\n\n")
## Análisis de posibles valores atípicos por variable:
for (variable in names(outliers_count)) {
  if (!is.na(outliers_count[variable])) {
    cat(paste0("- ", variable, ": ", outliers_count[variable], " valores atípicos.\n"))
  }
}
## - Año: 0 valores atípicos.
## - Codigo Iso 3166: 1023 valores atípicos.
## - Femenino: 22823 valores atípicos.
## - Masculino: 21762 valores atípicos.
## - Total: 22472 valores atípicos.
kable(outliers_count, col.names = c("    Variable    ", "    Valores Atípicos    "), caption = "Cantidad de Valores Atípicos") %>% kable_styling(bootstrap_options = c("striped", "hover", "condensed"), full_width = FALSE)
Cantidad de Valores Atípicos
Variable Valores Atípicos
Año 0
Mes NA
Nacionalidad NA
Codigo Iso 3166 1023
Femenino 22823
Masculino 21762
Indefinido NA
Total 22472
Latitud - Longitud NA
#Filtramos los datos sin los valores atípicos de las variables "Código Iso 3166", "Femenino", "Masculino", "Total"

filter(Base, Femenino > 2)
## # A tibble: 57,128 × 9
##      Año Mes   Nacionalidad `Codigo Iso 3166` Femenino Masculino Indefinido
##    <dbl> <chr> <chr>                    <dbl>    <dbl>     <dbl> <lgl>     
##  1  2012 Enero Alemania                   276       11        16 NA        
##  2  2012 Enero Alemania                   276       63       102 NA        
##  3  2012 Enero Alemania                   276       22        23 NA        
##  4  2012 Enero Alemania                   276       27        48 NA        
##  5  2012 Enero Alemania                   276        7         4 NA        
##  6  2012 Enero Alemania                   276        8        21 NA        
##  7  2012 Enero Alemania                   276        6         7 NA        
##  8  2012 Enero Alemania                   276       25        49 NA        
##  9  2012 Enero Alemania                   276     1182      2025 NA        
## 10  2012 Enero Alemania                   276       30        97 NA        
## # ℹ 57,118 more rows
## # ℹ 2 more variables: Total <dbl>, `Latitud - Longitud` <chr>
filter(Base, Masculino > 3)
## # A tibble: 66,145 × 9
##      Año Mes   Nacionalidad `Codigo Iso 3166` Femenino Masculino Indefinido
##    <dbl> <chr> <chr>                    <dbl>    <dbl>     <dbl> <lgl>     
##  1  2012 Enero Alemania                   276       11        16 NA        
##  2  2012 Enero Alemania                   276       63       102 NA        
##  3  2012 Enero Alemania                   276       22        23 NA        
##  4  2012 Enero Alemania                   276       27        48 NA        
##  5  2012 Enero Alemania                   276        7         4 NA        
##  6  2012 Enero Alemania                   276        8        21 NA        
##  7  2012 Enero Alemania                   276        6         7 NA        
##  8  2012 Enero Alemania                   276       25        49 NA        
##  9  2012 Enero Alemania                   276     1182      2025 NA        
## 10  2012 Enero Alemania                   276       30        97 NA        
## # ℹ 66,135 more rows
## # ℹ 2 more variables: Total <dbl>, `Latitud - Longitud` <chr>
filter(Base, `Codigo Iso 3166` > 392)
## # A tibble: 66,801 × 9
##      Año Mes   Nacionalidad      `Codigo Iso 3166` Femenino Masculino Indefinido
##    <dbl> <chr> <chr>                         <dbl>    <dbl>     <dbl> <lgl>     
##  1  2012 Enero Islas Alboran y …             99999        1         0 NA        
##  2  2012 Enero Países Bajos                    528        1         2 NA        
##  3  2012 Enero Aruba                           533        0         1 NA        
##  4  2012 Enero Aruba                           533        0         1 NA        
##  5  2012 Enero Burkina Faso                    854        1         0 NA        
##  6  2012 Enero España                          724        1         0 NA        
##  7  2012 Enero España                          724       14        27 NA        
##  8  2012 Enero España                          724       10        14 NA        
##  9  2012 Enero España                          724        3        11 NA        
## 10  2012 Enero España                          724        0         1 NA        
## # ℹ 66,791 more rows
## # ℹ 2 more variables: Total <dbl>, `Latitud - Longitud` <chr>
filter(Base, Total > 5)
## # A tibble: 65,039 × 9
##      Año Mes   Nacionalidad `Codigo Iso 3166` Femenino Masculino Indefinido
##    <dbl> <chr> <chr>                    <dbl>    <dbl>     <dbl> <lgl>     
##  1  2012 Enero Alemania                   276       11        16 NA        
##  2  2012 Enero Alemania                   276       63       102 NA        
##  3  2012 Enero Alemania                   276       22        23 NA        
##  4  2012 Enero Alemania                   276       27        48 NA        
##  5  2012 Enero Alemania                   276        7         4 NA        
##  6  2012 Enero Alemania                   276        8        21 NA        
##  7  2012 Enero Alemania                   276        6         7 NA        
##  8  2012 Enero Alemania                   276       25        49 NA        
##  9  2012 Enero Alemania                   276     1182      2025 NA        
## 10  2012 Enero Alemania                   276       30        97 NA        
## # ℹ 65,029 more rows
## # ℹ 2 more variables: Total <dbl>, `Latitud - Longitud` <chr>
#Reemplazamos los valores atípicos por NA
Base$Femenino[Base$Femenino > 2] <- NA

Base$Masculino[Base$Masculino > 3] <- NA

Base$`Codigo Iso 3166`[Base$`Codigo Iso 3166` > 392] <- NA

Base$Total[Base$Total > 5] <- NA

#Graficamos para ver la diferencia
par(mfrow=c(1,5))
 boxplot(Base$Año,main="Años")
 boxplot(Base$`Codigo Iso 3166`,main="Código")
 boxplot(Base$Femenino, main="Femenino")
 boxplot(Base$Masculino, main="Masculino")
 boxplot(Base$Total, main="Total")

Calculo con variables

Procederemos a calcular las medidas de tendencia para obtener un analisis más detallado.

# Cargar librerías necesarias
library(dplyr)
library(ggplot2)
library(plotly)
## 
## Adjuntando el paquete: 'plotly'
## The following object is masked from 'package:ggplot2':
## 
##     last_plot
## The following object is masked from 'package:stats':
## 
##     filter
## The following object is masked from 'package:graphics':
## 
##     layout
library(DescTools)
library(readr)
library(nortest)


# Función para calcular estadísticas
calcular_estadisticas <- function(columna) {
  media <- mean(columna, na.rm = TRUE)
  mediana <- median(columna, na.rm = TRUE)
  percentiles <- quantile(columna, probs = c(0.25, 0.5, 0.75), na.rm = TRUE)
  sd <- sd(columna, na.rm = TRUE)
  cv <- (sd / media) * 100
  
  list(
    media = media,
    mediana = mediana,
    percentiles = percentiles,
    sd = sd,
    cv = cv
  )
}

# Calcular estadísticas para Masculino y Femenino
estadisticas_masculino <- calcular_estadisticas(Base$Masculino)
estadisticas_femenino <- calcular_estadisticas(Base$Femenino)

# Imprimir resultados
cat("Medidas para 'Masculino':\n")
## Medidas para 'Masculino':
print(estadisticas_masculino)
## $media
## [1] 1.295943
## 
## $mediana
## [1] 1
## 
## $percentiles
## 25% 50% 75% 
##   1   1   2 
## 
## $sd
## [1] 0.9048324
## 
## $cv
## [1] 69.82038
cat("\n")
cat("Medidas para 'Femenino':\n")
## Medidas para 'Femenino':
print(estadisticas_femenino)
## $media
## [1] 0.6357557
## 
## $mediana
## [1] 0
## 
## $percentiles
## 25% 50% 75% 
##   0   0   1 
## 
## $sd
## [1] 0.7275461
## 
## $cv
## [1] 114.438
cat("\n")
# Limpiar datos de NA
data_masculino <- na.omit(Base$Masculino)
data_femenino <- na.omit(Base$Femenino)

# Pruebas de normalidad
if (length(data_masculino) >= 3 & length(data_masculino) <= 5000) {
  shapiro_masculino <- shapiro.test(data_masculino)
  cat("Prueba de Shapiro-Wilk para 'Masculino':\n")
  print(shapiro_masculino)
} else {
  cat("El tamaño de la muestra para 'Masculino' no es adecuado para la prueba de Shapiro-Wilk.\n")
}
## El tamaño de la muestra para 'Masculino' no es adecuado para la prueba de Shapiro-Wilk.
if (length(data_femenino) >= 3 & length(data_femenino) <= 5000) {
  shapiro_femenino <- shapiro.test(data_femenino)
  cat("Prueba de Shapiro-Wilk para 'Femenino':\n")
  print(shapiro_femenino)
} else {
  cat("El tamaño de la muestra para 'Femenino' no es adecuado para la prueba de Shapiro-Wilk.\n")
}
## El tamaño de la muestra para 'Femenino' no es adecuado para la prueba de Shapiro-Wilk.
# Prueba de Anderson-Darling para normalidad (alternativa)
ad_masculino <- ad.test(data_masculino)
ad_femenino <- ad.test(data_femenino)

cat("Prueba de Anderson-Darling para 'Masculino':\n")
## Prueba de Anderson-Darling para 'Masculino':
print(ad_masculino)
## 
##  Anderson-Darling normality test
## 
## data:  data_masculino
## A = 4298.5, p-value < 2.2e-16
cat("\n")
cat("Prueba de Anderson-Darling para 'Femenino':\n")
## Prueba de Anderson-Darling para 'Femenino':
print(ad_femenino)
## 
##  Anderson-Darling normality test
## 
## data:  data_femenino
## A = 8282.4, p-value < 2.2e-16
cat("\n")
# Graficar densidad y boxplots interactivos
# Gráfico de densidad
fig_density_masculino <- plot_ly(Base, x = ~Masculino, type = 'histogram', nbinsx = 50, histnorm = 'density',
                                 name = 'Masculino', marker = list(color = 'blue')) %>%
  layout(title = 'Distribución de Masculino - Gráfico de Densidad',
         xaxis = list(title = 'Cantidad de Masculino'),
         yaxis = list(title = 'Densidad'))

fig_density_femenino <- plot_ly(Base, x = ~Femenino, type = 'histogram', nbinsx = 50, histnorm = 'density',
                                name = 'Femenino', marker = list(color = 'red')) %>%
  layout(title = 'Distribución de Femenino - Gráfico de Densidad',
         xaxis = list(title = 'Cantidad de Femenino'),
         yaxis = list(title = 'Densidad'))

# Gráfico de boxplot
fig_boxplot_masculino <- plot_ly(Base, y = ~Masculino, type = 'box', name = 'Masculino', marker = list(color = 'blue')) %>%
  layout(title = 'Boxplot de Masculino',
         yaxis = list(title = 'Cantidad de Masculino'))

fig_boxplot_femenino <- plot_ly(Base, y = ~Femenino, type = 'box', name = 'Femenino', marker = list(color = 'red')) %>%
  layout(title = 'Boxplot de Femenino',
         yaxis = list(title = 'Cantidad de Femenino'))

# Mostrar gráficos
fig_density_masculino
## Warning: Ignoring 66145 observations
fig_density_femenino
## Warning: Ignoring 57128 observations
fig_boxplot_masculino
## Warning: Ignoring 66145 observations
fig_boxplot_femenino
## Warning: Ignoring 57128 observations

Comentarios Generales

Dimensiones de la Base de Datos

La base de datos cuenta con 135,040 filas y 9 columnas. Esto indica un volumen considerable de datos que refleja las entradas de extranjeros a lo largo de varios años, lo que permite un análisis detallado de patrones de migración.

Variables Presentes

Las variables incluyen información crítica como el año y mes de entrada, la nacionalidad de los extranjeros, y la distribución por género. La variable ‘Total’ resume el número total de entradas, lo que facilita un análisis agregado.

Clasificación de Variables

cat(“Las variables han sido correctamente clasificadas en cualitativas (como Nacionalidad) y cuantitativas (como Total). Esta clasificación es esencial para elegir las técnicas estadísticas adecuadas en el análisis.

Valores Atípicos

cat(“Se identificaron varios valores atípicos en variables numéricas como ‘Femenino’, ‘Masculino’, y ‘Total’. La presencia de estos valores puede deberse a varios factores, como la alta variabilidad en los datos o posibles errores en el registro de los mismos.

Posibles Causas

Alta Variabilidad en los Datos: En bases de datos como esta, es común que ciertos eventos (por ejemplo, un aumento repentino en las entradas debido a un evento internacional) generen valores que se consideran atípicos en comparación con el comportamiento regular. cat(“Errores en el Registro: También es posible que algunos de estos valores sean el resultado de errores en la entrada de datos, especialmente si se ven significativamente alejados de otros valores en la misma categoría.

Distribución por Nacionalidad

El análisis muestra que ciertas nacionalidades tienen un número significativamente mayor de entradas a Colombia, lo que puede estar relacionado con la cercanía geográfica, lazos históricos, o políticas migratorias específicas.

Distribución por Género

Al observar la distribución por género, se nota un equilibrio general en las entradas masculinas y femeninas, aunque algunas diferencias pueden ser observadas en ciertos años, lo cual podría ser investigado más a fondo para entender las causas detrás de estos cambios.

Impacto de Eventos Recientes

Es notable que los años recientes (2020-2023) muestran una fluctuación en el número de entradas, lo que probablemente esté relacionado con eventos globales como la pandemia de COVID-19. Este impacto es visible en la reducción o aumento de entradas en ciertos períodos.

Valor de la Variable “Indefinido”

La variable ‘Indefinido’, que registra las entradas de personas cuyo género no se clasifica como masculino o femenino, es interesante desde una perspectiva de inclusión y podría ser útil en estudios sobre diversidad y reconocimiento de identidades no binarias.