Este es el tercer Cuaderno R Markdown para el curso Geomática Básica 2026-2. Ilustra cómo obtener estadísticas multianuales para un grupo dado de cultivos en cualquier departamento. Usaremos como fuente principal de datos las Evaluaciones Agropecuarias Municipales (EVA), un conjunto de datos agropecuarios 2007-2018 proporcionado por el Ministerio de Agricultura y Desarrollo Rural. En mi caso, el análisis se hace para el departamento del Cesar.
En este paso, instalaremos y cargaremos las librerías de R requeridas.
# ejecute las siguientes líneas desde la línea de comandos:
#install.packages('dplyr')
#install.packages('readxl')
#install.packages('sf')
knitr::opts_chunk$set(message = FALSE, warning = FALSE)
options(dplyr.summarise.inform = FALSE)
library(tidyverse)
library(dplyr)
library(readr)
library(ggplot2)
# función auxiliar: escribe los números con punto de miles
fmt <- function(x) format(round(x), big.mark = ".", decimal.mark = ",", scientific = FALSE)
Vaya a https://www.datos.gov.co/Agricultura-y-Desarrollo-Rural/Evaluaciones-Agropecuarias-Municipales-EVA/2pnw-mmge/data para encontrar el conjunto de datos. En el sitio enlazado (es decir, datos.gov.co), visualice los datos y aplique un filtro para obtener solo los datos correspondientes a su departamento. Luego, exporte los datos en formato csv. Ahora, vaya a la carpeta de descargas para encontrar el archivo Evaluaciones_Agropecuarias_Municipales_EVA.csv. Muévalo a su directorio de trabajo.
list.files(".", pattern=c('csv'))
## [1] "Evaluaciones_Agropecuarias_Municipales_EVA_20261110.csv"
Ahora, procedamos a leer el conjunto de datos EVA:
# ajuste la ruta del archivo de acuerdo con sus datos
# (aquí el código busca solo el archivo CSV de EVA en la carpeta de trabajo)
archivo <- list.files(".", pattern = "^(CULTIVO_CESAR|Evaluaciones_Agropecuarias).*\\.csv$")[1]
# revisión: el archivo no debe tener bytes vacíos (archivo dañado)
bytes <- readBin(archivo, "raw", n = file.size(archivo))
if (sum(bytes == as.raw(0)) > 0) {
stop("El archivo CSV está dañado (tiene bytes vacíos). Descárguelo de nuevo y cópielo a la carpeta del proyecto.")
}
# el archivo tiene encabezados con saltos de línea, así que se leen las líneas
# y se asignan los nombres de columna manualmente
lineas <- read_lines(archivo, locale = locale(encoding = "UTF-8"))
ini <- grep('^"?[0-9]+"?,"', lineas)[1]
nombres_eva <- c("CÓD. \nDEP.", "DEPARTAMENTO", "CÓD. MUN.", "MUNICIPIO",
"GRUPO \nDE CULTIVO", "SUBGRUPO \nDE CULTIVO", "CULTIVO",
"DESAGREGACIÓN REGIONAL Y/O SISTEMA PRODUCTIVO", "AÑO", "PERIODO",
"Área Sembrada\n(ha)", "Área Cosechada\n(ha)", "Producción\n(t)",
"Rendimiento\n(t/ha)", "ESTADO FISICO PRODUCCION",
"NOMBRE \nCIENTIFICO", "CICLO DE CULTIVO")
(eva <- read_csv(I(paste(lineas[ini:length(lineas)], collapse = "\n")),
col_names = nombres_eva,
col_types = cols(.default = col_character())))
Visualice la tabla y confirme que contiene estadísticas agropecuarias para diferentes años. ¿Puede decir cuál es el período de tiempo de estos datos?
Respuesta: los datos van del año 2006 al 2018. La tabla tiene 5.191 registros.
Es muy importante saber cuáles son los nombres que el software “ve”. Pueden ser diferentes de los que vemos nosotros. Averigüémoslo:
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"
Seleccionemos algunos atributos para limpiar el objeto eva:
# revise la salida del chunk anterior y
# cambie los nombres de los atributos de acuerdo con sus propios datos
eva %>%
dplyr::select('CÓD. MUN.':'ESTADO FISICO PRODUCCION') -> eva.tmp
eva.tmp
Revise la salida y verifique que solo se seleccionaron las columnas relevantes.
Respuesta: sí, quedaron solo las columnas que van desde el código del municipio hasta el estado físico de la producción.
Ahora, cambiemos los nombres de varias columnas que contienen caracteres vacíos o “ruidosos”:
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
Revisemos la salida:
new_eva
Revise la tabla anterior y verifique que los atributos cuantitativos estén almacenados como tipos de datos numéricos (no como cadenas de texto).
Respuesta: en mi archivo esos atributos estaban como texto, porque los números vienen con formato colombiano (punto para los miles y coma para los decimales). Por eso los convertí a numéricos. Además, el archivo trae algunas filas de La Guajira, así que dejé solo las del Cesar:
new_eva <- new_eva %>%
mutate(across(c(Year, AreaSembrada, AreaCosechada, Produccion, Rendimiento),
~ parse_number(as.character(.x), locale = locale(decimal_mark = ",", grouping_mark = "."))))
if ("DEPARTAMENTO" %in% names(new_eva)) {
new_eva <- new_eva %>% filter(DEPARTAMENTO == "CESAR")
}
new_eva
Después de este paso quedan 5.191 registros del Cesar y los atributos cuantitativos ya son numéricos.
Muchas tareas de análisis de datos pueden abordarse usando el
paradigma split-apply-combine (dividir-aplicar-combinar):
dividir los datos en grupos, aplicar algún análisis a cada grupo y luego
combinar los resultados. La librería dplyr hace esto muy fácil mediante
el uso de la función group_by(), que divide los datos en
grupos. Cuando los datos están agrupados de esta manera,
summarize() puede usarse para colapsar cada grupo en un
resumen de una sola fila. summarize() hace esto aplicando
una función de agregación o resumen a cada grupo.
Por ejemplo, si queremos averiguar la producción total por grupo de cultivos, escribimos:
new_eva %>%
##filter(Produccion > 0) %>%
group_by(Grupo) %>%
summarize(total_produccion = sum(Produccion)) %>%
arrange(desc(total_produccion))
Note que la producción total contiene la suma de la producción de cada grupo de cultivos entre 2007 y 2018. En el Cesar, los dos cultivos con mayor producción fueron “OLEAGINOSAS” (2.043.635 t) y “CEREALES” (1.840.165 t).
Para guardar la producción total en un objeto:
new_eva %>%
group_by(Grupo) %>%
summarize(total_produccion = sum(Produccion)) -> PT
Para filtrar los cultivos más importantes:
PT %>%
filter(total_produccion > 1000000) -> main.groups
main.groups
Para conocer la producción total de los principales grupos de cultivos:
(value = sum(main.groups$total_produccion))
## [1] 4995277
Para agregar un nuevo atributo con el porcentaje de la producción total:
main.groups$percent = main.groups$total_produccion/value
main.groups
Para crear un gráfico de torta de la producción total de main.groups:
library(ggplot2)
# Gráfico de barras
bp<- ggplot(main.groups, aes(x="", y=percent, fill=Grupo))+
geom_bar(width = 1, stat = "identity")
# Gráfico de torta
pie <- bp + coord_polar("y", start=0)
pie
En la torta se ve que las oleaginosas son la mayor parte de lo que producen los tres grupos principales (40.9 %). Los cereales tienen 36.8 % y los tubérculos y plátanos 22.3 %.
Para averiguar los municipios líderes en la producción de cada cultivo entre 2007 y 2018:
new_eva %>%
group_by(Grupo, MUNICIPIO) %>%
summarize(total_prod = sum(Produccion, na.rm = TRUE)) %>%
slice(which.max(total_prod)) %>%
arrange(desc(total_prod))
Para guardar el objeto:
new_eva %>%
group_by(Grupo, MUNICIPIO) %>%
summarize(total_prod = sum(Produccion, na.rm = TRUE)) %>%
slice(which.max(total_prod)) -> leaders
leaders
Para filtrar los municipios más importantes desde el punto de vista agrícola:
leaders %>%
filter(total_prod > 50000) -> main.leaders
main.leaders
Graficuemos los líderes filtrados:
# Gráfico de barras básico
p<-ggplot(data=main.leaders, aes(x=MUNICIPIO, y=total_prod)) +
geom_bar(stat="identity") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
p
El municipio que más produce en un solo grupo es El Copey, con 410.045 t de oleaginosas. Cada grupo tiene un municipio líder distinto.
El cultivo y el municipio se escogen automáticamente: son los de mayor producción total en el Cesar.
top_mc <- new_eva %>%
group_by(MUNICIPIO, CULTIVO) %>%
summarize(total = sum(Produccion, na.rm = TRUE), .groups = "drop") %>%
arrange(desc(total)) %>%
slice(1)
new_eva %>%
filter(MUNICIPIO == top_mc$MUNICIPIO & CULTIVO == top_mc$CULTIVO) %>%
group_by(Year, CULTIVO) %>%
select(MUNICIPIO, CULTIVO, Produccion, Year) -> cesar_cultivo
Revisemos la salida:
cesar_cultivo
Hagamos un gráfico rápido de la producción de palma de aceite en El Copey para todo el período de tiempo cubierto por el conjunto de datos EVA:
g <- ggplot(aes(x = Year, y = Produccion/1000), data = cesar_cultivo) +
geom_bar(stat = 'identity') +
labs(y = paste('Produccion de', str_to_title(top_mc$CULTIVO), '[Ton x 1000]'))
Agreguemos un título y visualicemos:
g + ggtitle(paste("Evolución de la Producción del Cultivo de", str_to_title(top_mc$CULTIVO),
"en", str_to_title(top_mc$MUNICIPIO), "de 2007 a 2018")) +
labs(caption = "Basado en datos EVA (Minagricultura, 2020)")
El Copey produjo en total 410.045 toneladas de palma de aceite en el período, y en el gráfico se ve cómo fue cambiando la producción de un año a otro.
He ilustrado unos pocos ejemplos de análisis. Podría analizar otras variables distintas a producción (por ejemplo rendimiento, áreacosechada, áreasembrada). A continuación hago algunos análisis adicionales sobre el departamento del Cesar.
El cultivo que más se produce en todo el departamento es la palma de aceite, con 2.043.585 toneladas. Eso es el 29.5 % de toda la producción registrada en el Cesar. Después vienen arroz (1.162.426 t) y yuca (703.132 t).
Figura: cultivo de palma de aceite
La palma de aceite es un cultivo permanente, es decir, una vez sembrada sigue produciendo durante muchos años. Veamos cómo cambió en todo el departamento:
new_eva %>%
filter(CULTIVO == top_cultivo) %>%
group_by(Year) %>%
summarize(AreaSembrada = sum(AreaSembrada, na.rm = TRUE),
Produccion = sum(Produccion, na.rm = TRUE)) -> palma_anual
palma_anual %>%
pivot_longer(c(AreaSembrada, Produccion), names_to = "Variable", values_to = "Valor") %>%
mutate(Variable = recode(Variable,
AreaSembrada = "Área sembrada [ha]",
Produccion = "Producción [t]")) %>%
ggplot(aes(x = Year, y = Valor)) +
geom_line() +
geom_point() +
facet_wrap(~Variable, scales = "free_y") +
scale_x_continuous(breaks = seq(2007, 2018, 3)) +
labs(x = "Año", y = "", title = "Palma de aceite en el Cesar: área sembrada y producción",
caption = "Basado en datos EVA (Minagricultura, 2020)")
Entre 2007 y 2018 la producción de palma de aceite pasó de 117.922 a 249.741 toneladas, es decir, se multiplicó por 2.1. El área sembrada también creció, de 38.352 a 94.664 hectáreas. Parece que la producción subió sobre todo porque se sembró más área.
new_eva %>%
group_by(MUNICIPIO) %>%
summarize(total = sum(Produccion, na.rm = TRUE)) %>%
arrange(desc(total)) %>%
slice(1:10) -> top_mun
ggplot(top_mun, aes(x = reorder(str_to_title(MUNICIPIO), total), y = total/1000)) +
geom_bar(stat = "identity") +
coord_flip() +
labs(x = "Municipio", y = "Producción total [Ton x 1000]",
title = "Los 10 municipios con mayor producción agrícola del Cesar",
caption = "Basado en datos EVA (Minagricultura, 2020)")
Los municipios que más producen son Valledupar (689.518 t) y El Copey (681.890 t). Entre los diez primeros suman el 63.7 % de la producción del departamento.
new_eva %>%
filter(Year >= 2007) %>%
group_by(Year) %>%
summarize(total = sum(Produccion, na.rm = TRUE)) -> prod_anual
ggplot(prod_anual, aes(x = Year, y = total/1000)) +
geom_line() +
geom_point() +
scale_x_continuous(breaks = 2007:2018) +
labs(x = "Año", y = "Producción total [Ton x 1000]",
title = "Producción agrícola total del Cesar por año",
caption = "Basado en datos EVA (Minagricultura, 2020)")
La producción total del departamento está entre 471.076 y 639.521 toneladas por año. El año con más producción fue 2017 y el de menos fue 2010. El año 2006 no se incluyó en este gráfico porque en el archivo tiene muy pocos registros.
En el Cesar la mayor parte de la producción agrícola viene de tres grupos: oleaginosas, cereales y tubérculos y plátanos. La palma de aceite es el cultivo que más se produce y creció bastante entre 2007 y 2018, sobre todo porque aumentó el área sembrada. La producción se concentra en pocos municipios, entre ellos Valledupar y El Copey, y cada grupo de cultivos tiene un municipio líder distinto.
Lizarazo, I., 2022. Understanding dynamic productivity of crops. Disponible en https://rpubs.com/ials2un/production_dyn_v1.
Ministerio de Agricultura y Desarrollo Rural, 2020. Evaluaciones Agropecuarias Municipales (EVA). Datos Abiertos Colombia. https://www.datos.gov.co/Agricultura-y-Desarrollo-Rural/Evaluaciones-Agropecuarias-Municipales-EVA/2pnw-mmge/data
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