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.
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)
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"
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
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.
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
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
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)")
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]')
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