1. Introducción

Este es mi tercer cuaderno de R Markdown. Aquí se obtienen estadísticas de varios años para los grupos de cultivos del departamento del Cesar, y después se analiza con más detalle el municipio de Valledupar. La fuente principal de datos son las Evaluaciones Agropecuarias Municipales (EVA), un conjunto de datos agrícolas publicado por el Ministerio de Agricultura y Desarrollo Rural.

2. Configuración

En este paso se cargan las librerías necesarias.

# si no están instaladas, ejecutar desde la consola (una sola vez):
# install.packages('tidyverse')

library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.2.1     ✔ readr     2.2.0
## ✔ forcats   1.0.1     ✔ stringr   1.6.0
## ✔ ggplot2   4.0.3     ✔ tibble    3.3.1
## ✔ lubridate 1.9.5     ✔ tidyr     1.3.2
## ✔ purrr     1.2.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(dplyr)
library(readr)
library(ggplot2)

3. Lectura del conjunto de datos EVA

El siguiente bloque de código indica en dónde estoy trabajando:

getwd()
## [1] "D:/MI PC/GB02/Proyecto6"

El siguiente bloque de código muestra los archivos csv que hay en mi carpeta de trabajo:

list.files(".", pattern = c('csv'))
## [1] "Evaluaciones_Agropecuarias_Municipales_EVA.csv"

Ahora leo el conjunto de datos EVA:

# ajustar la ruta del archivo según donde esté mi archivo
(eva = read_csv("./Evaluaciones_Agropecuarias_Municipales_EVA.csv", col_names = TRUE,
                show_col_types = FALSE))

Es muy importante saber cuáles son los nombres que el software “ve”, que pueden ser distintos de los que yo veo en pantalla:

names(eva)
##  [1] "CÓD. \nDEP."                                  
##  [2] "DEPARTAMENTO"                                 
##  [3] "CÓD. MUN."                                    
##  [4] "MUNICIPIO"                                    
##  [5] "GRUPO \nDE CULTIVO"                           
##  [6] "SUBGRUPO \nDE CULTIVO"                        
##  [7] "CULTIVO"                                      
##  [8] "DESAGREGACIÓN REGIONAL Y/O SISTEMA PRODUCTIVO"
##  [9] "AÑO"                                          
## [10] "PERIODO"                                      
## [11] "Área Sembrada\n(ha)"                          
## [12] "Área Cosechada\n(ha)"                         
## [13] "Producción\n(t)"                              
## [14] "Rendimiento\n(t/ha)"                          
## [15] "ESTADO FISICO PRODUCCION"                     
## [16] "NOMBRE \nCIENTIFICO"                          
## [17] "CICLO DE CULTIVO"

4. Limpieza del conjunto de datos EVA

Selecciono algunos atributos para limpiar el objeto eva:

# revisar el objeto del último bloque y cambiar los nombres de atributos según mis datos
eva %>% dplyr::select('CÓD. MUN.':'ESTADO FISICO PRODUCCION') -> eva.tmp
eva.tmp

Reviso la salida y verifico que solo se seleccionaron las columnas relevantes.

Ahora cambio los nombres de las columnas que tienen espacios o caracteres “ruidosos”:

# asegurarse de usar los nombres de columnas que aparecen en names(eva)
eva.tmp %>% dplyr::rename('Cod_Mun' = 'CÓD. MUN.',
                          'Grupo' = 'GRUPO \nDE CULTIVO',
                          'Subgrupo' = 'SUBGRUPO \nDE CULTIVO',
                          'Year' = 'AÑO',
                          'AreaSembrada' = 'Área Sembrada\n(ha)',
                          'AreaCosechada' = 'Área Cosechada\n(ha)',
                          'Produccion' = 'Producción\n(t)',
                          'Rendimiento' = 'Rendimiento\n(t/ha)',
                          'Sistema' = 'DESAGREGACIÓN REGIONAL Y/O SISTEMA PRODUCTIVO',
                          'Estado' = 'ESTADO FISICO PRODUCCION') -> new_eva

Reviso la salida:

new_eva

Verifico que los atributos cuantitativos estén guardados como numéricos (no como texto). Si alguno aparece como texto, lo convierto:

new_eva$Year          = as.numeric(new_eva$Year)
new_eva$AreaSembrada  = as.numeric(new_eva$AreaSembrada)
new_eva$AreaCosechada = as.numeric(new_eva$AreaCosechada)
new_eva$Produccion    = as.numeric(new_eva$Produccion)
new_eva$Rendimiento   = as.numeric(new_eva$Rendimiento)
## Warning: NAs introducidos por coerción
str(new_eva)
## tibble [5,191 × 13] (S3: tbl_df/tbl/data.frame)
##  $ Cod_Mun      : num [1:5191] 20 20.4 20.6 20.6 20.8 ...
##  $ MUNICIPIO    : chr [1:5191] "VALLEDUPAR" "LA JAGUA DE IBIRICO" "LA PAZ" "PUEBLO BELLO" ...
##  $ Grupo        : chr [1:5191] "FRUTALES" "FRUTALES" "FRUTALES" "FRUTALES" ...
##  $ Subgrupo     : chr [1:5191] "AGUACATE" "AGUACATE" "AGUACATE" "AGUACATE" ...
##  $ CULTIVO      : chr [1:5191] "AGUACATE" "AGUACATE" "AGUACATE" "AGUACATE" ...
##  $ Sistema      : chr [1:5191] "AGUACATE" "AGUACATE" "AGUACATE" "AGUACATE" ...
##  $ Year         : num [1:5191] 2.01 2.01 2.01 2.01 2.01 ...
##  $ PERIODO      : chr [1:5191] "2007" "2007" "2007" "2007" ...
##  $ AreaSembrada : num [1:5191] 713 430 300 105 90 65 60 33 30 18 ...
##  $ AreaCosechada: num [1:5191] 713 430 300 103 80 65 40 33 30 18 ...
##  $ Produccion   : num [1:5191] 5.7 2.15 3 830 640 ...
##  $ Rendimiento  : num [1:5191] 8 5 10 NA 8 NA 8 7 8 8 ...
##  $ Estado       : chr [1:5191] "FRUTO FRESCO" "FRUTO FRESCO" "FRUTO FRESCO" "FRUTO FRESCO" ...

El siguiente bloque de código muestra el periodo de tiempo que cubren los datos:

range(new_eva$Year, na.rm = TRUE)
## [1] 2.006 2.018

5. Análisis de datos

Muchas tareas de análisis de datos se pueden abordar con el paradigma split-apply-combine: se divide el conjunto de datos en grupos, se aplica algún análisis a cada grupo y luego se combinan los resultados.

La librería dplyr hace esto muy fácil con la función group_by(), que divide los datos en grupos. Cuando los datos están agrupados, summarize() se puede usar para reducir cada grupo a un resumen de una sola fila.

5.1 Los cultivos más importantes en el Cesar

Por ejemplo, para saber la producción total por grupo de cultivos escribo:

new_eva %>%
  filter(Produccion > 0) %>%
  group_by(Grupo) %>%
  summarize(total_produccion = sum(Produccion)) %>%
  arrange(desc(total_produccion))

Para guardar la producción total en un objeto:

new_eva %>%
  group_by(Grupo) %>%
  summarize(total_produccion = sum(Produccion, na.rm = TRUE)) -> PT

Para filtrar los grupos más importantes (dejo los 5 con mayor producción):

PT %>%
  arrange(desc(total_produccion)) %>%
  head(5) -> main.groups
main.groups

Para conocer la producción total de los grupos principales de cultivos:

(value = sum(main.groups$total_produccion))
## [1] 932837.3

Para agregar un nuevo atributo con el porcentaje de la producción total:

main.groups$percent = main.groups$total_produccion/value

Para crear un gráfico de torta de la producción total de main.groups:

library(ggplot2)
# Barplot
bp <- ggplot(main.groups, aes(x = "", y = percent, fill = Grupo)) +
  geom_bar(width = 1, stat = "identity")
# Piechart
pie <- bp + coord_polar("y", start = 0)
pie

5.2 Municipios con mayor producción

Para saber qué municipios lideran la producción de cada grupo de cultivos:

new_eva %>%
  group_by(Grupo, MUNICIPIO) %>%
  summarize(total_prod = sum(Produccion, na.rm = TRUE)) %>%
  slice(which.max(total_prod)) %>%
  arrange(desc(total_prod))
## `summarise()` has regrouped the output.
## ℹ Summaries were computed grouped by Grupo and MUNICIPIO.
## ℹ Output is grouped by Grupo.
## ℹ Use `summarise(.groups = "drop_last")` to silence this message.
## ℹ Use `summarise(.by = c(Grupo, MUNICIPIO))` for per-operation grouping
##   (`?dplyr::dplyr_by`) instead.

Para guardar el objeto:

new_eva %>%
  group_by(Grupo, MUNICIPIO) %>%
  summarize(total_prod = sum(Produccion, na.rm = TRUE)) %>%
  slice(which.max(total_prod)) -> leaders
## `summarise()` has regrouped the output.
## ℹ Summaries were computed grouped by Grupo and MUNICIPIO.
## ℹ Output is grouped by Grupo.
## ℹ Use `summarise(.groups = "drop_last")` to silence this message.
## ℹ Use `summarise(.by = c(Grupo, MUNICIPIO))` for per-operation grouping
##   (`?dplyr::dplyr_by`) instead.

Veo el objeto leaders:

leaders

Filtro los líderes más importantes (los 5 con mayor producción):

leaders %>%
  arrange(desc(total_prod)) %>%
  head(5) -> main.leaders
main.leaders

Grafico los líderes filtrados:

# Basic barplot
p <- ggplot(data = main.leaders, aes(x = MUNICIPIO, y = total_prod)) +
  geom_bar(stat = "identity")
p

5.3 Dinámica de un cultivo importante en Valledupar

Primero miro los cultivos de Valledupar con mayor producción total:

new_eva %>%
  filter(MUNICIPIO == "VALLEDUPAR") %>%
  group_by(CULTIVO) %>%
  summarize(total = sum(Produccion, na.rm = TRUE)) %>%
  arrange(desc(total)) -> cultivos_vd
cultivos_vd

Escojo el cultivo con mayor producción en Valledupar:

(cultivo_foco = cultivos_vd$CULTIVO[1])
## [1] "CACAO"

Selecciono los datos de ese cultivo en Valledupar, año por año:

new_eva %>%
  filter(MUNICIPIO == "VALLEDUPAR" & CULTIVO == cultivo_foco) %>%
  group_by(Year, CULTIVO) %>%
  summarize(Produccion = sum(Produccion, na.rm = TRUE)) -> valledupar_cultivo
## `summarise()` has regrouped the output.
## ℹ Summaries were computed grouped by Year and CULTIVO.
## ℹ Output is grouped by Year.
## ℹ Use `summarise(.groups = "drop_last")` to silence this message.
## ℹ Use `summarise(.by = c(Year, CULTIVO))` for per-operation grouping
##   (`?dplyr::dplyr_by`) instead.
valledupar_cultivo

Hago un gráfico rápido de la producción para todo el periodo cubierto por EVA:

g <- ggplot(aes(x = Year, y = Produccion/1000), data = valledupar_cultivo) +
  geom_bar(stat = 'identity') +
  labs(y = 'Produccion [Ton x 1000]')
g

Agrego un título y visualizo:

g + ggtitle(paste("Evolución de la producción de", cultivo_foco, "en Valledupar")) +
  labs(caption = "Basado en datos EVA (Minagricultura)")

6. Análisis y gráficos adicionales

He ilustrado algunos ejemplos de análisis. Se pueden analizar otras variables además de la producción (por ejemplo rendimiento, areacosechada, areasembrada).

El siguiente bloque grafica el área sembrada del mismo cultivo en Valledupar:

ggplot(aes(x = Year, y = AreaSembrada),
       data = new_eva %>% filter(MUNICIPIO == "VALLEDUPAR" & CULTIVO == cultivo_foco)) +
  geom_bar(stat = 'identity') +
  labs(y = 'Área sembrada [ha]')

7. Bibliografía

Este trabajo se basó en el cuaderno: Lizarazo, I., 2022. Understanding dynamic productivity of crops. Disponible en https://rpubs.com/ials2un/production_dyn_v1.

Fuente de datos: Ministerio de Agricultura y Desarrollo Rural. Evaluaciones Agropecuarias Municipales (EVA). datos.gov.co.

sessionInfo()
## R version 4.6.1 (2026-06-24 ucrt)
## Platform: x86_64-w64-mingw32/x64
## Running under: Windows 11 x64 (build 22000)
## 
## Matrix products: default
##   LAPACK version 3.12.1
## 
## locale:
## [1] LC_COLLATE=Spanish_Colombia.utf8  LC_CTYPE=Spanish_Colombia.utf8   
## [3] LC_MONETARY=Spanish_Colombia.utf8 LC_NUMERIC=C                     
## [5] LC_TIME=Spanish_Colombia.utf8    
## 
## time zone: America/Bogota
## tzcode source: internal
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
##  [1] lubridate_1.9.5 forcats_1.0.1   stringr_1.6.0   dplyr_1.2.1    
##  [5] purrr_1.2.2     readr_2.2.0     tidyr_1.3.2     tibble_3.3.1   
##  [9] ggplot2_4.0.3   tidyverse_2.0.0
## 
## loaded via a namespace (and not attached):
##  [1] bit_4.6.0          gtable_0.3.6       jsonlite_2.0.0     crayon_1.5.3      
##  [5] compiler_4.6.1     tidyselect_1.2.1   parallel_4.6.1     jquerylib_0.1.4   
##  [9] scales_1.4.0       yaml_2.3.12        fastmap_1.2.0      R6_2.6.1          
## [13] labeling_0.4.3     generics_0.1.4     knitr_1.52         bslib_0.12.0      
## [17] pillar_1.11.1      RColorBrewer_1.1-3 tzdb_0.5.0         rlang_1.3.0       
## [21] stringi_1.8.9      cachem_1.1.0       xfun_0.62          sass_0.4.10       
## [25] S7_0.2.2           bit64_4.8.6        otel_0.2.0         timechange_0.4.0  
## [29] cli_3.6.6          withr_3.0.3        magrittr_2.0.5     digest_0.6.39     
## [33] grid_4.6.1         vroom_1.7.1        rstudioapi_0.19.0  hms_1.1.4         
## [37] lifecycle_1.0.5    vctrs_0.7.3        evaluate_1.0.5     glue_1.8.1        
## [41] farver_2.1.2       rmarkdown_2.32     tools_4.6.1        pkgconfig_2.0.3   
## [45] htmltools_0.5.9