Introducción

Objetivos

General:

Analizar el comportamiento del comercio exterior de productos del rubro forestal en Paraguay durante el período de estudio, mediante técnicas de análisis estadístico y visualización de datos en R, considerando las operaciones de importación y exportación, su evolución temporal, volumen comercializado, composición de los productos y principales mercados de origen y destino

Especificos

  1. Caracterizar las operaciones de comercio exterior del rubro forestal según tipo de operación y categoría de producto.

  2. Analizar el volumen físico de productos forestales importados y exportados, considerando el peso neto y la cantidad estadística.

  3. Analizar la evolución temporal del comercio forestal, identificando tendencias y posibles patrones estacionales durante el período de estudio.

  4. Identificar los principales productos y categorías forestales comercializados, diferenciando su comportamiento entre importaciones y exportaciones.

  5. Identificar los principales países de origen, procedencia y destino de los productos forestales según el tipo de operación.

  6. Caracterizar las operaciones forestales según las principales aduanas y medios de transporte utilizados.

Datos: Aduanas

https://www.dnit.gov.py/web/portal-institucional/datos-abiertos

Metodología

Tratamiento y gestión de datos

Carga de datos mensuales


# Instala las librerías si hace falta
# install.packages(c("arrow", "dplyr"))

library(arrow)
library(dplyr)

# ---------------------------------------------------------
# 1. Ubicación de los archivos Parquet
# ---------------------------------------------------------

dir_parquet <- "C:/Users/emper/Downloads/Analitica de Big Data/dataset_rubro_forestal"

# Buscar todos los archivos Parquet de la carpeta
files <- list.files(
  dir_parquet,
  pattern = "\\.parquet$",
  full.names = TRUE
)

# Ver cuántos archivos Parquet se encontraron
cat("Archivos Parquet encontrados:", length(files), "\n")

# ---------------------------------------------------------
# 2. Abrir los archivos como un Dataset
# ---------------------------------------------------------

ds <- open_dataset(
  files,
  format = "parquet"
)

# ---------------------------------------------------------
# 3. Categorías del rubro forestal
# ---------------------------------------------------------

rubros_forestales <- c(
  "MADERA",
  "CARBON VEGETAL",
  "CAPITULO 45CORCHO Y MANUFACTURAS DE CORCHO",
  "CAPITULO 46  MANUFACTURAS DE ESPARTERIA O DE CESTERIA",
  "CAPITULO 47  PASTA DE MADERA O DE OTRAS MATERIAS FIBROSAS CELULOSICAS ,DESPERDICIOS Y DESECHOS DE PA",
  "PAPEL Y CARTON"
)

# ---------------------------------------------------------
# 4. Filtrar únicamente los rubros forestales
# ---------------------------------------------------------

forestal <- ds %>%
  filter(RUBRO %in% rubros_forestales) %>%
  collect()

# ---------------------------------------------------------
# 5. Verificación de los resultados
# ---------------------------------------------------------

cat("Filas forestales:", nrow(forestal), "\n")

cat("\nRubros forestales encontrados:\n")
print(unique(forestal$RUBRO))

# ---------------------------------------------------------
# 6. Cantidad de registros por rubro
# ---------------------------------------------------------

cat("\nCantidad de registros por rubro:\n")

forestal %>%
  count(RUBRO, sort = TRUE) %>%
  print()


#guardar en formato .parquet la base compilada y cargar
# =========================================================
# CONSOLIDACIÓN DE LA BASE DE DATOS DEL RUBRO FORESTAL
# DNIT - Últimos 10 años
# =========================================================

library(arrow)
library(dplyr)

# ---------------------------------------------------------
# 1. Ubicación de los archivos originales
# ---------------------------------------------------------

dir_parquet <- "C:/Users/emper/Downloads/Analitica de Big Data/dataset_rubro_forestal"

# Buscar todos los archivos Parquet
files <- list.files(
  dir_parquet,
  pattern = "\\.parquet$",
  full.names = TRUE
)

cat("Archivos Parquet encontrados:", length(files), "\n")

if (length(files) == 0) {
  stop("No se encontraron archivos Parquet en la carpeta de origen.")
}

# ---------------------------------------------------------
# 2. Abrir los archivos como un único conjunto de datos
# ---------------------------------------------------------

ds <- open_dataset(
  files,
  format = "parquet"
)

# ---------------------------------------------------------
# 3. Definir los rubros forestales
# ---------------------------------------------------------

rubros_forestales <- c(
  "MADERA",
  "CARBON VEGETAL",
  "CAPITULO 45CORCHO Y MANUFACTURAS DE CORCHO",
  "CAPITULO 46  MANUFACTURAS DE ESPARTERIA O DE CESTERIA",
  "CAPITULO 47  PASTA DE MADERA O DE OTRAS MATERIAS FIBROSAS CELULOSICAS ,DESPERDICIOS Y DESECHOS DE PA",
  "PAPEL Y CARTON"
)

# ---------------------------------------------------------
# 4. Filtrar los registros forestales
# ---------------------------------------------------------

ds_forestal <- ds %>%
  filter(RUBRO %in% rubros_forestales)

# ---------------------------------------------------------
# 5. Definir la carpeta de salida
# ---------------------------------------------------------

dir_salida <- "C:/Users/emper/Downloads/Analitica de Big Data/base_forestal_consolidada"

# Crear la carpeta si todavía no existe
dir.create(
  dir_salida,
  recursive = TRUE,
  showWarnings = FALSE
)

# ---------------------------------------------------------
# 6. Guardar la base consolidada en formato Parquet
# ---------------------------------------------------------

write_dataset(
  ds_forestal,
  path = dir_salida,
  format = "parquet",
  existing_data_behavior = "delete_matching",
  max_rows_per_file = 1000000,
  max_rows_per_group = 100000
)

cat("\nConsolidación finalizada correctamente.\n")
cat("Carpeta de salida:", dir_salida, "\n")

# ---------------------------------------------------------
# 7. Abrir la base consolidada para verificarla
# ---------------------------------------------------------

base_forestal <- open_dataset(
  dir_salida,
  format = "parquet"
)

# Cantidad total de registros
total_registros <- base_forestal %>%
  summarise(total = n()) %>%
  collect() %>%
  pull(total)

cat("\nTotal de registros forestales:", total_registros, "\n")

# Cantidad de registros por rubro
cat("\nRegistros por rubro:\n")

base_forestal %>%
  count(RUBRO, sort = TRUE) %>%
  collect() %>%
  print()

# =========================================================
# FIN DE LA CONSOLIDACIÓN
# =========================================================
library(arrow)
## 
## Adjuntando el paquete: 'arrow'
## The following object is masked from 'package:utils':
## 
##     timestamp
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
archivo="C:/Users/emper/Downloads/Analitica de Big Data/base_forestal_consolidada/part-0.parquet"

#archivo="H:/Mi unidad/FACEN_BIGDATA/FACEN_BIG_DATA_2DO_SEM_2026/FACEN_BIG_DATA_2DO_SEM_2026/trabajos_2do_sem_2026_presencial_sabados/erika_peralta/dataset_rubro_forestal/base_forestal_consolidada/part-0.parquet"


base_forestal <- open_dataset(
  archivo,
  format = "parquet"
)
base_forestal=as.data.frame(base_forestal)
base_forestal
## # A tibble: 953,299 × 47
##    `DESPACHO CIFRADO` OPERACION   DESTINACION REGIMEN OFICIALIZACION CANCELACION
##    <chr>              <chr>       <chr>       <chr>   <chr>          <chr>      
##  1 16DA000000056900   IMPORTACION IC04        IMPORT… 26/04/2016     26/04/2016 
##  2 16DA000000055847   IMPORTACION IC04        IMPORT… 28/04/2016     28/04/2016 
##  3 16DA000000042195   IMPORTACION IM04        IMPORT… 01/04/2016     01/04/2016 
##  4 16DA000000042195   IMPORTACION IM04        IMPORT… 01/04/2016     01/04/2016 
##  5 16DA000000041803   EXPORTACION EC03        EXPORT… 30/03/2016     01/04/2016 
##  6 16DA000000049632   EXPORTACION EC01        EXPORT… 31/03/2016     06/04/2016 
##  7 16DA000000050793   IMPORTACION IC04        IMPORT… 11/04/2016     11/04/2016 
##  8 16DA000000063010   EXPORTACION EC03        EXPORT… 14/04/2016     19/04/2016 
##  9 16DA000000042195   IMPORTACION IM04        IMPORT… 01/04/2016     01/04/2016 
## 10 16DA000000042195   IMPORTACION IM04        IMPORT… 01/04/2016     01/04/2016 
## # ℹ 953,289 more rows
## # ℹ 41 more variables: AÑO <int>, MES <chr>, ADUANA <chr>, COTIZACION <chr>,
## #   `MEDIO TRANSPORTE` <chr>, CANAL <chr>, ITEM <int>, `PAIS ORIGEN` <chr>,
## #   `PAIS PROCEDENCIA/DESTINO` <chr>, USO <chr>,
## #   `UNIDAD MEDIDA ESTADISTICA` <chr>, `CANTIDAD ESTADISTICA` <chr>,
## #   `KILO NETO` <chr>, `KILO BRUTO` <chr>, `FOB DOLAR` <chr>,
## #   `FLETE DOLAR` <chr>, `SEGURO DOLAR` <chr>, `IMPONIBLE DOLAR` <chr>, …
names(base_forestal)
##  [1] "DESPACHO CIFRADO"          "OPERACION"                
##  [3] "DESTINACION"               "REGIMEN"                  
##  [5] "OFICIALIZACION"            "CANCELACION"              
##  [7] "AÑO"                       "MES"                      
##  [9] "ADUANA"                    "COTIZACION"               
## [11] "MEDIO TRANSPORTE"          "CANAL"                    
## [13] "ITEM"                      "PAIS ORIGEN"              
## [15] "PAIS PROCEDENCIA/DESTINO"  "USO"                      
## [17] "UNIDAD MEDIDA ESTADISTICA" "CANTIDAD ESTADISTICA"     
## [19] "KILO NETO"                 "KILO BRUTO"               
## [21] "FOB DOLAR"                 "FLETE DOLAR"              
## [23] "SEGURO DOLAR"              "IMPONIBLE DOLAR"          
## [25] "IMPONIBLE GS"              "AJUSTE A INCLUIR"         
## [27] "AJUSTE A DEDUCIR"          "POSICION "                
## [29] "RUBRO"                     "DESC CAPITULO"            
## [31] "DESC PARTIDA"              "DESC POSICION"            
## [33] "MERCADERIA"                "MARCA ITEM"               
## [35] "ACUERDO"                   "NUMERO SUBITEM"           
## [37] "CANTIDAD SUBITEM"          "PRECION UNITARIO SUBITEM" 
## [39] "DESC SUBITEM"              "MARCA SUBITEM"            
## [41] "DERECHO"                   "ISC"                      
## [43] "SERVICIO"                  "RENTA"                    
## [45] "IVA"                       "OTROS"                    
## [47] "TOTAL"
# Consultar la cantidad de registros
nrow(base_forestal)
## [1] 953299
base_forestal %>%
  summarise(total = n()) %>%
  collect()
## # A tibble: 1 × 1
##    total
##    <int>
## 1 953299
# Consultar los rubros disponibles
base_forestal %>%
  count(RUBRO, sort = TRUE) %>%
  collect()
## # A tibble: 6 × 2
##   RUBRO                                                                        n
##   <chr>                                                                    <int>
## 1 PAPEL Y CARTON                                                          747201
## 2 MADERA                                                                  140295
## 3 CARBON VEGETAL                                                           48645
## 4 CAPITULO 47  PASTA DE MADERA O DE OTRAS MATERIAS FIBROSAS CELULOSICAS …   9511
## 5 CAPITULO 46  MANUFACTURAS DE ESPARTERIA O DE CESTERIA                     6568
## 6 CAPITULO 45CORCHO Y MANUFACTURAS DE CORCHO                                1079
#table(base_forestal$MERCADERIA4)
str(base_forestal)
## tibble [953,299 × 47] (S3: tbl_df/tbl/data.frame)
##  $ DESPACHO CIFRADO         : chr [1:953299] "16DA000000056900" "16DA000000055847" "16DA000000042195" "16DA000000042195" ...
##  $ OPERACION                : chr [1:953299] "IMPORTACION" "IMPORTACION" "IMPORTACION" "IMPORTACION" ...
##  $ DESTINACION              : chr [1:953299] "IC04" "IC04" "IM04" "IM04" ...
##  $ REGIMEN                  : chr [1:953299] "IMPORTACION A CONSUMO CON DOCUMENTO DE TRANSPORTE" "IMPORTACION A CONSUMO CON DOCUMENTO DE TRANSPORTE" "IMPORTACION MENOR A CONSUMO CON DOCUMENTO DE TRANSPORTE" "IMPORTACION MENOR A CONSUMO CON DOCUMENTO DE TRANSPORTE" ...
##  $ OFICIALIZACION           : chr [1:953299] "26/04/2016" "28/04/2016" "01/04/2016" "01/04/2016" ...
##  $ CANCELACION              : chr [1:953299] "26/04/2016" "28/04/2016" "01/04/2016" "01/04/2016" ...
##  $ AÑO                      : int [1:953299] 2016 2016 2016 2016 2016 2016 2016 2016 2016 2016 ...
##  $ MES                      : chr [1:953299] "ABRIL" "ABRIL" "ABRIL" "ABRIL" ...
##  $ ADUANA                   : chr [1:953299] "TER. DE CARGAS KM.12" "PAKSA" "AEROP. PETTIROSSI" "AEROP. PETTIROSSI" ...
##  $ COTIZACION               : chr [1:953299] "5530,27" "5537,45" "5628,71" "5628,71" ...
##  $ MEDIO TRANSPORTE         : chr [1:953299] "CAMION" "CAMION" "AVION" "AVION" ...
##  $ CANAL                    : chr [1:953299] "R" "R" "R" "R" ...
##  $ ITEM                     : int [1:953299] 8 10 1 1 2 1 30 1 1 1 ...
##  $ PAIS ORIGEN              : chr [1:953299] "CHINA" "CHINA" "REINO UNIDO" "REINO UNIDO" ...
##  $ PAIS PROCEDENCIA/DESTINO : chr [1:953299] "CHINA" "CHINA" "REINO UNIDO" "REINO UNIDO" ...
##  $ USO                      : chr [1:953299] "NUEVO" "NUEVO" "NUEVO" "NUEVO" ...
##  $ UNIDAD MEDIDA ESTADISTICA: chr [1:953299] "KILOGRAMO" "KILOGRAMO" "KILOGRAMO" "KILOGRAMO" ...
##  $ CANTIDAD ESTADISTICA     : chr [1:953299] "23,0" "234,0" "11,0" "11,0" ...
##  $ KILO NETO                : chr [1:953299] "23,0" "234,0" "11,0" "11,0" ...
##  $ KILO BRUTO               : chr [1:953299] "23,0" "234,0" "11,0" "11,0" ...
##  $ FOB DOLAR                : chr [1:953299] "34,0" "2260,4" "708,46" "708,46" ...
##  $ FLETE DOLAR              : chr [1:953299] "1,4" "196,85" "179,81" "179,81" ...
##  $ SEGURO DOLAR             : chr [1:953299] ",34" "22,6" "7,09" "7,09" ...
##  $ IMPONIBLE DOLAR          : chr [1:953299] "35,74" "2479,85" "895,37" "895,37" ...
##  $ IMPONIBLE GS             : chr [1:953299] "197651,85" "13732045,38" "5039753,47" "5039753,47" ...
##  $ AJUSTE A INCLUIR         : chr [1:953299] ",0" ",0" ",0" ",0" ...
##  $ AJUSTE A DEDUCIR         : chr [1:953299] ",0" ",0" ",0" ",0" ...
##  $ POSICION                 : chr [1:953299] "4819.20.00.000C" "4819.20.00.000C" "4810.99.90.000F" "4810.99.90.000F" ...
##  $ RUBRO                    : chr [1:953299] "PAPEL Y CARTON" "PAPEL Y CARTON" "PAPEL Y CARTON" "PAPEL Y CARTON" ...
##  $ DESC CAPITULO            : chr [1:953299] "CAPITULO 48 PAPEL Y CARTON, MANUFACTURAS DE PASTA DECELULOSA, DE PAPEL O DE CARTON" "CAPITULO 48 PAPEL Y CARTON, MANUFACTURAS DE PASTA DECELULOSA, DE PAPEL O DE CARTON" "CAPITULO 48 PAPEL Y CARTON, MANUFACTURAS DE PASTA DECELULOSA, DE PAPEL O DE CARTON" "CAPITULO 48 PAPEL Y CARTON, MANUFACTURAS DE PASTA DECELULOSA, DE PAPEL O DE CARTON" ...
##  $ DESC PARTIDA             : chr [1:953299] "CAJAS, SACOS (BOLSAS), BOLSITAS, CUCURUCHOS Y DEMAS ENVASES DE PAPEL, CARTON, GUATA DE CELULOSAO NAPAS DE FIBRA"| __truncated__ "CAJAS, SACOS (BOLSAS), BOLSITAS, CUCURUCHOS Y DEMAS ENVASES DE PAPEL, CARTON, GUATA DE CELULOSAO NAPAS DE FIBRA"| __truncated__ "PAPEL Y CARTON, ESTUCADOS POR UNA O LAS DOS CARAS CON CAOLIN U OTRAS SUSTANCIAS INORGANICAS,CON AGLUTINANTE O S"| __truncated__ "PAPEL Y CARTON, ESTUCADOS POR UNA O LAS DOS CARAS CON CAOLIN U OTRAS SUSTANCIAS INORGANICAS,CON AGLUTINANTE O S"| __truncated__ ...
##  $ DESC POSICION            : chr [1:953299] "CAPITULO 48 PAPEL Y CARTON, MANUFACTURAS DE PASTA DECELULOSA, DE PAPEL O DE CARTON  CAJAS, SACOS (BOLSAS), BOLS"| __truncated__ "CAPITULO 48 PAPEL Y CARTON, MANUFACTURAS DE PASTA DECELULOSA, DE PAPEL O DE CARTON  CAJAS, SACOS (BOLSAS), BOLS"| __truncated__ "CAPITULO 48 PAPEL Y CARTON, MANUFACTURAS DE PASTA DECELULOSA, DE PAPEL O DE CARTON  PAPEL Y CARTON, ESTUCADOS P"| __truncated__ "CAPITULO 48 PAPEL Y CARTON, MANUFACTURAS DE PASTA DECELULOSA, DE PAPEL O DE CARTON  PAPEL Y CARTON, ESTUCADOS P"| __truncated__ ...
##  $ MERCADERIA               : chr [1:953299] "LOS DEMAS EN: 111 UNIDADES DE CAJAS VACIAS" "13680 PCS. CAJA P/REGALO" "PAPEL INDICADOR PARA REALIZAR TEST DETALLADOS EN SUBITEM" "PAPEL INDICADOR PARA REALIZAR TEST DETALLADOS EN SUBITEM" ...
##  $ MARCA ITEM               : chr [1:953299] "." "." NA NA ...
##  $ ACUERDO                  : chr [1:953299] "SIN ACUERDO" "SIN ACUERDO" "SIN ACUERDO" "SIN ACUERDO" ...
##  $ NUMERO SUBITEM           : int [1:953299] 0 0 1 2 0 0 0 0 4 3 ...
##  $ CANTIDAD SUBITEM         : int [1:953299] 0 0 50 100 0 0 0 0 50 100 ...
##  $ PRECION UNITARIO SUBITEM : chr [1:953299] ",0" ",0" "3,02" "2,23" ...
##  $ DESC SUBITEM             : chr [1:953299] NA NA "PH INDICATOR STRIPS, PH 0-14" "COMPARATOR STRIPS PH 3.6-5.1" ...
##  $ MARCA SUBITEM            : chr [1:953299] NA NA "JOHNSON" "JOHNSON" ...
##  $ DERECHO                  : chr [1:953299] "31624,0" "2197127,0" "705565,0" "705565,0" ...
##  $ ISC                      : chr [1:953299] ",0" ",0" ",0" ",0" ...
##  $ SERVICIO                 : chr [1:953299] "988,0" "68660,0" "25199,0" "25199,0" ...
##  $ RENTA                    : chr [1:953299] ",0" ",0" ",0" ",0" ...
##  $ IVA                      : chr [1:953299] "23035,0" "1601482,0" "585495,0" "585495,0" ...
##  $ OTROS                    : chr [1:953299] "5,0" "709,0" ",0" ",0" ...
##  $ TOTAL                    : chr [1:953299] "55652,0" "3867978,0" "1316259,0" "1316259,0" ...
table(base_forestal$MES)
## 
##      ABRIL     AGOSTO  DICIEMBRE      ENERO    FEBRERO      JULIO      JUNIO 
##      64326      79302      83813      77147      72748      83621      74663 
##      MARZO       MAYO  NOVIEMBRE    OCTUBRE SEPTIEMBRE 
##      87599      79416      87820      89751      73093
table(base_forestal$MES,base_forestal$AÑO)
##             
##               2016  2017  2018  2019  2020  2021  2022  2023  2024  2025  2026
##   ABRIL       4113  5540  4792  4981  3092  5065  5849  5205  7877  8623  9189
##   AGOSTO      4601  4896  6798  6377  5376  5016  8016  9028  8693 10290 10211
##   DICIEMBRE   5993  5646  8161  7369  7218  7510  8949 10180 11165 11622     0
##   ENERO       5150  7161  5328  5906  8688  4532  8170  5029  8233  9433  9517
##   FEBRERO     4185  4698  7096  5332  5784  5881  5984  6790  7312  7961 11725
##   JULIO       4414  5120  6261  7376  4713  6186  8371  7452 10445  9880 13403
##   JUNIO       5029  6115  5617  5136  4076  7054  7320  8043  7666  8861  9746
##   MARZO       4952  5350  5673  5274  5091  6499  7944 19319  8294  8594 10609
##   MAYO        4203  4319  6325  6638  3445  6421  6199 10572  8844 10591 11859
##   NOVIEMBRE   4946  5511  9402  8593 12889  7474 10854 10721  9034  8396     0
##   OCTUBRE     4545  8707  6686  7687  6121  9648  8230 10070 12819 15238     0
##   SEPTIEMBRE  7157  5801  6616  5937  6784  5709  8054  8009  9754  9272     0

##Calcular el campo fecha a partir de año mes y dia 0,1

library(dplyr)
library(ggplot2)
library(lubridate)
## 
## Adjuntando el paquete: 'lubridate'
## The following object is masked from 'package:arrow':
## 
##     duration
## The following objects are masked from 'package:base':
## 
##     date, intersect, setdiff, union
# Revisar el período de los datos
range(base_forestal$`AÑO`, na.rm = TRUE)
## [1] 2016 2026
# Revisar las fechas de oficialización
head(base_forestal$OFICIALIZACION, 10)
##  [1] "26/04/2016" "28/04/2016" "01/04/2016" "01/04/2016" "30/03/2016"
##  [6] "31/03/2016" "11/04/2016" "14/04/2016" "01/04/2016" "01/04/2016"
# Revisar los años disponibles
sort(unique(base_forestal$`AÑO`))
##  [1] 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026
# Revisar las operaciones registradas
table(base_forestal$OPERACION)
## 
## EXPORTACION IMPORTACION 
##      149159      804140
library(dplyr)
library(lubridate)

# Correspondencia entre nombres de meses y números
MESNRO <- c(
  ENERO = 1L,
  FEBRERO = 2L,
  MARZO = 3L,
  ABRIL = 4L,
  MAYO = 5L,
  JUNIO = 6L,
  JULIO = 7L,
  AGOSTO = 8L,
  SEPTIEMBRE = 9L,
  OCTUBRE = 10L,
  NOVIEMBRE = 11L,
  DICIEMBRE = 12L
)

base_forestal <- base_forestal %>%
  mutate(
    # Normalizar nombres de meses y convertirlos a números
    MES_TEXTO = toupper(trimws(as.character(MES))),
    MES_NRO = unname(MESNRO[MES_TEXTO]),

    # Convertir el año a entero
    ANIO_NRO = suppressWarnings(
      as.integer(trimws(as.character(AÑO)))
    ),

    # Construir la fecha con el primer día de cada mes
    FECHA = make_date(
      year = ANIO_NRO,
      month = MES_NRO,
      day = 1L
    ),

    MES_FECHA = floor_date(FECHA, unit = "month")
  )

# Comprobar las fechas generadas
summary(base_forestal$FECHA)
##         Min.      1st Qu.       Median         Mean      3rd Qu.         Max. 
## "2016-01-01" "2019-06-01" "2022-07-01" "2022-01-04" "2024-09-01" "2026-08-01"
library(dplyr)
library(ggplot2)
library(lubridate)

# Preparar la cantidad de registros por mes
despachos_mensuales <- base_forestal %>%
  filter(
    !is.na(FECHA),
    FECHA >= as.Date("2016-01-01"),
    FECHA <= Sys.Date()
  ) %>%
  count(MES_FECHA, name = "CANTIDAD_REGISTROS") %>%
  arrange(MES_FECHA)

# Crear el gráfico
grafico_despachos <- ggplot(
  despachos_mensuales,
  aes(x = MES_FECHA, y = CANTIDAD_REGISTROS)
) +
  geom_line(linewidth = 0.6) +
  scale_x_date(
    date_breaks = "6 months",
    date_labels = "%b\n%Y",
    expand = expansion(mult = c(0.01, 0.02))
  ) +
  labs(
    title = "Evolución mensual de los registros forestales",
    subtitle = "Paraguay, desde 2016",
    x = "Mes y año",
    y = "Cantidad de registros"
  ) +
  theme_minimal() +
  theme(
    axis.text.x = element_text(
      angle = 0,
      hjust = 0.5,
      size = 8
    ),
    plot.title = element_text(
      face = "bold",
      size = 14
    )
  )

# Mostrar el gráfico
print(grafico_despachos)

# Guardar el gráfico en formato PNG, con mayor anchura
ggsave(
  filename = "evolucion_mensual.png",
  plot = grafico_despachos,
  width = 16,
  height = 6,
  units = "in",
  dpi = 300
)
despachos_unicos_mensuales <- base_forestal %>%
  filter(
    !is.na(FECHA),
    FECHA >= as.Date("2016-01-01"),
    FECHA <= Sys.Date()
  ) %>%
  group_by(MES_FECHA, OPERACION) %>%
  summarise(
    CANTIDAD_DESPACHOS = n_distinct(`DESPACHO CIFRADO`),
    .groups = "drop"
  )

despachos_unicos_mensuales
## # A tibble: 256 × 3
##    MES_FECHA  OPERACION   CANTIDAD_DESPACHOS
##    <date>     <chr>                    <int>
##  1 2016-01-01 EXPORTACION                254
##  2 2016-01-01 IMPORTACION                860
##  3 2016-02-01 EXPORTACION                246
##  4 2016-02-01 IMPORTACION                898
##  5 2016-03-01 EXPORTACION                270
##  6 2016-03-01 IMPORTACION               1003
##  7 2016-04-01 EXPORTACION                284
##  8 2016-04-01 IMPORTACION                976
##  9 2016-05-01 EXPORTACION                301
## 10 2016-05-01 IMPORTACION               1029
## # ℹ 246 more rows
ggplot(despachos_unicos_mensuales,
       aes(x = MES_FECHA, y = CANTIDAD_DESPACHOS, fill=OPERACION, color=OPERACION)) +
  geom_line(linewidth = 0.6) +
  scale_x_date(
    date_breaks = "6 months",
    date_labels = "%b\n%Y"
  ) +
  labs(
    title = "Evolución mensual de los despachos forestales",
    x = "Mes y año",
    y = "Cantidad de despachos únicos"
  ) +
  theme_minimal() +
  theme(
    axis.text.x = element_text(angle = 0, hjust = 0)
  )

##graficar la evolucion mensual de la cantidad total de despachos en el rubro forestal

library(dplyr)
library(ggplot2)
library(lubridate)

# Contar los despachos únicos por mes
despachos_mensuales <- base_forestal %>%
    filter(
    !is.na(FECHA),
    FECHA >= as.Date("2016-01-01"),
    FECHA <= Sys.Date()
  ) %>%
  group_by(FECHA) %>%
  summarise(
    TOTAL_DESPACHOS = n_distinct(`DESPACHO CIFRADO`),
    .groups = "drop"
  ) %>%
  arrange(FECHA)

despachos_mensuales
## # A tibble: 128 × 2
##    FECHA      TOTAL_DESPACHOS
##    <date>               <int>
##  1 2016-01-01            1114
##  2 2016-02-01            1144
##  3 2016-03-01            1273
##  4 2016-04-01            1260
##  5 2016-05-01            1330
##  6 2016-06-01            1337
##  7 2016-07-01            1349
##  8 2016-08-01            1545
##  9 2016-09-01            1694
## 10 2016-10-01            1453
## # ℹ 118 more rows
# Graficar la evolución mensual
grafico_despachos <- ggplot(
  despachos_mensuales,
  aes(x = FECHA, y = TOTAL_DESPACHOS)
) +
  geom_line(linewidth = 0.1) +
  labs(
    title = "Evolución mensual de los despachos forestales",
    subtitle = "Paraguay, desde 2016",
    x = "Mes y año",
    y = "Cantidad de despachos únicos"
  ) +
  scale_x_date(
    date_breaks = "6 months",
    date_labels = "%b\n%Y",
    expand = expansion(mult = c(0.01, 0.02))
  ) +
  theme_minimal() +
  theme(
    axis.text.x = element_text(size = 8),
    plot.title = element_text(face = "bold")
  )

print(grafico_despachos)

ggsave(
  "evolucion_mensual_despachos.png",
  grafico_despachos,
  width = 16, height = 6, units = "in", dpi = 300
)

##Graficar el peso

# Función para convertir números con coma decimal
convertir_numero <- function(x) {
  x <- gsub(",", ".", x, fixed = TRUE)
  as.numeric(x)
}

base_forestal <- base_forestal %>%
  mutate(
    KILO_NETO_NUM = convertir_numero(`KILO NETO`)
  )
# Sumar el peso neto por mes
peso_anual <- base_forestal %>%
      filter(
    !is.na(FECHA),
    FECHA >= as.Date("2016-01-01"),
    FECHA <= as.Date("2025-12-31")
  ) %>%
  group_by(FECHA, OPERACION) %>%
  summarise(
    PESO_NETO_TOTAL = sum(KILO_NETO_NUM, na.rm = TRUE),
    .groups = "drop"
  ) %>%
  arrange(FECHA)

peso_anual
## # A tibble: 240 × 3
##    FECHA      OPERACION   PESO_NETO_TOTAL
##    <date>     <chr>                 <dbl>
##  1 2016-01-01 EXPORTACION       15619928.
##  2 2016-01-01 IMPORTACION       40691470.
##  3 2016-02-01 EXPORTACION       25980688.
##  4 2016-02-01 IMPORTACION       37673416.
##  5 2016-03-01 EXPORTACION       22217641.
##  6 2016-03-01 IMPORTACION       41515634.
##  7 2016-04-01 EXPORTACION       19748512.
##  8 2016-04-01 IMPORTACION       33496608.
##  9 2016-05-01 EXPORTACION       22737818.
## 10 2016-05-01 IMPORTACION       35511757.
## # ℹ 230 more rows
# Graficar el peso neto mensual
grafico_peso <- ggplot(
  peso_anual,
  aes(x = FECHA, y = PESO_NETO_TOTAL, fill=OPERACION, colour = OPERACION)
) +
  geom_line(linewidth = 0.6) +
  labs(
    title = "Evolución mensual del peso neto forestal",
    x = "Mes y año",
    y = "Peso neto total (kg)"
  ) +
  scale_x_date(
    date_breaks = "12 months",
    date_labels = "%b\n%Y",
    expand = expansion(mult = c(0.01, 0.02))
  ) +
  theme_minimal() +
  theme(
    axis.text.x = element_text(size = 8),
    plot.title = element_text(face = "bold")
  )

print(grafico_peso)

ggsave(
  "evolucion_mensual_peso.png",
  grafico_peso,
  width = 16, height = 6, units = "in", dpi = 300
)

##Graficar los precios

# Convertir FOB DOLAR a numérico
base_forestal$`FOB DOLAR` <- as.numeric(
  gsub(",", ".", base_forestal$`FOB DOLAR`, fixed = TRUE)
)
quantile(
  base_forestal$`FOB DOLAR`,
  probs = c(0.90, 0.95, 0.99),
  na.rm = TRUE
)
##       90%       95%       99% 
##  58846.22  92232.10 165830.62
# Convertir el valor FOB a número
base_forestal <- base_forestal %>%
  mutate(
    FOB_DOLAR_NUM = convertir_numero(`FOB DOLAR`)
  )

# Sumar el valor FOB por mes
fob_mensual <- base_forestal %>%
  filter(!is.na(MES_FECHA)) %>%
  group_by(MES_FECHA) %>%
  summarise(
    FOB_TOTAL = sum(FOB_DOLAR_NUM, na.rm = TRUE),
    .groups = "drop"
  ) %>%
  arrange(MES_FECHA)

# Graficar el valor FOB mensual
grafico_fob <- ggplot(
  fob_mensual,
  aes(x = MES_FECHA, y = FOB_TOTAL)
) +
  geom_line(linewidth = 0.6) +
  labs(
    title = "Evolución mensual del valor FOB forestal",
    x = "Mes y año",
    y = "Valor FOB total (US$)"
  ) +
  scale_x_date(
    date_breaks = "6 months",
    date_labels = "%b\n%Y",
    expand = expansion(mult = c(0.01, 0.02))
  ) +
  scale_y_continuous(
    labels = scales::label_number(
      big.mark = ".",
      decimal.mark = ","
    )
  ) +
  theme_minimal() +
  theme(
    axis.text.x = element_text(size = 8),
    plot.title = element_text(face = "bold")
  )

print(grafico_fob)

ggsave(
  "evolucion_mensual_valor_fob.png",
  grafico_fob,
  width = 16, height = 6, units = "in", dpi = 300
)

##Explorar modelos de series de tiempo para identificar tendencias y pronosticar

library(dplyr)
library(ggplot2)
library(lubridate)
library(tidyr)
library(forecast)

# Contar despachos únicos por mes
serie_despachos <- base_forestal %>%
  filter(
    !is.na(MES_FECHA),
    MES_FECHA >= as.Date("2016-01-01")
  ) %>%
  group_by(MES_FECHA) %>%
  summarise(
    TOTAL_DESPACHOS = n_distinct(`DESPACHO CIFRADO`),
    .groups = "drop"
  ) %>%
  arrange(MES_FECHA)

# Completar los meses sin registros
serie_despachos <- serie_despachos %>%
  complete(
    MES_FECHA = seq(
      min(MES_FECHA),
      max(MES_FECHA),
      by = "month"
    ),
    fill = list(TOTAL_DESPACHOS = 0)
  ) %>%
  arrange(MES_FECHA)

# Visualizar la serie
head(serie_despachos)
## # A tibble: 6 × 2
##   MES_FECHA  TOTAL_DESPACHOS
##   <date>               <int>
## 1 2016-01-01            1114
## 2 2016-02-01            1144
## 3 2016-03-01            1273
## 4 2016-04-01            1260
## 5 2016-05-01            1330
## 6 2016-06-01            1337
#Visualización de la tendencia
ggplot(serie_despachos,
       aes(x = MES_FECHA, y = TOTAL_DESPACHOS)) +

  geom_line(linewidth = 0.6) +

  geom_smooth(
    method = "loess",
    se = FALSE,
    color = "red",
    linewidth = 0.8
  ) +

  scale_x_date(
    date_breaks = "6 months",
    date_labels = "%b\n%Y"
  ) +

  labs(
    title = "Tendencia de los despachos forestales",
    subtitle = "Evolución mensual y tendencia suavizada",
    x = "Mes y año",
    y = "Cantidad de despachos únicos"
  ) +

  theme_minimal()
## `geom_smooth()` using formula = 'y ~ x'

#Construcción de la serie temporal 
# Convertir los datos a una serie temporal
serie_ts <- ts(
  serie_despachos$TOTAL_DESPACHOS,
  start = c(
    year(min(serie_despachos$MES_FECHA)),
    month(min(serie_despachos$MES_FECHA))
  ),
  frequency = 12
)

# Visualizar la serie
plot(
  serie_ts,
  main = "Serie temporal de los despachos forestales",
  xlab = "Año",
  ylab = "Cantidad de despachos",
  col = "blue"
)

#Descomposición de la serie temporal en tres componentes:
#Tendencia, Estacionalidad, irregularidad.
# Descomposición de la serie
descomposicion <- decompose(
  serie_ts,
  type = "additive"
)

# Graficar componentes
plot(descomposicion)

#Ajuste y comparación de modelos ARIMA y ets
# Ajustar modelo ARIMA
modelo_arima <- auto.arima(
  serie_ts,
  seasonal = TRUE,
  stepwise = FALSE,
  approximation = FALSE
)

# Ajustar modelo ETS
modelo_ets <- ets(serie_ts)

# Consultar resultados
summary(modelo_arima)
## Series: serie_ts 
## ARIMA(0,1,1) with drift 
## 
## Coefficients:
##           ma1    drift
##       -0.8956  17.1180
## s.e.   0.0388   7.0359
## 
## sigma^2 = 507005:  log likelihood = -1014.16
## AIC=2034.32   AICc=2034.52   BIC=2042.85
## 
## Training set error measures:
##                    ME     RMSE      MAE       MPE     MAPE      MASE
## Training set 4.824346 703.6488 297.4142 -3.962797 12.58593 0.6842124
##                     ACF1
## Training set -0.08224028
summary(modelo_ets)
## ETS(M,Ad,M) 
## 
## Call:
## ets(y = serie_ts)
## 
##   Smoothing parameters:
##     alpha = 0.0792 
##     beta  = 0.0303 
##     gamma = 1e-04 
##     phi   = 0.9334 
## 
##   Initial states:
##     l = 1283.1376 
##     b = 19.8694 
##     s = 1.019 1.0114 1.0746 1.0258 1.0112 1.0017
##            0.9153 0.8854 0.8366 1.5459 0.847 0.8262
## 
##   sigma:  0.216
## 
##      AIC     AICc      BIC 
## 2203.404 2209.680 2254.741 
## 
## Training set error measures:
##                    ME     RMSE      MAE       MPE     MAPE      MASE
## Training set 7.331563 661.4497 326.8266 -1.828576 14.03981 0.7518769
##                     ACF1
## Training set -0.05919977
# Comparar criterios AICc
comparacion_modelos <- data.frame(
  Modelo = c("ARIMA", "ETS"),
  AICc = c(
    modelo_arima$aicc,
    modelo_ets$aicc
  )
)

comparacion_modelos
##   Modelo     AICc
## 1  ARIMA 2034.517
## 2    ETS 2209.680
#RESIDUOS
# Diagnóstico de residuos ARIMA
checkresiduals(modelo_arima)

## 
##  Ljung-Box test
## 
## data:  Residuals from ARIMA(0,1,1) with drift
## Q* = 8.3383, df = 23, p-value = 0.9977
## 
## Model df: 1.   Total lags used: 24
# Diagnóstico de residuos ETS
checkresiduals(modelo_ets)

## 
##  Ljung-Box test
## 
## data:  Residuals from ETS(M,Ad,M)
## Q* = 9.6983, df = 24, p-value = 0.9957
## 
## Model df: 0.   Total lags used: 24
#Pronóstico para los próximos 12 meses
# Seleccionar el modelo ARIMA
modelo_final <- modelo_arima

# Generar pronóstico para los próximos 12 meses
pronostico <- forecast(
  modelo_final,
  h = 12,
  level = c(80, 95)
)

# Consultar resultados
pronostico
##          Point Forecast    Lo 80    Hi 80    Lo 95    Hi 95
## Sep 2026       3459.180 2546.661 4371.699 2063.602 4854.758
## Oct 2026       3476.298 2558.822 4393.774 2073.140 4879.456
## Nov 2026       3493.416 2571.011 4415.821 2082.719 4904.113
## Dec 2026       3510.534 2583.225 4437.843 2092.337 4928.731
## Jan 2027       3527.652 2595.465 4459.839 2101.995 4953.308
## Feb 2027       3544.770 2607.731 4481.809 2111.692 4977.847
## Mar 2027       3561.888 2620.021 4503.754 2121.428 5002.348
## Apr 2027       3579.006 2632.337 4525.675 2131.200 5026.811
## May 2027       3596.124 2644.676 4547.571 2141.010 5051.237
## Jun 2027       3613.242 2657.039 4569.444 2150.857 5075.627
## Jul 2027       3630.360 2669.426 4591.293 2160.739 5099.980
## Aug 2027       3647.478 2681.836 4613.119 2170.657 5124.299
# Graficar pronóstico
autoplot(pronostico) +

  labs(
    title = "Pronóstico de los despachos forestales",
    subtitle = "Modelo ARIMA - Horizonte de 12 meses",
    x = "Año",
    y = "Cantidad de despachos únicos"
  ) +

  theme_minimal()

##Participacion de los rubros, clasificación según mayor incidencia

#Resumen de participación por rubro
participacion_rubros <- base_forestal %>%

  filter(
    !is.na(RUBRO),
    OPERACION %in% c("IMPORTACION", "EXPORTACION")
  ) %>%

  group_by(OPERACION, RUBRO) %>%

  summarise(
    TOTAL_DESPACHOS = n_distinct(`DESPACHO CIFRADO`),

    PESO_TOTAL = sum(
      KILO_NETO_NUM,
      na.rm = TRUE
    ),

    FOB_TOTAL = sum(
      FOB_DOLAR_NUM,
      na.rm = TRUE
    ),

    .groups = "drop"
  ) %>%

  group_by(OPERACION) %>%

  mutate(
    PARTICIPACION_DESPACHOS =
      100 * TOTAL_DESPACHOS / sum(TOTAL_DESPACHOS),

    PARTICIPACION_PESO =
      100 * PESO_TOTAL / sum(PESO_TOTAL),

    PARTICIPACION_FOB =
      100 * FOB_TOTAL / sum(FOB_TOTAL)
  ) %>%

  ungroup() %>%

  arrange(OPERACION, desc(FOB_TOTAL))

participacion_rubros
## # A tibble: 12 × 8
##    OPERACION   RUBRO TOTAL_DESPACHOS PESO_TOTAL FOB_TOTAL PARTICIPACION_DESPAC…¹
##    <chr>       <chr>           <int>      <dbl>     <dbl>                  <dbl>
##  1 EXPORTACION PAPE…           33361     1.35e9   1.36e 9                32.5   
##  2 EXPORTACION MADE…           23279     1.24e9   1.02e 9                22.7   
##  3 EXPORTACION CARB…           44516     1.94e9   8.05e 8                43.3   
##  4 EXPORTACION CAPI…            1508     7.50e7   1.53e 7                 1.47  
##  5 EXPORTACION CAPI…              88     6.98e3   9.69e 5                 0.0856
##  6 EXPORTACION CAPI…              14     2.24e3   4.04e 4                 0.0136
##  7 IMPORTACION PAPE…          148272     5.81e9   1.66e10                78.6   
##  8 IMPORTACION MADE…           31232     1.89e9   1.14e 9                16.5   
##  9 IMPORTACION CAPI…            7606     2.50e8   7.40e 7                 4.03  
## 10 IMPORTACION CAPI…             870     2.40e6   2.10e 7                 0.461 
## 11 IMPORTACION CARB…             238     8.26e6   6.40e 6                 0.126 
## 12 IMPORTACION CAPI…             509     3.66e5   1.41e 6                 0.270 
## # ℹ abbreviated name: ¹​PARTICIPACION_DESPACHOS
## # ℹ 2 more variables: PARTICIPACION_PESO <dbl>, PARTICIPACION_FOB <dbl>
#Clasificación de los rubros según su incidencia económica
ranking_rubros <- participacion_rubros %>%

  group_by(OPERACION) %>%

  arrange(desc(FOB_TOTAL), .by_group = TRUE) %>%

  mutate(
    CLASIFICACION = paste0(
      "Puesto ",
      row_number()
    )
  ) %>%

  ungroup()

ranking_rubros
## # A tibble: 12 × 9
##    OPERACION   RUBRO TOTAL_DESPACHOS PESO_TOTAL FOB_TOTAL PARTICIPACION_DESPAC…¹
##    <chr>       <chr>           <int>      <dbl>     <dbl>                  <dbl>
##  1 EXPORTACION PAPE…           33361     1.35e9   1.36e 9                32.5   
##  2 EXPORTACION MADE…           23279     1.24e9   1.02e 9                22.7   
##  3 EXPORTACION CARB…           44516     1.94e9   8.05e 8                43.3   
##  4 EXPORTACION CAPI…            1508     7.50e7   1.53e 7                 1.47  
##  5 EXPORTACION CAPI…              88     6.98e3   9.69e 5                 0.0856
##  6 EXPORTACION CAPI…              14     2.24e3   4.04e 4                 0.0136
##  7 IMPORTACION PAPE…          148272     5.81e9   1.66e10                78.6   
##  8 IMPORTACION MADE…           31232     1.89e9   1.14e 9                16.5   
##  9 IMPORTACION CAPI…            7606     2.50e8   7.40e 7                 4.03  
## 10 IMPORTACION CAPI…             870     2.40e6   2.10e 7                 0.461 
## 11 IMPORTACION CARB…             238     8.26e6   6.40e 6                 0.126 
## 12 IMPORTACION CAPI…             509     3.66e5   1.41e 6                 0.270 
## # ℹ abbreviated name: ¹​PARTICIPACION_DESPACHOS
## # ℹ 3 more variables: PARTICIPACION_PESO <dbl>, PARTICIPACION_FOB <dbl>,
## #   CLASIFICACION <chr>
#GRÁFICO DE LOS RUBROS
library(ggplot2)
library(dplyr)
library(forcats)

grafico_rubros <- ranking_rubros %>%

  group_by(OPERACION) %>%

  slice_max(
    order_by = PARTICIPACION_FOB,
    n = 10,
    with_ties = FALSE
  ) %>%

  ungroup() %>%

  ggplot(
    aes(
      x = PARTICIPACION_FOB,
      y = fct_reorder(RUBRO, PARTICIPACION_FOB)
    )
  ) +

  geom_col(width = 0.7) +

  geom_text(
    aes(label = paste0(round(PARTICIPACION_FOB, 1), "%")),
    hjust = -0.2,
    size = 3.5
  ) +

  facet_wrap(~OPERACION, scales = "free_y") +

  scale_x_continuous(
    labels = function(x) paste0(x, "%"),
    expand = expansion(mult = c(0, 0.15))
  ) +

  labs(
    title = "Participación de los rubros forestales",
    subtitle = "Principales rubros según valor FOB",
    x = "Participación del valor FOB",
    y = "Rubro"
  ) +

  theme_minimal() +

  theme(
    plot.title = element_text(face = "bold", size = 14),
    axis.text.y = element_text(size = 9),
    strip.text = element_text(face = "bold"),
    panel.spacing = unit(1.5, "lines")
  )

print(grafico_rubros)

ggsave(
  "participacion_rubros.png",
  grafico_rubros,
  width = 14,
  height = 8,
  dpi = 300
)
#tABLA SEGÚN PESO
ranking_peso <- participacion_rubros %>%

  group_by(OPERACION) %>%

  arrange(desc(PESO_TOTAL), .by_group = TRUE) %>%

  mutate(
    PUESTO_PESO = row_number()
  ) %>%

  ungroup()

ranking_peso
## # A tibble: 12 × 9
##    OPERACION   RUBRO TOTAL_DESPACHOS PESO_TOTAL FOB_TOTAL PARTICIPACION_DESPAC…¹
##    <chr>       <chr>           <int>      <dbl>     <dbl>                  <dbl>
##  1 EXPORTACION CARB…           44516     1.94e9   8.05e 8                43.3   
##  2 EXPORTACION PAPE…           33361     1.35e9   1.36e 9                32.5   
##  3 EXPORTACION MADE…           23279     1.24e9   1.02e 9                22.7   
##  4 EXPORTACION CAPI…            1508     7.50e7   1.53e 7                 1.47  
##  5 EXPORTACION CAPI…              88     6.98e3   9.69e 5                 0.0856
##  6 EXPORTACION CAPI…              14     2.24e3   4.04e 4                 0.0136
##  7 IMPORTACION PAPE…          148272     5.81e9   1.66e10                78.6   
##  8 IMPORTACION MADE…           31232     1.89e9   1.14e 9                16.5   
##  9 IMPORTACION CAPI…            7606     2.50e8   7.40e 7                 4.03  
## 10 IMPORTACION CARB…             238     8.26e6   6.40e 6                 0.126 
## 11 IMPORTACION CAPI…             870     2.40e6   2.10e 7                 0.461 
## 12 IMPORTACION CAPI…             509     3.66e5   1.41e 6                 0.270 
## # ℹ abbreviated name: ¹​PARTICIPACION_DESPACHOS
## # ℹ 3 more variables: PARTICIPACION_PESO <dbl>, PARTICIPACION_FOB <dbl>,
## #   PUESTO_PESO <int>

##Participación de los países según el peso neto

paises_forestales <- base_forestal %>%

  filter(
    OPERACION %in% c("IMPORTACION", "EXPORTACION")
  ) %>%

  select(
    OPERACION,
    KILO_NETO_NUM,
    FOB_DOLAR_NUM,
    `DESPACHO CIFRADO`,
    `PAIS PROCEDENCIA/DESTINO`
  ) %>%

  mutate(
    PAIS = as.character(`PAIS PROCEDENCIA/DESTINO`),

    # Normalizar espacios
    PAIS = stringr::str_squish(PAIS),

    # Eliminar siglas iniciales
    PAIS = stringr::str_remove(
      PAIS,
      "^[A-Z]{2,3}\\s*-\\s*"
    ),

    # Convertir a mayúsculas conservando ñ y tildes
    PAIS = stringr::str_to_upper(PAIS),

    # Identificar valores faltantes
    PAIS = na_if(PAIS, ""),

    PAIS = ifelse(
      is.na(PAIS),
      "SIN INFORMACION",
      PAIS
    )
  )
#participación por país
participacion_paises <- paises_forestales %>%

  group_by(OPERACION, PAIS) %>%

  summarise(

    TOTAL_DESPACHOS = n_distinct(`DESPACHO CIFRADO`),

    PESO_TOTAL = sum(
      KILO_NETO_NUM,
      na.rm = TRUE
    ),

    FOB_TOTAL = sum(
      FOB_DOLAR_NUM,
      na.rm = TRUE
    ),

    .groups = "drop"

  ) %>%

  group_by(OPERACION) %>%

  mutate(

    PARTICIPACION_PESO =
      100 * PESO_TOTAL / sum(PESO_TOTAL),

    PARTICIPACION_FOB =
      100 * FOB_TOTAL / sum(FOB_TOTAL),

    PARTICIPACION_DESPACHOS =
      100 * TOTAL_DESPACHOS / sum(TOTAL_DESPACHOS)

  ) %>%

  ungroup() %>%

  arrange(OPERACION, desc(PESO_TOTAL))

participacion_paises
## # A tibble: 230 × 8
##    OPERACION   PAIS      TOTAL_DESPACHOS PESO_TOTAL FOB_TOTAL PARTICIPACION_PESO
##    <chr>       <chr>               <int>      <dbl>     <dbl>              <dbl>
##  1 EXPORTACION "BRASIL"            20587 778783666.    5.17e8              16.9 
##  2 EXPORTACION "REINO U…            6501 604753922.    4.76e8              13.1 
##  3 EXPORTACION "CHILE"             12959 555232789.    3.71e8              12.1 
##  4 EXPORTACION "ARGENTI…            9590 469270869.    4.09e8              10.2 
##  5 EXPORTACION "ESTADOS…           10493 331238751.    2.71e8               7.20
##  6 EXPORTACION "ALEMANI…            3479 327235093.    1.20e8               7.11
##  7 EXPORTACION "URUGUAY"            8596 258750284.    1.15e8               5.62
##  8 EXPORTACION "ISRAEL"             2804 139158381.    5.53e7               3.02
##  9 EXPORTACION "ARABIA …            2210 113675838.    4.99e7               2.47
## 10 EXPORTACION "ESPA\\A"            2764  91822985.    4.28e7               1.99
## # ℹ 220 more rows
## # ℹ 2 more variables: PARTICIPACION_FOB <dbl>, PARTICIPACION_DESPACHOS <dbl>
#Ranking de los principales países
ranking_paises <- participacion_paises %>%

  group_by(OPERACION) %>%

  slice_max(
    order_by = PESO_TOTAL,
    n = 10,
    with_ties = FALSE
  ) %>%

  arrange(
    OPERACION,
    desc(PESO_TOTAL)
  ) %>%

  mutate(
    RANKING = row_number()
  ) %>%

  ungroup()

ranking_paises
## # A tibble: 20 × 9
##    OPERACION   PAIS      TOTAL_DESPACHOS PESO_TOTAL FOB_TOTAL PARTICIPACION_PESO
##    <chr>       <chr>               <int>      <dbl>     <dbl>              <dbl>
##  1 EXPORTACION "BRASIL"            20587     7.79e8    5.17e8              16.9 
##  2 EXPORTACION "REINO U…            6501     6.05e8    4.76e8              13.1 
##  3 EXPORTACION "CHILE"             12959     5.55e8    3.71e8              12.1 
##  4 EXPORTACION "ARGENTI…            9590     4.69e8    4.09e8              10.2 
##  5 EXPORTACION "ESTADOS…           10493     3.31e8    2.71e8               7.20
##  6 EXPORTACION "ALEMANI…            3479     3.27e8    1.20e8               7.11
##  7 EXPORTACION "URUGUAY"            8596     2.59e8    1.15e8               5.62
##  8 EXPORTACION "ISRAEL"             2804     1.39e8    5.53e7               3.02
##  9 EXPORTACION "ARABIA …            2210     1.14e8    4.99e7               2.47
## 10 EXPORTACION "ESPA\\A"            2764     9.18e7    4.28e7               1.99
## 11 IMPORTACION "BRASIL"            98872     4.65e9    5.85e9              58.4 
## 12 IMPORTACION "ARGENTI…           17280     8.65e8    1.56e9              10.9 
## 13 IMPORTACION "CHINA"             19612     5.00e8    7.94e8               6.27
## 14 IMPORTACION "ESPA\\A"            2537     2.89e8    2.82e9               3.63
## 15 IMPORTACION "ESPANA"             2240     2.68e8    2.15e9               3.37
## 16 IMPORTACION "ESTADOS…            9216     2.15e8    1.90e9               2.70
## 17 IMPORTACION "FINLAND…             662     1.55e8    1.46e8               1.95
## 18 IMPORTACION "AUSTRIA"             803     1.50e8    1.24e8               1.88
## 19 IMPORTACION "URUGUAY"            3459     1.36e8    3.63e8               1.71
## 20 IMPORTACION "POLONIA"             155     1.28e8    7.49e7               1.61
## # ℹ 3 more variables: PARTICIPACION_FOB <dbl>, PARTICIPACION_DESPACHOS <dbl>,
## #   RANKING <int>
#Grafico de los países
grafico_paises <- ranking_paises %>%

  ggplot(
    aes(
      x = PARTICIPACION_PESO,
      y = forcats::fct_reorder(PAIS, PARTICIPACION_PESO)
    )
  ) +

  geom_col(width = 0.7) +

  geom_text(
    aes(
      label = paste0(
        round(PARTICIPACION_PESO, 1),
        "%"
      )
    ),
    hjust = -0.2,
    size = 3
  ) +

  facet_wrap(
    ~OPERACION,
    scales = "free_y"
  ) +

  scale_x_continuous(
    labels = function(x) paste0(x, "%"),
    expand = expansion(mult = c(0, 0.15))
  ) +

  labs(
    title = "Principales países de procedencia y destino",
    subtitle = "Participación según peso neto de los productos forestales",
    x = "Participación del peso neto (%)",
    y = "País"
  ) +

  theme_minimal() +

  theme(
    plot.title = element_text(face = "bold", size = 14),
    axis.text.y = element_text(size = 9),
    strip.text = element_text(face = "bold")
  )

print(grafico_paises)

ggsave(
  "principales_paises_forestales.png",
  grafico_paises,
  width = 12,
  height = 8,
  dpi = 300
)
#bbdd por rubro y pais de procedencia/destino
library(dplyr)
library(stringr)
library(ggplot2)
library(forcats)
library(scales)

# Preparar los datos
paises_rubros <- base_forestal %>%
  filter(OPERACION %in% c("IMPORTACION", "EXPORTACION")) %>%
  mutate(
    PAIS = as.character(`PAIS PROCEDENCIA/DESTINO`),
    PAIS = str_squish(PAIS),
    PAIS = str_remove(PAIS, "^[A-Z]{2,3}\\s*-\\s*"),
    PAIS = str_to_upper(PAIS),
    PAIS = na_if(PAIS, ""),
    PAIS = ifelse(is.na(PAIS), "SIN INFORMACION", PAIS),
    RUBRO = as.character(RUBRO),
    RUBRO = str_squish(RUBRO),
    RUBRO = ifelse(is.na(RUBRO) | RUBRO == "",
                   "SIN INFORMACION", RUBRO)
  )

# Agrupar por operación, país y rubro
resumen_paises_rubros <- paises_rubros %>%
  group_by(OPERACION, PAIS, RUBRO) %>%
  summarise(
    PESO_NETO = sum(KILO_NETO_NUM, na.rm = TRUE),
    .groups = "drop"
  )

# Calcular la participación de cada rubro dentro de cada país
resumen_paises_rubros <- resumen_paises_rubros %>%
  group_by(OPERACION, PAIS) %>%
  mutate(
    PESO_TOTAL_PAIS = sum(PESO_NETO, na.rm = TRUE),
    PARTICIPACION = (PESO_NETO / PESO_TOTAL_PAIS) * 100
  ) %>%
  ungroup()
#rubros por país
top_rubros_pais <- resumen_paises_rubros %>%
  group_by(OPERACION, PAIS) %>%
  slice_max(
    order_by = PESO_NETO,
    n = 5,
    with_ties = FALSE
  ) %>%
  arrange(OPERACION, PAIS, desc(PESO_NETO)) %>%
  ungroup()

# Visualizar resultados
View(top_rubros_pais)
#Ranking 10 países por operación

Resultados

Rerencias