library(dplyr)
library(tidyr)
library(ggplot2)
library(scales)
library(gt)
library(here)
library(purrr)
library(treemapify)
library(strucchange)
library(patchwork)
library(stringr)
library(patchwork)
# --- Opciones globales de chunk ----------------------------------------------
# fig.pos = "H" (paquete float, cargado en el YAML) ancla cada figura donde
# aparece en el código en vez de dejar que LaTeX la flote a otra página; sin
# esto, un documento con tantas figuras termina con la mayoría amontonadas al
# final. out.extra = "" evita que knitr agregue su propio float por defecto,
# que pisaría el "H" de arriba.
knitr::opts_chunk$set(fig.pos = "H", out.extra = "")
# --- Parámetros --------------------------------------------------------------
año_min <- 2010
año_max_hs4 <- 2023 # Etapa A --- ver nota sobre los dos cortes en el encabezado
año_max_hs6 <- 2023 # Etapa B --- ídem, por razón distinta
n_top <- 10 # exportadores/importadores a retener, por universo
rank_window <- 3 # el ranking de exportadores se arma sobre los últimos k años
base_años <- año_min:(año_min + 2) # base del índice: promedio trienal
otros_lab <- "Otros exportadores"
# El residuo se llama "Otros exportadores" y no "Resto del mundo" porque las
# bases conservan el destino: "resto del mundo" se leería como lado socio.
caption_ancho <- 150 # ancho de la nota de fuente, en caracteres
label_min_pct <- 0.04 # no rotular tajadas por debajo de este umbral
# --- Formateadores -----------------------------------------------------------
# Un solo formateador de porcentajes, sobre proporciones.
pct_es <- label_percent(accuracy = 1, decimal.mark = ",")
num_es <- label_number(accuracy = 1, big.mark = ".", decimal.mark = ",")
# --- Tema --------------------------------------------------------------------
tema_drp <- theme_bw(base_size = 11) +
theme(
panel.grid.minor = element_blank(),
legend.position = "right",
legend.key.width = unit(1.2, "lines"),
plot.caption = element_text(hjust = 0, size = 7.5, colour = "grey35"),
plot.title = element_text(face = "bold")
)
# --- Utilidades comunes ------------------------------------------------------
envolver <- function(x) paste(strwrap(x, width = caption_ancho), collapse = "\n")
# Todas las figuras estándar (9x5.5) se guardan por acá. Las que necesitan otro
# tamaño (los treemaps consolidados, más abajo) llaman ggsave() directamente.
# NOTA: en desuso -- los chunks nuevos usan ggsave() explícito, a mano, sin
# wrapper (ver recent_updates). Se conserva acá sólo mientras quedan chunks
# viejos sin migrar; se borra cuando el último de ellos se actualice.
guardar <- function(p, nombre) {
ggsave(here::here("Plots", paste0(nombre, ".png")), p,
width = 9, height = 5.5, dpi = 300, bg = "white")
}
# --- Diccionario de nombres de país ------------------------------------------
# Único punto de traducción de nombres de país en todo el archivo. Se usa tanto
# del lado exportador/importador como del lado destino/origen.
lab_pais <- c(
# Productores de palma
"Malaysia" = "Malasia", "Indonesia" = "Indonesia", "Thailand" = "Tailandia",
"Papua New Guinea" = "PNGuinea", "Guatemala" = "Guatemala",
"Colombia" = "Colombia", "Costa Rica" = "CR", "Honduras" = "Honduras",
"Côte d'Ivoire" = "Marfil", "Cote d'Ivoire" = "Marfil", "Gabon" = "Gabón",
"Ecuador" = "Ecuador", "Nigeria" = "Nigeria", "Brazil" = "Brasil",
"Cameroon" = "Camerún", "Ghana" = "Ghana", "Angola" = "Angola",
"Mozambique" = "Mozamb.",
# Refinadores y puertos de entrada europeos
"Netherlands" = "PBajos", "Germany" = "Alemania", "Italy" = "Italia",
"Spain" = "España", "Belgium" = "Bélgica", "France" = "Francia",
"Denmark" = "Dinamarca", "Switzerland" = "Suiza", "Estonia" = "Estonia",
"United Kingdom" = "ReinoU", "Portugal" = "Portugal", "Poland" = "Polonia",
# Otros destinos y reexportadores
"USA" = "EUA", "United States of America" = "EUA",
"Dominican Rep." = "RDom", "Dominican Republic" = "RDom",
"Pakistan" = "Pakistán", "Kenya" = "Kenia", "India" = "India",
"China" = "China", "Djibouti" = "Yibuti",
"Türkiye" = "Turquía", "Turkey" = "Turquía",
"United Arab Emirates" = "Emiratos",
"Morocco" = "Marruec.", "El Salvador" = "ElSalv.", "Singapore" = "Singap.",
"United Rep. of Tanzania" = "Tanzania",
# Compradores de refinado (mercados de consumo masivo)
"Bangladesh" = "Bangla.", "Philippines" = "Filip.", "Egypt" = "Egipto",
"Russian Federation" = "Rusia", "Viet Nam" = "Vietnam",
"Saudi Arabia" = "ArabSau", "Myanmar" = "Myanmar", "Japan" = "Japón",
"Ethiopia" = "Etiopía", "Rep. of Korea" = "Corea", "South Africa" = "Sudáf.",
"Iran" = "Irán", "Afghanistan" = "Afgan.", "Togo" = "Togo"
)
# Devuelve el nombre original si no está en la tabla: un país nuevo aparece en
# inglés en la figura, que se ve y se corrige agregando una línea arriba, en
# lugar de convertirse en NA, que se pierde.
es_pais <- function(x) {
y <- unname(lab_pais[x])
if_else(is.na(y), x, y)
}
# --- Paleta de origen/destino (treemaps) -------------------------------------
# Paleta desaturada, tipo prensa económica: sin rosados ni magentas, tonos
# tierra y azules apagados en vez de colores saturados de librería. Se usa en
# CUALQUIER treemap de país (origen o destino), acá y en las dos secciones de
# treemaps más abajo, para que el mismo país conserve el mismo tono en todas
# las figuras del documento.
paleta_origen <- c(
"#2E5C8A", "#8C6B4F", "#4A7C6F", "#B0673A", "#5B6B8C",
"#7C9885", "#A67C52", "#3D6B7D", "#8B5A6B", "#6B7A3D",
"#9B8B5A", "#4F6D8C", "#7A5C4F", "#5A7A6B", "#8C7A9B"
)
gris_residuo <- "#B8B4AE"
# --- Aceites vegetales, Sección 1 (Etapa A) ----------------------------------
# Compartidos por las dos figuras de líneas y las dos de composición; no
# dependen de ningún dato cargado, así que viven acá y no en un chunk de carga.
oil_es <- c(
"1511" = "Palma",
"1507" = "Soya",
"1514" = "Colza / canola",
"1512" = "Girasol y algodón",
"1513" = "Coco y palmiste"
)
# La palma lleva el color de acento en las cinco figuras de la Sección 1; los
# aceites competidores quedan apagados.
oil_cols <- c(
"Palma" = "#C77B1F",
"Soya" = "#2E5E4E",
"Colza / canola" = "#7C9885",
"Girasol y algodón" = "#4F6D7A",
"Coco y palmiste" = "#A8A29E"
)
caption_hs4 <- envolver(paste(
"Fuente: elaboración propia con base en UN Comtrade, exportaciones HS4 al mundo,",
paste0(año_min, "-", año_max_hs4, "."),
"Se excluye 2024 porque Indonesia no aparece entre los reportantes de ese año.",
"Comercio registrado: incluye reexportación."
))
# --- Aceite de palma, Sección 3 (Etapa B: crudo/refinado) --------------------
# Alimentan prácticamente todos los outputs de la Etapa B (composición,
# índices, tablas, valor, paneles, treemaps de destino). No dependen de
# `palm` ni de ningún otro dato cargado, sólo de objetos ya definidos arriba
# (otros_lab, es_pais(), envolver(), año_min, año_max_hs6).
lab_aceite <- c(crudo = "crudo", refinado = "refinado")
# Costa Rica lleva el color de acento --- rojo brillante --- CUANDO clasifica
# en el top-10 (no se fuerza su inclusión). Los demás exportadores quedan
# apagados. OJO: acento distinto del de la Sección 1 (que marca a la palma,
# no a Costa Rica) -- mismo concepto, colores intencionalmente distintos.
col_acento <- "#E01B24"
paleta_paises <- c(
"#1F4E79", "#1B9E77", "#B5179E", "#7FB3D5", "#4D7C0F",
"#7570B3", "#8C6B4F", "#86C5A0", "#666666", "#4B0082"
)
# Los colores se asignan sobre los NIVELES DEL FACTOR de la base --- es decir,
# sobre el orden del ranking --- y no sobre el orden de cada figura, para que
# un mismo país no cambie de color entre la figura de índices y la de
# composición.
colores_de <- function(df) {
niveles <- levels(df$exportador)
cr <- es_pais("Costa Rica")
resto <- setdiff(niveles, c(cr, otros_lab))
cols <- setNames(rep_len(paleta_paises, length(resto)), resto)
if (cr %in% niveles) cols[cr] <- col_acento
cols[otros_lab] <- "#D6D3D1"
cols
}
# Un solo caption para las figuras de la Etapa B. Cambia únicamente la
# subpartida; la advertencia sobre reexportación es común, porque el universo
# también lo es.
caption_fuente <- function(tipo) {
envolver(paste(
"Fuente: elaboración propia con base en UN Comtrade, HS",
if (tipo == "crudo") "1511.10," else "1511.90,",
paste0(año_min, "-", año_max_hs6, "."),
"Se excluye 2024 por cobertura incompleta de reportantes en esta base.",
"Comercio registrado: incluye reexportación, de modo que el aceite que pasa por un",
"puerto intermedio se cuenta más de una vez.",
"Valor FOB en US$ corrientes, sin deflactar: la serie mezcla cambios de precio y de volumen.",
"El crudo y el refinado son universos distintos y no se suman."
))
}
# Tabla_países() no depende de ningún dato cargado --- opera sobre el df que
# recibe --- y la usan dos chunks de tabla independientes (Tablas 1 y 2), así
# que vive acá.
tabla_países <- function(df, tipo, numero_tabla) {
países <- setdiff(levels(df$exportador), otros_lab)
df |>
filter(exportador %in% países) |>
summarise(valor_mm = sum(valor_usd, na.rm = TRUE) / 1e6,
.by = c(ref_year, exportador)) |>
pivot_wider(names_from = ref_year, values_from = valor_mm) |>
arrange(exportador) |>
gt(rowname_col = "exportador") |>
tab_header(
title = paste0("Tabla ", numero_tabla, ". Exportaciones de aceite de palma ",
lab_aceite[[tipo]], ", por exportador"),
subtitle = paste0("Valor exportado, millones de US$, ", año_min, "-", año_max_hs6)
) |>
fmt_number(columns = -exportador, decimals = 0, dec_mark = ",", sep_mark = ".") |>
tab_options(table.font.size = px(11)) |>
tab_source_note(caption_fuente(tipo))
}
# --- USDA, oferta/consumo/uso industrial (razones y quiebres) ----------------
# Compartidos por las dos series de paneles USDA (razones de exportación y
# consumo/uso industrial) dentro de plot_sec5.
# obtener_quiebre() opera sobre el df que recibe como argumento, no sobre
# ningún dato cargado acá; caption_quiebres tampoco depende de datos.
# breaks = 1 fuerza una única partición óptima; tryCatch cubre series casi
# constantes donde el modelo no converge.
obtener_quiebre <- function(df) {
bp <- tryCatch(
breakpoints(valor ~ marketYear, data = df, breaks = 1),
error = function(e) NULL
)
if (is.null(bp) || is.na(bp$breakpoints[1])) return(NA_integer_)
df$marketYear[bp$breakpoints[1]]
}
caption_quiebres <- envolver(paste(
"Fuente: elaboración propia con base en USDA FAS, PSD Online (Palm Oil), 2000-2025.",
"Recta de tendencia ajustada por MCO, en dos tramos cuando un test de quiebre",
"estructural (paquete strucchange, breakpoints) detecta una partición óptima;",
"la línea punteada cobre marca el año del quiebre. Sin quiebre detectado, el",
"ajuste es una sola recta para toda la serie."
))
col_quiebre <- "#B0673A" # línea de quiebre estructural, en las dos figuras de paneles USDA
El aceite de palma forma parte de un mercado mayor, el mercado de aceites vegetales comestibles (y cuyos subproductos tienen en algunos casos usos en otras industrias, tales como la producción de cosméticos, alimento animal y otros). Conviene dar una mirada a ese mercado antes de analizar específicamente el mercado de aceite de palma, para entender el contexto competitivo en el que se desenvuelve el aceite de palma. El comportamiento de los precios, altamente correlacionados como se muestra más adelante, hace evidente que los diversos tipos de aceite vegetal son sustitutos cercanos unos de otros, por lo que esta mirada general es necesaria como contexto para el resto de nuestro trabajo.
La Figura 1 muestra la evolución del valor de las exportaciones de aceite de palma, girasol y algodón, canola, soya, y coco y palmiste (estos últimos se reportan como una sola línea en el sistema armonizado, que no permite separar los datos correspondientes a palmiste). Como estos datos están expresados en términos de valor, reflejan tanto el volumen de las exportaciones como las variaciones en los precios. Desde el punto de vista de Costa Rica, un país que por el volumen de su producción y sus exportaciones es un “tomador de precios” en el mercado de aceite de palma crudo, el dato de precio es el más importante. A un precio dado, el país debería de ser capaz de exportar toda la oferta que tenga disponible.
# Autocontenido salvo por oil_es/oil_cols/caption_hs4, que viven en setup
# (no dependen de datos, y los comparte con etapa_a_fig_composicion). Todo lo
# que sí depende de vegoil_world se recarga acá.
#
# Numeración manual ("Figura N." en el título), no vía bookdown: ver nota en
# el encabezado del archivo.
vegoil_world <- readRDS(here::here("Data", "vegoil_world_totals_2010_2024.rds")) |>
filter(ref_year >= año_min, ref_year <= año_max_hs4)
orden_codigos <- vegoil_world |>
filter(ref_year == max(ref_year)) |>
arrange(desc(export_value_usd)) |>
pull(cmd_code)
orden_aceites <- unname(oil_es[orden_codigos])
plot_df_hs4 <- vegoil_world |>
mutate(
aceite = factor(unname(oil_es[cmd_code]), levels = orden_aceites),
valor_mm = export_value_usd / 1e9,
volumen_m = export_wgt_tonnes / 1e6
) |>
group_by(ref_year) |>
mutate(
part_valor = export_value_usd / sum(export_value_usd, na.rm = TRUE),
part_volumen = export_wgt_tonnes / sum(export_wgt_tonnes, na.rm = TRUE)
) |>
ungroup()
stopifnot(!anyNA(plot_df_hs4$aceite))
lab_valor <- "Valor exportado (miles de millones de US$)"
lab_volumen <- "Volumen exportado (millones de toneladas)"
capas_base_hs4 <- list(
scale_colour_manual(values = oil_cols, name = NULL),
scale_x_continuous(breaks = seq(año_min, año_max_hs4, 2)),
scale_y_continuous(labels = num_es, limits = c(0, NA),
expand = expansion(mult = c(0, 0.05))),
labs(x = NULL),
tema_drp
)
local({
p <- ggplot(plot_df_hs4, aes(ref_year, valor_mm, colour = aceite)) +
geom_line(linewidth = 0.9) +
geom_point(size = 1.4) +
capas_base_hs4 +
labs(
title = "Figura 1. Exportaciones mundiales de aceites vegetales, por valor",
y = lab_valor,
caption = caption_hs4
)
print(p)
ggsave(here::here("Plots", "aceites_valor_linea.png"), p,
width = 9, height = 5.5, dpi = 300, bg = "white")
})
local({
p <- ggplot(plot_df_hs4, aes(ref_year, volumen_m, colour = aceite)) +
geom_line(linewidth = 0.9) +
geom_point(size = 1.4) +
capas_base_hs4 +
labs(
title = "Figura 2. Exportaciones mundiales de aceites vegetales, por volumen",
y = lab_volumen,
caption = caption_hs4
)
print(p)
ggsave(here::here("Plots", "aceites_volumen_linea.png"), p,
width = 9, height = 5.5, dpi = 300, bg = "white")
})
rm(vegoil_world, orden_codigos, orden_aceites, plot_df_hs4,
lab_valor, lab_volumen, capas_base_hs4)
knitr::include_graphics(here::here("Plots", "aceites_valor_linea.png"))
La Figura 2 presenta la información en términos del volumen de exportación de estos mismos tipos de aceite. Esta información es recopilada por Comtrade con ciertos rezagos, ya que los países exportadores no siempre la reportan oportunamente. Esta es la razón por la cual tanto la Figura 1 como la Figura 2 tienen como fecha de corte el año 2023. Aunque existen datos de valor de las exportaciones más recientes, los datos de volumen para los años 2024 en adelante contienen aún numerosas casillas en blanco, por lo que el volumen físico de exportaciones solo puede estimarse, pero no contabilizarse para esos años.
knitr::include_graphics(here::here("Plots", "aceites_volumen_linea.png"))
Vistas en conjunto, las figuras 1 y 2 revelan varias características del mercado de aceites comestibles que vale la pena destacar desde ahora, aunque algunas de ellas serán estudiadas en más detalle más adelante.
Pasamos ahora al análisis directo de los precios, apoyándonos en la base de datos Primary Commodity Prices, del FMI, la cual fe accesada por medio de la plataforma de datos FRED, del Banco de Reserva de Saint Louis, Estados Unidos. Los datos que se presenta en la Figura 3 han sido ajustados por estacionalidad, y aún así muestran obvias variaciones de corto plazo. El ajuste por estacionalidad fue aplicado porque nuestro interés es mostrar las tendencias del mercado, pero la variabilidad en el mercado real sin duda representa un desafío, fuente de oportunidades pero también de riesgos, para los operadores en ese mercado.
En primer lugar, debe notarse el co-movimiento de las series, que se mueven casi de manera paralela. Esto confirma la hipótesis de que es apropiado considerar el mercado de aceites vegetales como una unidad, y tiene la consecuencia práctica de que cambios en la oferta de cualquier tipo de aceite vegetal tendrán impacto sobre los precios de todos los aceites vegetales.
En segundo lugar, la Figura 3 muestra dos “picos” notorios en los precios, el primero alrededor de 2011 y el segundo alrededor de 2023. Las causas de los incrementos en esos dos períodos han sido ampliamente estudiados, y esos estudios son la base sobre la cual se sostiene la proyección de precios crecientes en los próximos años.
El incremento de precios que tiene lugar en 2011 está asociado las condiciones climáticas adversas en Rusia, Ucrania (el principal productor de aceite de girasol) y Kazakhstán (Trostle, 2011, Trostle et al. 2011). Estos autores muestran que los incrementos de precios están generalmente asociados a shocks de oferta producidos por fenómenos meteorológicos, que se ven potenciados cuando van acompañados por incrementos en los precios de los combustibles y políticas públicas, tales como la producción de biocombustibles, que reducen la oferta.
# Chunk único y autocontenido: Figura 3 (niveles) y Figura 4 (dispersión vs.
# Brent) comparten precios_sa y caption_fuente_precios(), así que van juntas
# acá en vez de repartidas en dos chunks con dependencia de orden. Se corre
# línea por línea; una vez guardados los PNG, este chunk pasa a
# echo=TRUE, eval=FALSE.
#
# --- Carga y tidy ------------------------------------------------------------
# El .rds crudo ya viene "largo" por construcción de fredr() (series_id,
# date, value, + vintage de FRED que no se usa acá). Se agrega la capa de
# metadatos -- producto (inglés, snake_case) y unidad -- en un único punto
# de traducción, para no repetir el mapeo series_id -> producto en cada figura.
precios_fred_raw <- readRDS(here::here("Data", "fred_prices.rds"))
productos_fred <- tibble::tribble(
~series_id, ~producto, ~unidad,
"PPOILUSDM", "palm_oil", "USD/tonne",
"PSOILUSDM", "soybean_oil", "USD/tonne",
"PSUNOUSDM", "sunflower_oil", "USD/tonne",
"POILBREUSDM", "brent_crude", "USD/barrel",
"MHHNGSP", "henry_hub_gas", "USD/MMBtu",
"PCU483111483111", "deep_sea_freight", "index (Jun 1988=100)"
)
# Cierre común: el último año en que TODAS las series tienen diciembre.
# Un año parcial en el borde alarga y distorsiona el ajuste estacional, y un
# cierre distinto por serie complicaría alinear las fechas en la dispersión.
último_año_completo <- precios_fred_raw |>
mutate(año = as.integer(format(date, "%Y")),
mes = as.integer(format(date, "%m"))) |>
filter(mes == 12) |>
summarise(año = max(año), .by = series_id) |>
pull(año) |>
min()
precios_tidy <- precios_fred_raw |>
select(series_id, date, value) |>
inner_join(productos_fred, by = "series_id") |>
filter(date >= as.Date("2010-01-01"),
date <= as.Date(paste0(último_año_completo, "-12-01")))
saveRDS(precios_tidy, here::here("Data", "fred_precios_tidy.rds"))
# Ajuste estacional (X-13ARIMA-SEATS vía sa_adj()), por serie, sobre datos ya
# ordenados por fecha dentro de cada grupo.
precios_sa <- precios_tidy |>
arrange(series_id, date) |>
mutate(value = sa_adj(value, date), .by = series_id)
saveRDS(precios_sa, here::here("Data", "fred_precios_sa.rds"))
lab_producto <- c(
palm_oil = "Aceite de palma",
soybean_oil = "Aceite de soya",
sunflower_oil = "Aceite de girasol"
)
colores_aceites <- c(
palm_oil = "#2E5C8A",
soybean_oil = "#4A7C6F",
sunflower_oil = "#B0673A"
)
caption_fuente_precios <- function() {
envolver(paste(
"Fuente: elaboración propia con datos del FMI (Primary Commodity Prices),",
"distribuidos por FRED (Reserva Federal de St. Louis).",
paste0(format(min(precios_sa$date), "%Y"), "-", format(max(precios_sa$date), "%Y"), "."),
"Series ajustadas por estacionalidad (X-13ARIMA-SEATS)."
))
}
# --- Figura 3: niveles --------------------------------------------------------
fig_precios_nivel <- function(df) {
ggplot(df, aes(date, value, colour = producto)) +
geom_vline(xintercept = as.Date(paste0(2010:2025, "-01-01")), colour = "grey85", linewidth = 0.3) +
geom_line(linewidth = 1) +
scale_colour_manual(
values = colores_aceites,
breaks = rev(names(colores_aceites)),
labels = lab_producto,
name = NULL
) +
scale_y_continuous(labels = scales::label_number(accuracy = 1, big.mark = ".", decimal.mark = ","),
limits = c(0, NA), expand = expansion(mult = c(0, 0.05))) +
labs(
title = "Figura 3. Precios internacionales de aceites vegetales",
subtitle = "US$/tonelada, ajustado por estacionalidad",
x = NULL, y = NULL, caption = caption_fuente_precios()
) +
tema_drp
}
p_precios_nivel <- fig_precios_nivel(filter(precios_sa, producto %in% names(lab_producto)))
print(p_precios_nivel)
ggsave(here::here("Plots", "precios_nivel.png"), p_precios_nivel,
width = 9, height = 5.5, dpi = 300, bg = "white")
# --- Figura 4: dispersión vs. Brent ------------------------------------------
r_es <- label_number(accuracy = 0.01, decimal.mark = ",")
fig_dispersión <- function(producto_y, etiqueta_y, numero) {
datos <- precios_sa |>
filter(producto %in% c("palm_oil", producto_y)) |>
select(date, producto, value) |>
pivot_wider(names_from = producto, values_from = value) |>
drop_na()
r <- cor(datos$palm_oil, datos[[producto_y]])
ggplot(datos, aes(.data[["palm_oil"]], .data[[producto_y]])) +
geom_point(alpha = 0.5, colour = "#2E5C8A") +
geom_smooth(method = "lm", se = TRUE, colour = "#B0673A", linewidth = 0.8) +
labs(
title = paste0("Figura ", numero, ". Aceite de palma vs. ", etiqueta_y),
subtitle = paste0("r = ", r_es(r), ", ajustado por estacionalidad"),
x = "Aceite de palma (US$/tonelada)", y = etiqueta_y,
caption = caption_fuente_precios()
) +
tema_drp
}
p_disp_brent <- fig_dispersión("brent_crude", "Brent (US$/barril)", 4)
print(p_disp_brent)
ggsave(here::here("Plots", "precios_disp_palma.png"), p_disp_brent,
width = 9, height = 5.5, dpi = 300, bg = "white")
# --- Limpieza ------------------------------------------------------------------
rm(precios_fred_raw, productos_fred, último_año_completo, precios_tidy,
precios_sa, lab_producto, colores_aceites, caption_fuente_precios,
fig_precios_nivel, p_precios_nivel, r_es, fig_dispersión, p_disp_brent)
knitr::include_graphics(here::here("Plots", "precios_nivel.png"))
El incremento, mucho más marcado, en 2023, está asociado por una parte a la reducción de las exportaciones de aceite de girasol por parte de Ucrania, como resultado de la guerra y las disrupciones en la cadena de suministro que ella cause, así como por restricciones a las exportaciones de aceite de palma por parte de Malasia e Indonesia, y por una severa sequía que redujo las exportaciones de aceite de canola de Canadá y redujo severamente la cosecha de soya en Brasil (Iacurci, 2022, Hamann, 2024).
A pesar de la reducción en los precios alrededor de 2024, el gravamen a la exportación de aceite de palma crudo en Indonesia, el incremento de la demanda de biocombustibles, así como el incremento tendencial de los precios del petróleo como resultado de la guerra en Irán y las restricciones al flujo de petróleo a través de los estrechos de Hormuz y Bab-el-Mandeb, seguirán ejerciendo presión al alza en los precios de los aceites vegetales.
La asociación entre el precio del petróleo y el del aceite de palma se muestra en la Figura 4. A pesar de una considerable dispersión alrededor de la linea de tendencia, el coeficiente de correlación, de 0.53, es elevado, y aunque no se realiza aqui una prueba estadística rigurosa, parece evidente que la causalidad va de los precios del petróleo hacia el del aceite de palma, sin descontar, por supuesto, el impacto de otros factores.
knitr::include_graphics(here::here("Plots", "precios_disp_palma.png"))
Ahora bien, aunque la diferencia entre el peso del aceite de palma y cualquier otro aceite vegetal considerado individualmente es muy grande, y eso es justamente lo que muestran las dos figuras 1 y 2, la pregunta más interesante desde el punto de vista de este estudio es más bien la del peso del aceite de palma dentro del mercado total de aceites vegetales.
Las figuras 5 y 6 permiten responder esa pregunta: en términos de valor el aceite de palma representa aproximadamente el 50% del mercado total, con ligeras oscilaciones pero sin tendencia ni al incremento ni a la disminución de este porcentaje, y desde el punto de vista del volumen representa un porcentaje ligeramente mayor, pero también estable, del 55%.
En otras palabras: el mercado de aceites vegetales comestibles es un mercado en crecimiento; dentro de ese mercado, la participación del aceite de palma es dominante, pero estable, y se mantiene alrededor del 50%.
# Autocontenido salvo por oil_es/oil_cols/caption_hs4, que viven en setup.
# vegoil_world/plot_df_hs4 se recargan acá, igual que en etapa_a_fig_lineas
# (duplicado a propósito, no factorizado) para que este chunk se pueda mover,
# copiar o borrar sin depender de que otro haya corrido antes.
vegoil_world <- readRDS(here::here("Data", "vegoil_world_totals_2010_2024.rds")) |>
filter(ref_year >= año_min, ref_year <= año_max_hs4)
orden_codigos <- vegoil_world |>
filter(ref_year == max(ref_year)) |>
arrange(desc(export_value_usd)) |>
pull(cmd_code)
orden_aceites <- unname(oil_es[orden_codigos])
plot_df_hs4 <- vegoil_world |>
mutate(
aceite = factor(unname(oil_es[cmd_code]), levels = orden_aceites),
valor_mm = export_value_usd / 1e9,
volumen_m = export_wgt_tonnes / 1e6
) |>
group_by(ref_year) |>
mutate(
part_valor = export_value_usd / sum(export_value_usd, na.rm = TRUE),
part_volumen = export_wgt_tonnes / sum(export_wgt_tonnes, na.rm = TRUE)
) |>
ungroup()
stopifnot(!anyNA(plot_df_hs4$aceite))
oil_txt <- c(
"Palma" = "white",
"Soya" = "white",
"Colza / canola" = "grey15",
"Girasol y algodón" = "white",
"Coco y palmiste" = "grey15"
)
lab_part <- "Participación en las exportaciones mundiales"
# Constructor común: las dos barras sólo difieren en la variable apilada.
# La palma transa más barata por tonelada que los aceites competidores, así que
# su participación por VOLUMEN corre por encima de la de VALOR. Las dos se
# reportan; el encuadre se elige a propósito, no por descuido.
#
# Sin baseline-cero explícito: position = "fill" ya obliga la escala a [0,1],
# la regla del eje-en-cero no aplica nada nuevo acá.
barra_100_hs4 <- function(df, var_y, var_part, titulo) {
ggplot(df, aes(ref_year, {{ var_y }}, fill = aceite)) +
geom_col(position = "fill", width = 0.75) +
geom_text(
aes(
label = ifelse({{ var_part }} >= label_min_pct,
pct_es({{ var_part }}), ""),
colour = aceite
),
position = position_fill(vjust = 0.5),
size = 3.2,
fontface = "bold",
show.legend = FALSE
) +
scale_colour_manual(values = oil_txt, guide = "none") +
scale_fill_manual(values = oil_cols, name = NULL) +
scale_x_continuous(breaks = seq(año_min, año_max_hs4, 2)) +
scale_y_continuous(labels = pct_es, expand = c(0, 0)) +
labs(title = titulo, x = NULL, y = lab_part, caption = caption_hs4) +
tema_drp
}
local({
p <- barra_100_hs4(
plot_df_hs4, valor_mm, part_valor,
"Figura 5. Composición exportaciones de aceites vegetales, por valor"
)
print(p)
ggsave(here::here("Plots", "aceites_valor_part.png"), p,
width = 9, height = 5.5, dpi = 300, bg = "white")
})
local({
p <- barra_100_hs4(
plot_df_hs4, volumen_m, part_volumen,
"Figura 6. Composición exportaciones de aceites vegetales, por volumen"
)
print(p)
ggsave(here::here("Plots", "aceites_volumen_part.png"), p,
width = 9, height = 5.5, dpi = 300, bg = "white")
})
rm(vegoil_world, orden_codigos, orden_aceites, plot_df_hs4,
oil_txt, lab_part, barra_100_hs4)
knitr::include_graphics(here::here("Plots", "aceites_valor_part.png"))
knitr::include_graphics(here::here("Plots", "aceites_volumen_part.png"))
A pesar de el peso dominante del aceite de palma, el análisis de los cambios en los precios en la sección anterior sugiere que se trata de un mercado en el que los diversos tipos de aceite son sustitutos cercano y por esta razón es que los precios de los tres tipos de aceite mostrados en la Figura 3 se mueven de manera casi paralela. Esta hipótesis se confirma al observar que el aceite de girasol representa el 17% del mercado por valor, y el 16 por ciento por volumen. Ucrania representa aproximadamente un tercio de la producción total. Sin embargo, la perturbación del suministro proveniente de ese país como resultado de la guerra causó un incremento de precio de más del 150% en el precio del aceite de girasol y de más de un 300% en el de aceite de palma.
Pero además es un mercado de demanda inelástico: el consumo de aceite de palma crece tanto durante los períodos de baja como durante los períodos de incremento de los precios.
Estos dos factores constituyen una característica estructural del mercado de aceites vegetales comestibles, y en consecuencia se puede concluir que la volatilidad de precios ante variaciones incluso modestas de la oferta se seguirá observando en el futuro, lo que sugiere que el uso de instrumentos de bolsa para protegerse de ella debería ser parte de la estrategia de manejo del riesgo de cualquier participante en este mercado.
El mercado internacional de aceites vegetales muestra una tendencia sólida al crecimiento en términos de volumen, asi como una considerable volatilidad en términos de precios, resultado de una demanda inelástica, que constituye una característica estructural del mercado.
El aceite de palma es el principal producto en este mercado global, y representa de manera consistente cerca del 50% del mercado en términos de valor y el 55% en términos de volumen pero no lo domina, en el sentido de que los precios de los aceites vegetales no son determinados por las variaciones en la oferta de aceite de palma, sino que variaciones en la oferta de cualquier tipo de aceite comestible genera variaciones considerables en los precios de todos ellos.
Finalmente, cabe anotar que las condiciones que dieron lugar a un incremento muy marcado de los precios en 2023 parecen estarse reproduciendo a mediados de 2026, y las proyecciones de Statista sugieren un incremento del precio promedio (US $ por tonelada métrica) de $963 en 2024 a $1062 en 2027, como se muestra en la Figura 7.
# Datos de Statista: precios promedio de aceite de palma, 2014-2027
# Años 2025-2027 son proyecciones (marcadas con * en la fuente)
precios_palma <- tibble::tibble(
anio = 2014:2027,
precio = c(837, 663, 736, 751, 639, 601, 752, 1131, 1276, 886, 963, 1020, 1051, 1062),
proyectado = anio >= 2025
)
# Separar en histórico y proyectado para poder unir con línea punteada
historico <- precios_palma |> filter(!proyectado)
proyectado <- precios_palma |> filter(anio >= 2024) # incluye 2024 para conectar la línea
p_precios_palma <- ggplot(precios_palma, aes(x = anio, y = precio)) +
geom_line(data = historico, color = "#2E5C8A", linewidth = 1) +
geom_line(data = proyectado, color = "#2E5C8A", linewidth = 1, linetype = "dashed") +
geom_point(aes(shape = proyectado), color = "#2E5C8A", size = 2) +
scale_shape_manual(values = c(`FALSE` = 16, `TRUE` = 1), guide = "none") +
scale_x_continuous(breaks = precios_palma$anio) +
scale_y_continuous(labels = scales::comma, limits = c(0, NA),
breaks = seq(0, 1300, by = 200),
expand = expansion(mult = c(0, 0.05))) +
labs(
title = "Figura 7. Precio promedio del aceite de palma a nivel mundial, 2014-2027",
subtitle = "En dólares nominales por tonelada métrica",
x = NULL,
y = "Precio (USD/t)",
caption = "Elaboración propia con base en Statista."
) +
theme_minimal() +
theme(
axis.text.x = element_text(angle = 45, hjust = 1),
plot.caption = element_text(hjust = 0, size = 8),
panel.grid.minor.x = element_blank()
) +
tema_drp
# Ver antes de guardar
p_precios_palma
# Guardar
ggsave(here::here("Plots", "precios_palma_statista.png"), p_precios_palma, width = 9, height = 5.5, dpi = 300)
knitr::include_graphics(here::here("Plots", "precios_palma_statista.png"))
Las exportaciones de aceite de palma representan tan solo una parte del mercado total de aceite de palma. La oferta de exportación depende de la producción de fruta y aceite crudo en primer lugar, pero luego de la distribución del aceite crudo entre el mercado de exportación y el doméstico.
La distribución del aceite que se destina al mercado doméstico entre usos alimentarios e industriales, a su vez, tiene impacto sobre la oferta exportable de aceite refinado y de productos derivados (aunque este último mercado queda fuera del ámbito de este estudio).
Por otra parte, la producción depende de tres factores: el área cultivada, la productividad agrícola y la tasa de extracción de aceite a partir de la fruta. Los dos últimos factores, combinados, nos permiten calcular la productividad total por área cultivada, definida como la producción de aceite crudo por área cultivada.
En esta sección se examinan estos diversos aspectos del mercado, empezando con la producción.
# ============================================================
# Producción mundial de aceite de palma (USDA PSD) -- Figuras 8-10
# ============================================================
# --- 3. Parámetros y utilidades -----------------------------------------------
año_min_prod <- 2010
n_top_barra <- 9 # top países individuales en la barra 100%; resto -> "Resto"
n_top_treemap <- 10 # top países individuales en cada treemap; resto -> "Resto"
label_min_pct_tm <- 0.005 # umbral de rotulado, treemaps -- más bajo para nombrar más países
otros_lab_prod <- "Resto"
caption_prod <- "Fuente: USDA FAS, PSD Online (Palm Oil, atributo Production)."
# Diccionario mínimo país -> español, sólo productores relevantes. Fallback al
# nombre original si un país no está listado, para que uno nuevo se note en la
# figura (en inglés) en vez de perderse como NA.
lab_pais_prod <- c(
"Indonesia" = "Indonesia", "Malaysia" = "Malasia", "Thailand" = "Tailandia",
"Colombia" = "Colombia", "Nigeria" = "Nigeria", "Guatemala" = "Guatemala",
"Honduras" = "Honduras", "Papua New Guinea" = "PNGuinea", "Ecuador" = "Ecuador",
"Brazil" = "Brasil", "Costa Rica" = "CR", "Mexico" = "México",
"Cote d'Ivoire" = "Marfil", "Côte d'Ivoire" = "Marfil", "Cameroon" = "Camerún",
"Congo (Kinshasa)" = "RDCongo", "Democratic Republic of the Congo" = "RDCongo"
)
es_pais_prod <- function(x) {
y <- unname(lab_pais_prod[x])
if_else(is.na(y), x, y)
}
# --- 4. Cargar datos -----------------------------------------------------------
usda_palm_tidy <- readRDS(here::here("Data", "usda_palm_tidy.rds"))
# --- 5. Preparar: panel de producción, 2010 al último año con datos ------------
año_max_prod <- usda_palm_tidy |>
filter(!is.na(produccion)) |>
summarise(m = max(marketYear)) |>
pull(m)
prod <- usda_palm_tidy |>
filter(marketYear >= año_min_prod, marketYear <= año_max_prod,
!is.na(produccion)) |>
select(countryName, marketYear, produccion) |>
mutate(produccion_m = produccion / 1000) # PSD reporta en miles de TM -> millones de TM
# --- 6. Preparar: total mundial por año (línea) ---------------------------------
mundo <- prod |>
summarise(produccion_m = sum(produccion_m, na.rm = TRUE), .by = marketYear)
# --- 7. Preparar: top-9 + resto por año (barra 100%) -----------------------------
top9_paises <- prod |>
filter(marketYear == año_max_prod) |>
slice_max(produccion_m, n = n_top_barra, with_ties = FALSE) |>
pull(countryName)
orden_paises <- prod |>
filter(marketYear == año_max_prod, countryName %in% top9_paises) |>
arrange(desc(produccion_m)) |>
pull(countryName)
niveles_es <- es_pais_prod(c(orden_paises, otros_lab_prod))
barra_df <- prod |>
mutate(pais_lab = if_else(countryName %in% top9_paises, countryName, otros_lab_prod)) |>
summarise(produccion_m = sum(produccion_m, na.rm = TRUE), .by = c(marketYear, pais_lab)) |>
mutate(part = produccion_m / sum(produccion_m), .by = marketYear,
pais_lab = factor(es_pais_prod(pais_lab), levels = niveles_es))
colores_barra <- setNames(rep_len(paleta_origen, length(orden_paises)), niveles_es[seq_along(orden_paises)])
colores_barra[otros_lab_prod] <- gris_residuo
# --- 8. Preparar: treemaps año inicial y año final (top-10 independiente) --------
armar_treemap_prod <- function(año) {
df_año <- prod |> filter(marketYear == año)
top <- df_año |> slice_max(produccion_m, n = n_top_treemap, with_ties = FALSE) |> pull(countryName)
df_año |>
mutate(pais_lab = if_else(countryName %in% top, countryName, otros_lab_prod)) |>
summarise(produccion_m = sum(produccion_m, na.rm = TRUE), .by = pais_lab) |>
mutate(part = produccion_m / sum(produccion_m),
pais_lab = es_pais_prod(pais_lab))
}
treemap_primero <- armar_treemap_prod(año_min_prod)
treemap_ultimo <- armar_treemap_prod(año_max_prod)
paises_todos_treemap <- union(
setdiff(treemap_primero$pais_lab, otros_lab_prod),
setdiff(treemap_ultimo$pais_lab, otros_lab_prod)
) |> sort()
colores_treemap <- setNames(rep_len(paleta_origen, length(paises_todos_treemap)), paises_todos_treemap)
colores_treemap[otros_lab_prod] <- gris_residuo
# --- 9. Graficar: línea, producción mundial total + tendencia --------------------
p_linea <- ggplot(mundo, aes(marketYear, produccion_m)) +
geom_smooth(method = "lm", se = FALSE, colour = "#B0673A",
linewidth = 0.8, linetype = "dashed") +
geom_line(linewidth = 0.9, colour = "#2E5C8A") +
geom_point(size = 1.6, colour = "#2E5C8A") +
scale_x_continuous(breaks = seq(año_min_prod, año_max_prod, 2)) +
scale_y_continuous(labels = num_es, limits = c(0, NA), expand = expansion(mult = c(0,0.05))) +
labs(
title = "Figura 8. Producción mundial de aceite de palma",
subtitle = paste0(año_min_prod, "-", año_max_prod),
x = NULL, y = "Millones de toneladas",
caption = caption_prod
) +
tema_drp
print(p_linea)
ggsave(here::here("Plots", "usda_produccion_linea.png"), p_linea,
width = 9, height = 5.5, dpi = 300, bg = "white")
# --- 10. Graficar: barra 100%, composición por país --------------------------------
p_barra <- ggplot(barra_df, aes(marketYear, produccion_m, fill = pais_lab)) +
geom_col(position = "fill", width = 0.85) +
geom_text(
aes(label = if_else(part >= label_min_pct, pct_es(part), "")),
position = position_fill(vjust = 0.5),
size = 2.3, fontface = "bold", colour = "white", show.legend = FALSE
) +
scale_fill_manual(values = colores_barra, name = NULL) +
scale_x_continuous(breaks = seq(año_min_prod, año_max_prod, 2)) +
scale_y_continuous(labels = pct_es, expand = c(0, 0)) +
labs(
title = "Figura 9. Distribución porcental de la producción mundial de aceite de palma",
subtitle = paste0(año_min_prod, "-", año_max_prod, " por países"),
x = NULL, y = "Participación en la producción mundial",
caption = caption_prod
) +
tema_drp
print(p_barra)
ggsave(here::here("Plots", "usda_produccion_barra.png"), p_barra,
width = 9, height = 5.5, dpi = 300, bg = "white")
# --- 11. Graficar: treemaps, año inicial y año final -------------------------------
fig_treemap_prod <- function(df, año) {
ggplot(df, aes(area = part, fill = pais_lab,
label = if_else(part >= label_min_pct_tm,
paste0(pais_lab, "\n", pct_es(part)), ""))) +
geom_treemap(colour = "white", size = 0.2) +
geom_treemap_text(colour = "white", place = "centre",
grow = FALSE, size = 10, reflow = TRUE, lineheight = 0.9) +
scale_fill_manual(values = colores_treemap) +
labs(subtitle = as.character(año)) +
tema_drp +
theme(legend.position = "none", panel.grid = element_blank(),
axis.text = element_blank(), axis.ticks = element_blank())
}
p_treemap_primero <- fig_treemap_prod(treemap_primero, año_min_prod)
p_treemap_ultimo <- fig_treemap_prod(treemap_ultimo, año_max_prod)
# título y caption únicos para el panel completo, no por sub-treemap
p_treemap_panel <- p_treemap_primero + p_treemap_ultimo +
patchwork::plot_annotation(
title = "Figura 10. Producción mundial de aceite de palma, 2010 y 2025",
subtitle = "Distribución porcentual",
caption = caption_prod
)
print(p_treemap_panel)
# 8.5x6.5: dos treemaps lado a lado -- ajustar si al ver el PNG queda apretado
ggsave(here::here("Plots", "usda_produccion_treemap_panel.png"), p_treemap_panel,
width = 8.5, height = 6.5, dpi = 300, bg = "white")
# --- 12. Limpieza -------------------------------------------------------------
rm(usda_palm_tidy, año_min_prod, año_max_prod, n_top_barra, n_top_treemap,
label_min_pct_tm, otros_lab_prod,
caption_prod, lab_pais_prod,
es_pais_prod, prod, mundo, top9_paises, orden_paises, niveles_es, barra_df,
colores_barra, armar_treemap_prod, treemap_primero, treemap_ultimo,
paises_todos_treemap, colores_treemap, p_linea, p_barra,
p_treemap_primero, p_treemap_ultimo, p_treemap_panel, fig_treemap_prod)
Examinaremos primero la evolución de la producción total de aceite crudo, y luego su distribución por países. Concluido ese análisis, examinaremos dos temas complementarios: la evolución de los rendimientos por hectárea, y las limitaciones que enfrentan distintos países para expandir el área cultivada.
En la Figura 8 muestra la evolución de la producción total, que tiene un incremento notable, cercano al 60%, entre 2010 y 2025. La creciente demanda de aceite vegetal, impulsada por el crecimiento de la población, pero más aún, por el incremento del ingreso y del poder de compra en algunos de los mercados importadores más importantes (OCDE-FAO 2026) genera condiciones para que, más allá de las variaciones de corto plazo, la tendencia de los precios se mantenga al alza, a pesar del incremento de la producción.
Sin embargo, como veremos un poco más adelante, la clave para el incremento de la producción ya no consistirá en la expansión del área cultivada, sino que dependerá fundamentalmente del incremento de la productividad agrícola y la del procesamiento industrial. Estas dos no son por completo independientes, ya que la tasa de extracción depende tanto de la calidad de la fruta como de la tecnología que se utiliza en el proceso de extracción
Esto crea una ventana de oportunidad para países con plantaciones relativamente jóvenes con respecto a países cuyas plantaciones tiene una edad promedio avanzada, particularmente si los planes de renovación de las plantaciones no están avanzando a un ritmo adecuado. Este es un tema que retomaremos más adelante.
knitr::include_graphics(here::here("Plots", "usda_produccion_linea.png"))
Es importante tomar nota de la notable desaceleración en el crecimiento de la producción de aceite de palma. De acuerdo a las proyecciones de OCDE-FAO (OCDE-FAO 2026), la tasa de crecimiento anual compuesto (TCAC) de la producción de aceite de palma para el próximo quinquenio será de 1.99%, y se reducirá a 1.43% en el quinquenio siguiente.
Para poner estas cifras en contexto: con una TCAC de 1.99%, la producción se duplicaría cada 35 años, y con una de 1.43% cada 49 años. Con una tasa de 1.43%, el crecimiento de la producción entre 2010 y 2015 hubiese sido de poco más de 20%, en contraste con el 60% observado.
En el mismo período abarcado por la Figura 8, es decir, entre 2010 y 2025, Indonesia ha consolidado su posición como el principal productor a nivel mundial, con una participación que se incrementó en 9 puntos porcentuales entre 2010 y 2025, período en el que pasó de representar el 48% al 57% de la producción mundial.
En contraste, Malasia, el segundo mayor productor a nivel mundial, vio su participación reducirse en 12 puntos porcentuales: de un 37% en 2010 a un 25% en 2025. El tercer productor, Tailandia, con 5% del mercado, tiene apenas una quinta parte de la participación de Malasia, y los demás productores tiene participaciones muy pequeñas. Costa Rica no llega a ocupar una posición entre los 9 mayores productores y aunque más adelante examinaremos algunos de sus datos, en la Figura 9 estos se subsumen dentro de la categoria “Resto” (del mundo).
La Figura 9 muestra cómo ha evolucionado esa participación porcentual entre 2010 y 2025.
knitr::include_graphics(here::here("Plots", "usda_produccion_barra.png"))
La Figura 10 muestra de manera mucho más contundente el cambio que tiene lugar de punta a punta, pues compara directamente la distribución de la producción en 2010 y 2025. El creciente predominio de Indonesia es indiscutible, pero es poco probable que su participación se incremente en el futuro y más bien podría tender a reducirse, de manera moderada y gradual, por razones que quedarán claras más adelante.
knitr::include_graphics(here::here("Plots", "usda_produccion_treemap_panel.png"))
Los dos países que dominan la producción dominan también, como era de esperarse, el área cultivada. Indonesia y Malasia sumadas representan aproximadamente el 75% del área cultivada a nivel mundial, y ese porcentaje se ha estabilizado de 2020 en adelante, como se muestra en la Figura 11.
Más interesante, desde el punto de vista de este estudio, es el estancamiento del área total cultivada, que prácticamente ha dejado de crecer, y que posiblemente no se expandirá de manera significativa en el futuro. ¿Por qué?
La respuesta consiste en que las causas de que el área cultivada no esté creciento no son coyunturales sino duraderas, y posiblemente permanentes (Gaveau et al. 2022, Guindon, 2021, Wulandary adn Sholihin, 2026) :
panel_productividad_palma <- readRDS(here::here("Data", "panel_productividad_palma.rds"))
anios_eje <- seq(2010, 2024, by = 2)
anios_menores <- seq(2011, 2023, by = 2)
# --- Panel 1: área cultivada (millones de ha), Total / Indonesia / Malasia --
area_total_anual <- panel_productividad_palma |>
group_by(anio) |>
summarise(area_cosechada_ha = sum(area_cosechada_ha, na.rm = TRUE)) |>
mutate(pais_es = "Total")
area_indonesia_malasia <- panel_productividad_palma |>
filter(pais_es %in% c("Indonesia", "Malasia")) |>
select(pais_es, anio, area_cosechada_ha)
area_lineas <- bind_rows(area_total_anual, area_indonesia_malasia) |>
mutate(area_cosechada_mha = area_cosechada_ha / 1e6)
p_area_lineas <- ggplot(area_lineas, aes(x = anio, y = area_cosechada_mha,
color = pais_es)) +
geom_line(linewidth = 1) +
scale_color_manual(values = c(
"Total" = "black",
"Indonesia" = paleta_origen[1],
"Malasia" = paleta_origen[2]
)) +
scale_x_continuous(breaks = anios_eje, minor_breaks = anios_menores,
expand = c(0, 0)) +
scale_y_continuous(limits = c(0, NA), expand = expansion(mult = c(0, 0.05))) +
tema_drp +
theme(
legend.position = "bottom",
panel.grid.minor.x = element_line(colour = "grey92")
) +
labs(x = NULL, y = NULL, color = NULL)
# --- Panel 2: participación del área, Indonesia / Malasia / Resto -----------
# "Resto" sale por diferencia contra area_total_anual. El apilado se calcula
# a mano (ymin/ymax) y se dibuja con geom_ribbon, no geom_area: con
# position = "stack", geom_area acumula los pct internamente y el ruido de
# punto flotante de esa suma puede autointersecar el polígono y dejar un
# hueco blanco vertical (visto y confirmado en este archivo). geom_ribbon
# con el acumulado ya resuelto por nosotros no tiene ese problema.
area_pct <- area_total_anual |>
select(anio, area_total_ha = area_cosechada_ha) |>
left_join(
area_indonesia_malasia |>
pivot_wider(names_from = pais_es, values_from = area_cosechada_ha),
by = "anio"
) |>
mutate(`Resto del mundo` = area_total_ha - Indonesia - Malasia) |>
select(anio, Indonesia, Malasia, `Resto del mundo`) |>
pivot_longer(-anio, names_to = "grupo", values_to = "area_ha") |>
group_by(anio) |>
mutate(pct = area_ha / sum(area_ha)) |>
ungroup() |>
mutate(grupo = factor(grupo, levels = c("Indonesia", "Malasia", "Resto del mundo"))) |>
arrange(anio, grupo) |>
group_by(anio) |>
mutate(
ymax = cumsum(pct),
ymin = lag(ymax, default = 0)
) |>
ungroup()
p_area_pct <- ggplot(area_pct, aes(x = anio, ymin = ymin, ymax = ymax, fill = grupo)) +
geom_ribbon(color = "white", linewidth = 0.2, alpha = 0.9) +
scale_fill_manual(values = c(
"Indonesia" = paleta_origen[1],
"Malasia" = paleta_origen[2],
"Resto del mundo" = gris_residuo
)) +
scale_x_continuous(breaks = anios_eje, minor_breaks = anios_menores,
expand = c(0, 0)) +
scale_y_continuous(labels = label_number(accuracy = 1, scale = 100),
limits = c(0, 1), expand = c(0, 0)) +
tema_drp +
theme(
legend.position = "bottom",
panel.grid.minor.x = element_line(colour = "grey92")
) +
labs(x = NULL, y = NULL, fill = NULL)
# --- Panel combinado ----------------------------------------------------
p_panel_area <- p_area_lineas / p_area_pct +
plot_annotation(
title = " Figura 11. Área cultivada de palma aceitera",
subtitle = "Millones de hectáreas y porcentajes",
caption = "Fuente: elaboración propia con datos de USDA y FAOSTAT",
theme = theme(
plot.title = element_text(face = "bold"),
plot.subtitle = element_text(size = 11),
plot.caption = element_text(hjust = 0, size = 7.5, colour = "grey35")
)
)
print(p_panel_area)
ggsave(here::here("Plots", "area_cosechada_indonesia_malasia_panel.png"),
p_panel_area, width = 7, height = 8, dpi = 300, bg = "white")
rm(anios_eje, anios_menores, area_total_anual, area_indonesia_malasia,
area_lineas, p_area_lineas, area_pct, p_area_pct, p_panel_area,
panel_productividad_palma)
knitr::include_graphics(here::here("Plots", "area_cosechada_indonesia_malasia_panel.png"))
Para poner las observaciones anteriores en su justa perspectiva, quizá lo correcto es decir que la época de rápida expansión del área cultivada con palma aceitera ha quedado atrás, sin que esto implique que el crecimiento futuro será igual a cero.
En primer lugar, otros productores de aceite de palma, o de otros aceites vegetales, podrían ver en el estancamiento del área cultivada en Indonesia y Malasia una oportunidad para expandir su participación en el mercado. Algunos de esos países, precisamente por no ocupar una posición dominante en el mercado, están sometidos a un escrutinio menos intensivo que Indonesia y Malasia, y si sus mercados de exportación no están concentrados en Europa, podrían tener menos incentivos para evitar la expansión del área cultivada.
Por otra parte, algunos países productores de otros aceites (o de la materia prima para producirlos) han visto fuertes oscilaciones en sus politicas de conservación ambiental, según el signo o preferencia del gobierno de turno, y han sido poco exitosos en sus esfuerzos por contener la deforestación, particularmente porque el impacto de gobiernos que promueven la expansión del área cultivada y el de los gobiernos que priorizan la conservación es asimétrico: en lo que dura un gobierno “conservacionista” sería imposible regenerar el bosque que se haya perdido durante un gobierno “desarrollista”, no solo por razones biológicas (el bosque tarda decenios en regenerarse) sino políticas: una vez que un área ha sido abierta al cultivo, se generan grupos de interés alrededor de esa actividad, que resistirán la reconversión del suelo. Brasil es un buen ejemplo de todo esto.
Aún así, en la medida en que el área cultivada se mantenga estable o crezca lentamente, el factor clave para que un país pueda expandir su participación en el mercado de crudo es la productividad, y este el el tema que examinamos en la sección siguiente.
La productividad total en la producción de aceite de palma, medida por hectárea, depende de dos factores: la productividad agrícola propiamente dicha (toneladas de fruta por hectárea) y la tasa de extracción (toneladas de aceite por tonelada de fruta). La combinación de información de USDA y FAO nos permite calcular tanto la productividad total como sus componentes.
anios_eje <- seq(2010, 2024, by = 2)
anios_menores <- seq(2011, 2023, by = 2)
panel_productividad_palma <- readRDS(here::here("Data", "panel_productividad_palma.rds"))
datos_3paises <- panel_productividad_palma |>
filter(pais_es %in% c("Indonesia", "Malasia", "Costa Rica"))
colores_3paises <- c(
"Indonesia" = paleta_origen[1],
"Malasia" = paleta_origen[2],
"Costa Rica" = "#E4572E"
)
# --- Figura 12: productividad total (CPO por hectárea cosechada) ------------
# rendimiento_cpo_t_ha ya integra rendimiento agrícola x tasa de extracción,
# por eso es la medida de "productividad total".
p_prod_total <- ggplot(datos_3paises, aes(x = anio, y = rendimiento_cpo_t_ha,
color = pais_es)) +
geom_line(linewidth = 1) +
scale_color_manual(values = colores_3paises) +
scale_x_continuous(breaks = anios_eje, minor_breaks = anios_menores,
expand = c(0, 0)) +
scale_y_continuous(limits = c(0, NA), expand = expansion(mult = c(0, 0.05))) +
tema_drp +
theme(
legend.position = "bottom",
panel.grid.minor.x = element_line(colour = "grey92")
) +
labs(
title = "Figura 12. Productividad total, aceite de palma crudo (CPO)",
subtitle = "Toneladas de CPO por hectárea cosechada",
x = NULL, y = NULL, color = NULL,
caption = "Fuente: elaboración propia con datos de USDA y FAOSTAT"
)
p_prod_total
ggsave(here::here("Plots", "productividad_total_indonesia_malasia_cr.png"),
p_prod_total, width = 7, height = 5, dpi = 300, bg = "white")
# --- Figura 13: productividad agrícola (FFB por hectárea cosechada) ---------
p_prod_agricola <- ggplot(datos_3paises, aes(x = anio, y = rendimiento_ffb_t_ha,
color = pais_es)) +
geom_line(linewidth = 1) +
scale_color_manual(values = colores_3paises) +
scale_x_continuous(breaks = anios_eje, minor_breaks = anios_menores,
expand = c(0, 0)) +
scale_y_continuous(limits = c(0, NA), expand = expansion(mult = c(0, 0.05))) +
tema_drp +
theme(
legend.position = "bottom",
panel.grid.minor.x = element_line(colour = "grey92")
) +
labs(
title = "Figura 13. Productividad agrícola, racimos de fruta fresca (FFB)",
subtitle = "Toneladas de FFB por hectárea cosechada",
x = NULL, y = NULL, color = NULL,
caption = "Fuente: elaboración propia con datos de USDA y FAOSTAT"
)
p_prod_agricola
ggsave(here::here("Plots", "productividad_agricola_indonesia_malasia_cr.png"),
p_prod_agricola, width = 7, height = 5, dpi = 300, bg = "white")
# --- Figura 14: tasa de extracción ------------------------------------------
# Asumo tasa_extraccion viene como proporción (0-1); si al correrlo aparece
# ya en puntos porcentuales, cambiar pct_es() por num_es() en scale_y_continuous.
p_tasa_extraccion <- ggplot(datos_3paises, aes(x = anio, y = tasa_extraccion,
color = pais_es)) +
geom_line(linewidth = 1) +
scale_color_manual(values = colores_3paises) +
scale_x_continuous(breaks = anios_eje, minor_breaks = anios_menores,
expand = c(0, 0)) +
scale_y_continuous(labels = pct_es, limits = c(0, NA),
expand = expansion(mult = c(0, 0.05))) +
tema_drp +
theme(
legend.position = "bottom",
panel.grid.minor.x = element_line(colour = "grey92")
) +
labs(
title = "Figura 14. Tasa de extracción de aceite de palma",
subtitle = "CPO extraído como porcentaje del FFB procesado",
x = NULL, y = NULL, color = NULL,
caption = "Fuente: elaboración propia con datos de USDA y FAOSTAT"
)
p_tasa_extraccion
ggsave(here::here("Plots", "tasa_extraccion_indonesia_malasia_cr.png"),
p_tasa_extraccion, width = 7, height = 5, dpi = 300, bg = "white")
# --- Limpieza ----------------------------------------------------------------
rm(anios_eje, anios_menores, panel_productividad_palma, datos_3paises,
colores_3paises, p_prod_total, p_prod_agricola, p_tasa_extraccion)
La Figura 12 muestra la productividad total, es decir, toneladas de aceite de palma crudo por hectárea plantada de aceite de palma, para Costa Rica, Indonesia y Malasia. Las causas de las fuertes fluctuaciones de la productividad costarricense entre 2010 y 2014 están pendientes de investigación, pero las tendencias son claras: al incremento en el caso de la productividad de Costa Rica, a la baja notable en el caso de Indonesia, que ha pasado de cerca de 4 a cerca de 3 toneladas de aceite por hectárea cultivada, y una tendencia estable, justo por debajo de 4 toneladas por hectárea en el caso de Malasia, cuya participación en la producción de aceite de palma, vale la pena recordarlo, tiende a disminuir, tale y como se mostró en la Figura 9.
knitr::include_graphics(here::here("Plots", "productividad_total_indonesia_malasia_cr.png"))
Pasamos al examen de la productividad agrícola. Los años 2013 y 2014 claramente fueron excepcionales para Costa Rica. La extraordinaria caída en los rendimientos agrícolas probablemente está asociada con la sequía que el país experimentó en esos años. La recuperación se inició en 2016 y la tendencia ha sido ascendente desde entonces, pero sin que se haya recuperado aún, en 2024, la productividad que se observó en 2010. La trayectoria de la productividad de los otros dos países incluidos en el gráfico no muestra fluctuaciones tan marcadas, pero tiende a reducirse lentamente en el caso de Indonesia, y fluctúa en niveles cercanos a las 17 o 18 toneladas por hectárea,sin tendencias marcadas ni al incremento ni al decrecimiento, en el caso de Malasia.
Una causa importante de este descenso es el envejecimiento de las plantaciones en Indonesia y Malasia, y el considerable atraso en los programas de renovación de plantaciones, causado tanto por problemas financieros como institucionales (bajo porcentaje de productores pequeños asociados a cooperativas, por ejemplo). Además, aunque hay material genético de alta calidad, muchos productores utilizan material genético de baja calidad, por el costo de acceso al de mayor calidad (Perumsan, K, 2025, Haisawit, 2026, Bernama, 2025, Torrebiarte, A. 2024).
La implicación es que si Costa Rica logra acelerar sus propios programas de renovación de plantaciones, y asegurar el uso de material genético de primera calidad, en los próximos años el país debería de superar la productividad de Indonesia y cerrar, o por lo menos reducir, la brecha que aún lo separa de Malasia.
knitr::include_graphics(here::here("Plots", "productividad_agricola_indonesia_malasia_cr.png"))
La diferencia más notable entre Costa Rica, Indonesia y Malasia se da en la tasa de extracción, que es consistentemente superior en el caso de Costa Rica, con una diferencia que parece tender a ensancharse de 2016 en adelante.
Una identificación precisa de las causas de esta diferencia supera el alcance de este documento, pero hay varias posibles causas que valdría la pena explorar (FAO,SF, Ruswanto, A. et al. 2020, Masika 2026) como parte de la definición de la estrategia competitiva del sector:
En cuanto al material genético, Costa Rica tiene acceso al material que produce ASD Costa Rica, y aunque material de la misma calidad está disponible en Indonesia, no todos los productores lo utilizan, según se explicó anteriormente.
El punto crucial a investigar es si esta ventaja, aunque duradera, es temporal, o si puede consolidarse de manera permanente. Si este fuera el caso, y al mismo tiempo se lograra incrementar la productividad agrícola (cosa que parece perfectamente viable y que de hecho ya está teniendo lugar) la posición competitiva de Costa Rica podría fortalecerse de manera duradera.
knitr::include_graphics(here::here("Plots", "tasa_extraccion_indonesia_malasia_cr.png"))
En resumen, como resultado de la interacción entre productividad agrícola y tasa de extracción, la productividad total de Costa Rica se ha recuperado de 2014 a la fecha, es muy similar a la de Malasia, y es bastante mayor a la de Indonesia, que ha mostrado una caída fuerte entre 2010 y 2022. Nótese, sin embargo, que a pesar de esta recuperación, la productividad de Costa Rica en 2024 es inferior a la que se observaba en 2010.
# Chunk único y autocontenido para toda la Etapa B, salvo los treemaps de
# destino (que sólo necesitan palma_crudo/palma_refinado, ya guardados en
# disco, y por eso viven en su propio chunk independiente). Se corre línea
# por línea; una vez guardados los PNG y tablas, este chunk pasa a
# echo=TRUE, eval=FALSE.
#
# lab_aceite, col_acento, paleta_paises, colores_de() y caption_fuente() ya
# viven en setup -- no se redefinen acá.
# --- Carga -------------------------------------------------------------------
# Los nombres de columna se piden explícitamente. comtradr los ha cambiado
# entre versiones; con `select` nombrado, un cambio de nombre da error acá y
# no un resultado silenciosamente incompleto veinte líneas más abajo.
palm <- readRDS(here::here("Data", "comtrade_palm_bilateral_hs6_2010_2024.rds")) |>
as_tibble() |>
select(
ref_year, cmd_code, reporter_desc,
destino = partner_desc,
valor_usd = primary_value,
wgt_kg = net_wgt
) |>
filter(destino != "World", ref_year >= año_min, ref_year <= año_max_hs6) |>
mutate(
volumen_t = wgt_kg / 1000,
aceite = unname(c("151110" = "crudo", "151190" = "refinado")[cmd_code])
) |>
select(-wgt_kg, -cmd_code)
stopifnot(!anyNA(palm$aceite))
# El lado DESTINO se conserva íntegro y nunca se filtra. Como el pull tomó
# flow_direction = "export" únicamente, el tramo de reexportación posterior
# (p. ej. lo que sale de Rotterdam hacia el resto de la UE) no se ve.
# --- Figuras 15-16: series totales por tipo de aceite -------------------------
totales_aceite <- palm |>
summarise(valor_mm = sum(valor_usd, na.rm = TRUE) / 1e9, .by = c(ref_year, aceite))
fig_totales <- function(df, tipo, numero) {
serie <- filter(df, aceite == tipo) |> arrange(ref_year)
ggplot(serie, aes(ref_year, valor_mm)) +
geom_line(colour = "#1F4E79", linewidth = 1) +
geom_point(colour = "#1F4E79", size = 1.3) +
geom_smooth(data = filter(serie, ref_year <= 2016),
method = "lm", formula = y ~ x, se = FALSE,
colour = "#E01B24", linewidth = 0.9, linetype = "dashed") +
geom_smooth(data = filter(serie, ref_year >= 2016),
method = "lm", formula = y ~ x, se = FALSE,
colour = "#E01B24", linewidth = 0.9, linetype = "dashed") +
scale_x_continuous(breaks = seq(año_min, año_max_hs6, 2)) +
scale_y_continuous(labels = num_es, limits = c(0, NA),
expand = expansion(mult = c(0, 0.05))) +
labs(
title = paste0("Figura ", numero, ". Exportaciones mundiales de aceite de palma ",
lab_aceite[[tipo]]),
subtitle = "Miles de millones de US$",
x = NULL, y = NULL, caption = caption_fuente(tipo)
) +
tema_drp
}
local({
p <- fig_totales(totales_aceite, "crudo", 15)
print(p)
ggsave(here::here("Plots", "palma_crudo_totales.png"), p,
width = 9, height = 5.5, dpi = 300, bg = "white")
})
local({
p <- fig_totales(totales_aceite, "refinado", 16)
print(p)
ggsave(here::here("Plots", "palma_refinado_totales.png"), p,
width = 9, height = 5.5, dpi = 300, bg = "white")
})
rm(totales_aceite, fig_totales)
# --- Agrupación: top-10 + residuo, un solo criterio para los dos universos ---
# Costa Rica entra si clasifica por valor, igual que cualquier otro país; no
# hay inclusión forzada.
agrupar <- function(df, tipo) {
años_rank <- (año_max_hs6 - rank_window + 1):año_max_hs6
rank_valor <- df |>
filter(ref_year %in% años_rank) |>
summarise(valor = sum(valor_usd, na.rm = TRUE), .by = reporter_desc) |>
arrange(desc(valor))
sel <- head(rank_valor$reporter_desc, n_top)
niveles <- c(es_pais(sel), otros_lab)
df |>
mutate(exportador = if_else(reporter_desc %in% sel,
es_pais(reporter_desc), otros_lab)) |>
summarise(valor_usd = sum(valor_usd, na.rm = TRUE),
volumen_t = sum(volumen_t, na.rm = TRUE),
.by = c(ref_year, exportador, destino)) |>
mutate(exportador = factor(exportador, levels = niveles))
}
palma_crudo <- agrupar(filter(palm, aceite == "crudo"), "crudo")
palma_refinado <- agrupar(filter(palm, aceite == "refinado"), "refinado")
saveRDS(palma_crudo, here::here("Data", "palma_crudo_top10.rds"))
saveRDS(palma_refinado, here::here("Data", "palma_refinado_top10.rds"))
# --- Figuras 17-18: composición porcentual -----------------------------------
fondos_claros <- c("#7FB3D5", "#86C5A0", "#D6D3D1")
colores_texto_de <- function(df) {
cols <- colores_de(df)
setNames(if_else(cols %in% fondos_claros, "grey15", "white"), names(cols))
}
fig_composicion <- function(df, tipo, numero) {
comp <- df |>
summarise(valor = sum(valor_usd, na.rm = TRUE), .by = c(ref_year, exportador)) |>
mutate(part = valor / sum(valor), .by = ref_year)
ggplot(comp, aes(ref_year, part, fill = exportador)) +
geom_col(width = 0.78) +
geom_text(
aes(label = if_else(part >= label_min_pct, pct_es(part), ""),
colour = exportador),
position = position_stack(vjust = 0.5),
size = 3.2, fontface = "bold", show.legend = FALSE
) +
scale_colour_manual(values = colores_texto_de(df), guide = "none") +
scale_fill_manual(values = colores_de(df), name = NULL) +
scale_x_continuous(breaks = seq(año_min, año_max_hs6, 2)) +
scale_y_continuous(labels = pct_es, expand = c(0, 0)) +
labs(
title = paste0("Figura ", numero, ". Exportaciones mundiales de aceite de palma ",
lab_aceite[[tipo]]),
subtitle = "Distribución porcentual por país exportador",
x = NULL, y = NULL, caption = caption_fuente(tipo)
) +
tema_drp
}
local({
p <- fig_composicion(palma_crudo, "crudo", 17)
print(p)
ggsave(here::here("Plots", "palma_crudo_composicion.png"), p,
width = 9, height = 5.5, dpi = 300, bg = "white")
})
local({
p <- fig_composicion(palma_refinado, "refinado", 18)
print(p)
ggsave(here::here("Plots", "palma_refinado_composicion.png"), p,
width = 9, height = 5.5, dpi = 300, bg = "white")
})
rm(fondos_claros, colores_texto_de, fig_composicion)
# --- Tabla 3: Costa Rica en el mercado de crudo ------------------------------
# Independiente del top-10: Costa Rica ronda el 2% del crudo mundial y casi
# nunca clasifica por sí sola, así que esta tabla se calcula sobre `palm`
# directamente, no sobre `palma_crudo`.
tabla_cr <- palm |>
filter(aceite == "crudo") |>
summarise(valor = sum(valor_usd, na.rm = TRUE), .by = c(ref_year, reporter_desc)) |>
mutate(part = valor / sum(valor), .by = ref_year) |>
filter(reporter_desc == "Costa Rica") |>
transmute(ref_year, valor_mm = valor / 1e6, part) |>
pivot_longer(c(valor_mm, part), names_to = "métrica", values_to = "valor") |>
pivot_wider(names_from = ref_year, values_from = valor) |>
mutate(métrica = recode(métrica,
valor_mm = "Millones de US$",
part = "Participación"))
saveRDS(tabla_cr, here::here("Data", "tabla_cr_datos.rds"))
rm(tabla_cr)
# --- Revisión: cifras detrás de las figuras (diagnóstico, sin numerar) -------
resumen <- function(df, tipo) {
message("\n=== ", toupper(tipo), " --- participación en el valor exportado (%)")
df |>
filter(ref_year %in% c(año_min, año_max_hs6)) |>
summarise(valor = sum(valor_usd, na.rm = TRUE), .by = c(ref_year, exportador)) |>
mutate(part_pct = round(valor / sum(valor) * 100, 1), .by = ref_year) |>
select(-valor) |>
pivot_wider(names_from = ref_year, values_from = part_pct) |>
print(n = Inf)
message("Peso del residuo, por año (%):")
df |>
summarise(valor = sum(valor_usd, na.rm = TRUE), .by = c(ref_year, exportador)) |>
mutate(part_pct = round(valor / sum(valor) * 100, 1), .by = ref_year) |>
filter(exportador == otros_lab) |>
select(ref_year, part_pct) |>
print(n = Inf)
}
resumen(palma_crudo, "crudo")
resumen(palma_refinado, "refinado")
rm(resumen)
# --- Figura 19: exportaciones de crudo por origen, paneles libres -----------
# Nueve paneles: el top-10 de crudo menos Marfil, sin el residuo. Escala
# libre: los NIVELES no son comparables entre paneles -- Indonesia corre dos
# órdenes de magnitud arriba de Honduras -- y por eso cada panel lleva su
# propio eje rotulado.
local({
excluir_paneles <- c(es_pais("Côte d'Ivoire"), otros_lab)
paneles <- setdiff(levels(palma_crudo$exportador), excluir_paneles)
saveRDS(paneles, here::here("Data", "paneles_crudo_top9.rds"))
stopifnot(all(setdiff(excluir_paneles, otros_lab) %in% levels(palma_crudo$exportador)))
message("Paneles (", length(paneles), "): ", paste(paneles, collapse = ", "))
serie_paneles <- palma_crudo |>
filter(exportador %in% paneles) |>
summarise(valor_mm = sum(valor_usd, na.rm = TRUE) / 1e9,
.by = c(ref_year, exportador)) |>
mutate(exportador = factor(exportador, levels = paneles))
# Los decimales del eje se derivan del PASO entre marcas de cada panel, no de
# la magnitud del valor: con `free_y`, un panel centrado en 0,2 con paso 0,05
# necesita dos decimales aunque otro panel, con valores mucho más grandes,
# no necesite ninguno.
num_es_auto <- function(x) {
b <- x[!is.na(x)]
if (length(b) == 0) return(character(0))
paso <- if (length(b) > 1) min(diff(sort(b))) else max(abs(b), 1)
dec <- max(0, ceiling(-log10(paso)))
label_number(accuracy = 10^(-dec), big.mark = ".", decimal.mark = ",")(x)
}
p <- ggplot(serie_paneles, aes(ref_year, valor_mm, colour = exportador)) +
geom_line(linewidth = 0.8) +
geom_point(size = 1.2) +
facet_wrap(~ exportador, ncol = 3, scales = "free_y") +
scale_colour_manual(values = colores_de(palma_crudo), guide = "none") +
scale_x_continuous(breaks = seq(año_min, año_max_hs6, 4)) +
scale_y_continuous(labels = num_es_auto, limits = c(0, NA),
expand = expansion(mult = c(0, 0.05))) +
labs(
title = "Figura 19. Exportaciones mundiales de aceite de palma crudo, por exportador",
subtitle = paste("Valor exportado, miles de millones de US$.",
"Escala vertical propia de cada panel: los niveles no son comparables entre paneles."),
x = NULL, y = NULL,
caption = caption_fuente("crudo")
) +
tema_drp
print(p)
ggsave(here::here("Plots", "palma_crudo_paneles_libre.png"), p,
width = 9, height = 5.5, dpi = 300, bg = "white")
})
# --- Limpieza final ------------------------------------------------------------
rm(palm, agrupar, palma_crudo, palma_refinado)
El análisis del mercado de exportación de aceite de palma tiene dos segmentos claramente diferenciados, y cuyos números no se pueden sumar a nivel global, aunque si para países individuales. El aceite crudo puede venderse y exportarse como tal, aunque no es todavía un producto comestible, y lo mismo sucede con el aceite refinado. Suponiendo que no hay importaciones, las exportaciones totales de aceite de un pais son la suma de las exportaciones de crudo y las de refinado.
No sucede lo mismo con las cifras globales. Muchos países importan crudo para reexportarlo o para procesarlo y exportar el aceite refinado, y también pueden usar el aceite importado para manufacturar productos derivados del aceite de palma, como margarina y otros. Si sumáramos todas las exportaciones de aceite crudo y todas las de aceite refinado estaríamos incurriendo en doble contabilidad. Por esta razón, en lo que sigue, cada uno de estos mercados se trata por separado.
El comportamiento reciente de las exportaciones de aceite de palma crudo, medido por valor, se muestra en la Figura 15. Los datos en UN COMTRADE, la fuente de la información utilizada en este gráfico, no están completos para todos los países más allá de 2023. Por definición, datos en términos de valor son el resultado de cambios en la cantidad y cambios en el precio, pero la información sobre precios que se presentó en la Sección 1 permite dilucidar el efecto predominante en cada período.
La caída en el valor de las exportaciones entre 2010 y 2016 está asociada a la reducción de los precios (ver Figura 3) que tuvo lugar de 2011 en adelante, conforme se normalizaron las condiciones meteorológicas y se recuperó la producción. Más interesante resulta el comportamiento del mercado entre 2016 y 2020: durante ese período los precios promedio siguieren bajando, pero el valor de las exportaciones creció. Esto es necesariamente efecto del incremento del volumen ficiso de las exportaciones.
La Figura 15 termina con una caída en el valor de las exportaciones, pero ya vimos en la Sección 1 que los precios se han recuperado rápidamente entre 2023 y 2025, lo que necesariamente se reflejan en el valor de las exportaciones en esos dos años.
knitr::include_graphics(here::here("Plots", "palma_crudo_totales.png"))
Un detalle preliminar, que conviene recordar, es que en términos físicos, las exportaciones de aceite crudo y refinado no se pueden sumar, ya que obviamente el aceite refinado se deriva del crudo. Pero en términos de valor, aunque las exportaciones de crudo y refinado de un país individual se podrían sumar, hacerlo con las exportaciones totales implicaría una doble contabilidad: hay países que importan crudo, lo procesan y exportan refinado.
El comportamiento de las exportaciones de aceite refinado se diferencia en dos aspectos importantes de el de las exportaciones de aceite crudo. En primer lugar, como es evidente si se comparan las Figuras 15 y 16, es que el valor de estas exportaciones es mucho más elevado. En segundo lugar, y este punto es quizás el más importante, es que la volatilidad es menor. Entre 2010 y 2016, mientras el valor de las exportaciones de aceite crudo desciende, el de las exportaciones de aceite refinado se mantiene estable. A partir del momento en que el valor de las exportaciones de crudo se empieza a incrementar, el del aceite refinado también crece, pero más rápidamente.
Esto sugiere que una estrategia de mitigación del riesgo asociado con la volatilidad de los precios, y de captura de un mayor valor agregado, buscaría incrementar el porcentaje de refinado versus crudo dentro del portafolio de ventas de un país o una empresa individual.
knitr::include_graphics(here::here("Plots", "palma_refinado_totales.png"))
El análisis de la distribución por país de la participación en cada uno de estos mercados es altamente instructivo.
En la Figura 17 se presenta la participación de los principales exportadores de aceite crudo y su evolución entre 2010 y 2023. Salta inmediatamente a la vista es la muy marcada y consistente participación de Indonesia, que representaba casi el 60% del mercado de aceite crudo en 2010, y apenas un 26% en 2023.
Este patrón no es producto de la casualidad, sino el resultado de una estrategia explícita de desarrollo industrial que Indonesia ha aplicado de manera consistente por un largo período. En la Sección 7 de este informe se discute brevemnte esa estrategia, así como sus implicaciones desde el punto de vista de la competitividad del sector productor de aceite de palma en Costa Rica.
En el caso de Malasia, el rasgo más notorio es la volatilidad de su participación en este mercado, que llegó a ser de tan solo un 22% en 2010, pero superó el 40% en 2021. Sin embargo, estas oscilaciones no parecen marcar una tendencia clara ni al aumento ni a la reducción de la participación de Malasia en el mercado de exportaciones de aceite de palma crudo.
Los países que crecen de manera sistemática son sin excepción países que tenían una participación casi despreciable en el mercado en 2010, pero que en conjunto ya representan un 40% en 2022: Tailandia, Papúa Nueva Guinea, Guatemala, Colombia, Costa Rica, Honduras y Costa de Marfil. Es cierto que en el gráfico también aparecen los Países Bajos, pero es obvio que en este caso se trata de reexportaciones, no de exportaciones de producción propia.
knitr::include_graphics(here::here("Plots", "palma_crudo_composicion.png"))
En las exportaciones de aceite de palma refinado el patrón es casi exactamente el opuesto: Indonesia capturaba el 31% de ese mercado en 2010, y elevó su participación a casi un 60% en 2023. Los demás exportadores de aceite refinado - que, como es obvio a partir de la lista incluida en la Figura 18, incluye varios países que no producen aceite de palma - han incrementado ligeramente su participación, que pasa del 14 al 16% del mercado entre 2010 y 2025. Aún así, el peso dominante de Indonesia es evidente. Si se suman las exportaciones de Malasia, entre ambos países suman el 86% de las exportaciones mundiales de aceite refinado.
El cambio en el peso de la participación de Indonesia en los mercados de aceite crudo y aceite refinado no es una casualidad, sino que es apenas la manifestación más obvia de una estrategia nacional de transformación e industrialización del sector de aceite de palma que, junto con las instituciones científicas que trabajan en temas relevantes para dicha estrategia, constituye posiblemente la ventaja competitiva más sólida de Indonesia.
Como se verá más adelante, esta estrategia no se limita a promover la exportación de aceite refinado en vez de crudo, sino también la de aceite del coquito de la palma, varios productos derivados, así como la utilización del aceite de palma en la fabricación de biodiesel. En la Sección 7 de este documento se presenta una descripción más detallada de dicha estrategia.
Cabe anotar que la estrategia indonesia que esquemáticamente se acaba de describir, junto con una institucionalidad científica amplia y de muy altas calificaciones enfocada en la agroindustria del aceite de palma. Es, además, la ventaja competitiva que a Costa Rica le resultaría más difícil replicar: el país no tiene una política industrial explícita, no tienen una institucionalidad científica sólida en el sector agrícola, y en todo caso, carece de los recursos para financiar un programa de transformación del sector semejante al indonesio. Esta estrategia es tan importante que en este informe se ha dedicado una sección completa, la Sección 5, a su análisis y a la discusión de sus implicaciones desde el punto de vista de Costa Rica.
knitr::include_graphics(here::here("Plots", "palma_refinado_composicion.png"))
La Figura 19, junto con la Tabla 4, permiten una visualización complementaria, aunque por ahora simplificada, de cómo ha cambiado la participación de los principales exportadores en el mercado de aceite crudo. En la Figura 19 simplemente se han graficado estas exportaciones, pero el lector debe poner atención al hecho de que las escalas son muy distintas de un país a otro.
knitr::include_graphics(here::here("Plots", "palma_crudo_paneles_libre.png"))
Para facilitar, entonce, la interpretación de la información presentada en la Figura 19, en la Tabla 4 se presenta la TCAC de las exportaciones de aceite de palma crudo de cada uno de estos países. Indonesia deliberadamente reduce su participación en este mercado (por razones que se discuten en la Sección 7), Malasia crece lentamente, y son países nuevos, incluyendo Papúa Nueva Guinea que ni siquiera figuraba entre los principales exportadores en 2010, los que crecen en este mercado. Por qué y con qué consecuencias es parte de la discución en la Sección 7.
Esta información simplifica la evolución del mercado porque considera la tasa de crecimiento de punta a punta, y no considera cambios de tendencia que ocurren dentro del período, pero permite evidencia el cambio de largo plazo. Más adelante en el documento se examinan los cambios de tendencia entre 2010 y 2025, para una comprensión más granular de la evolución del mercado de aceite de palma.
# Tabla 4: TCAC 2010-2023 de las exportaciones de aceite de palma crudo, para
# los mismos 9 países de la Figura 19 (top-10 menos Côte d'Ivoire, sin el
# residuo). TCAC punto a punto: (valor_2023 / valor_2010)^(1/13) - 1. Mismo
# orden que los paneles del facet_wrap, vía paneles_crudo_top9.rds.
palma_crudo_top10 <- readRDS(here::here("Data", "palma_crudo_top10.rds"))
paneles <- readRDS(here::here("Data", "paneles_crudo_top9.rds"))
tcac <- palma_crudo_top10 |>
filter(exportador %in% paneles, ref_year %in% c(año_min, año_max_hs6)) |>
summarise(valor_usd = sum(valor_usd, na.rm = TRUE), .by = c(exportador, ref_year)) |>
pivot_wider(names_from = ref_year, values_from = valor_usd, names_prefix = "y") |>
mutate(tcac = (.data[[paste0("y", año_max_hs6)]] / .data[[paste0("y", año_min)]])^
(1 / (año_max_hs6 - año_min)) - 1) |>
mutate(exportador = factor(exportador, levels = paneles)) |>
arrange(exportador)
tabla_tcac <- tcac |>
select(exportador, tcac) |>
pivot_wider(names_from = exportador, values_from = tcac) |>
mutate(fila = "TCAC", .before = 1) |>
gt(rowname_col = "fila") |>
fmt_percent(columns = -fila, decimals = 1, dec_mark = ",", sep_mark = ".") |>
tab_stubhead(label = "") |>
tab_header(title = "Tabla 1. TCAC 2010-2023 de las exportaciones de aceite de palma crudo") |>
tab_source_note("Fuente: elaboración propia con base en UN Comtrade HS 1511.10") |>
tab_options(table.font.size = px(13),
heading.title.font.size=px(14)
)
tabla_tcac
| Tabla 1. TCAC 2010-2023 de las exportaciones de aceite de palma crudo | |||||||||
| Malasia | Indonesia | Tailandia | PNGuinea | Guatemala | Colombia | PBajos | CR | Honduras | |
|---|---|---|---|---|---|---|---|---|---|
| TCAC | 2,1% | −6,8% | 22,3% | NA | 17,8% | 16,9% | 5,4% | 7,2% | 11,4% |
| Fuente: elaboración propia con base en UN Comtrade HS 1511.10 | |||||||||
rm(palma_crudo_top10, paneles, tcac, tabla_tcac)
En la Sección 3 se examinó el origen de las exportaciones de aceite tanto crudo como refinado, tanto de manera agregada como por país de origen.
Sin embargo, existe otra dimensión del mercado que también ha mostrado cambios considerables, y que hasta ahora no hemos analizado: ¿adónde se dirgen esas exportaciones? Este es el tema que se examina en esta sección.
Empezamos por las exportaciones de aceite de palma crudo. La Figura 20 concentra una gran cantidad de información, ya que despliega, para los principales exportadores, los principales destinos de exportación tanto en 2010 como en 2023. Los cambios son pronunciados.
El primer cambio, y quizás el más obvio, es el peso creciendo de la India, que para los tres mayores exportadores se convierte, por un margen muy amplio, en el destino más importante: 69% de las exportaciones de aceite crudo de Malasia, 86% de las de Indonesia y 97% de las de Tailandia. Esto es importante desde el punto de vista de Costa Rica: India es una economía en crecimiento, tanto económico como poblacional, en contraste con China, hasta ahora el país más poblado del mundo, pero que podría ser desplazdo de esa posición por India.
Dada la cercanía geográfica entre Malasia, Indonesia, Tailandia e India, en la medida en que la demanda de este último país crezca más rápido que la producción de aceite crudo de los tres primeros países, es razonable suponer que India seguirá siendo el principal destino de sus exportaciones de aceite crudo.
En el caso de los países centroamericanos y Colombia, el cambio más notorio es la reducción de la importancia de México, que era el principal destino de exportación de todos ellos en 2010, y no lo es para ninguno en 2023. Recuérdese que este es un período de crecimiento de dos dígitos de las exportaciones de Colombia, Guatemala, Costa Rica y Honduras. La reducción de la importancia del mercado mexicano no surge de problemas de oferta o competitividad de estos países, sino del incremento de la producción mexicana, que abastecía su demanda interna casi exclusivamente con importaciones, pero ya en 2019 fue capaz de atender el 10% de esa demanda con producción doméstica, y para 2025 logró incrementar ese porcentaje hasta un 40% (COMEXPALMA-SADER 2021, FEMEXPALMA 2025, Isaac-Marquez, I. 2021)
# Autocontenido: sólo necesita palma_crudo/palma_refinado, ya guardados en
# disco por plot_sec3 (Tablas top-10 + residuo), así que se leen esos .rds
# en vez de volver a tocar el archivo bilateral completo.
n_dest_max <- 9 # destinos con baldosa propia, tope por exportador
min_part_dest <- 0.01 # piso de participación en año_max_hs6
otros_dest <- "Otros destinos" # residuo del lado DESTINO, distinto de `otros_lab`
años_treemap <- c(año_min, año_max_hs6)
palma_crudo <- readRDS(here::here("Data", "palma_crudo_top10.rds"))
palma_refinado <- readRDS(here::here("Data", "palma_refinado_top10.rds"))
# Construye el data frame de baldosas (exportador x año x destino_lab) para un
# universo. Misma lógica en las dos secciones de treemaps del archivo:
# filtrar por participación ANTES de cortar en `n_dest_max`, para no gastar
# baldosas en destinos irrelevantes.
armar_treemap_destinos <- function(df) {
paneles <- setdiff(levels(df$exportador), otros_lab)
base <- df |>
filter(exportador %in% paneles, ref_year %in% años_treemap) |>
summarise(valor = sum(valor_usd, na.rm = TRUE),
.by = c(exportador, ref_year, destino))
sel <- base |>
filter(ref_year == año_max_hs6) |>
mutate(part = valor / sum(valor), .by = exportador) |>
filter(part >= min_part_dest) |>
slice_max(valor, n = n_dest_max, by = exportador, with_ties = FALSE) |>
transmute(exportador, destino, sel = TRUE)
base |>
left_join(sel, by = c("exportador", "destino")) |>
mutate(destino_lab = if_else(is.na(sel), otros_dest, es_pais(destino))) |>
summarise(valor = sum(valor), .by = c(exportador, ref_year, destino_lab)) |>
mutate(part = valor / sum(valor), .by = c(exportador, ref_year))
}
# Dibuja el treemap consolidado (todos los exportadores x los dos años). La
# paleta de destinos se asigna sobre el conjunto de destinos que aparece en
# CUALQUIER panel, no por exportador, para que un mismo destino (p. ej. Países
# Bajos) conserve su color en todos los renglones.
fig_treemap_destinos <- function(treemap_df, tipo, numero) {
destinos_todos <- treemap_df |>
filter(destino_lab != otros_dest) |>
distinct(destino_lab) |>
arrange(destino_lab) |>
pull(destino_lab)
colores <- setNames(rep_len(paleta_origen, length(destinos_todos)), destinos_todos)
colores[otros_dest] <- gris_residuo
ggplot(
treemap_df,
aes(area = part, fill = destino_lab,
label = if_else(part >= label_min_pct,
paste0(destino_lab, "\n", pct_es(part)), ""))
) +
geom_treemap(colour = "white", size = 0.4) +
geom_treemap_text(colour = "white", place = "centre",
grow = FALSE, size = 10, reflow = TRUE, lineheight = 0.9) +
facet_grid(exportador ~ ref_year, switch = "y") +
scale_fill_manual(values = colores) +
labs(
title = paste0("Figura ", numero, ". Destinos de las exportaciones de aceite de palma ",
lab_aceite[[tipo]], ", ", año_min, " y ", año_max_hs6),
subtitle = paste0("Participación en el valor exportado del año; top-", n_dest_max,
" destinos por exportador, residuo en '", otros_dest, "'."),
caption = caption_fuente(tipo)
) +
tema_drp +
theme(legend.position = "none",
strip.text.y.left = element_text(angle = 0),
panel.grid = element_blank(),
axis.text = element_blank(), axis.ticks = element_blank())
}
local({
df <- armar_treemap_destinos(palma_crudo)
p <- fig_treemap_destinos(df, "crudo", 20)
print(p)
ggsave(here::here("Plots", "palma_crudo_destinos.png"),
p, width = 8.5, height = 11, dpi = 300, bg = "white")
})
local({
df <- armar_treemap_destinos(palma_refinado)
p <- fig_treemap_destinos(df, "refinado", 21)
print(p)
ggsave(here::here("Plots", "palma_refinado_destinos.png"),
p, width = 8.5, height = 11, dpi = 300, bg = "white")
})
rm(n_dest_max, min_part_dest, otros_dest, años_treemap, palma_crudo, palma_refinado,
armar_treemap_destinos, fig_treemap_destinos)
knitr::include_graphics(here::here("Plots", "palma_crudo_destinos.png"))
Los destinos de las exportaciones de aceite de palma refinado, según país de origen, en 2010 y 2023 se muestran en la Figura 21. Es notorio que en esta figura se incluyen bastantes países que no son productores de palma, pero debe recordarse que los dos países más importantes, tanto en crudo como en refinado, son Malasia e Indonesia, que juntos representan el 84% de las exportaciones de aceite de palma refinado en 2023 (Ver Figura 18).
En esta figura, un rasgo notorio es la diversificación de las exportaciones de Indonesia y Malasia. La figura se construyó identificando a los 9 destinos principales de manera individual y agrupando todos los demás países bajo el rubro “Otros destinos”. Este rubro resultó ser el principal destino para ambos países, tanto en 2010 como con 2023.
El segundo punto de interés, desde la perspectiva de este estudio, es que ningún país latinoamericano se encuentra entre los principales exportadores de aceite refinado; la región tiene una presencia que no es despreciable en las exportaciones de aceite crudo, pero no en las de refinado. Es decir, está concentrado en la parte del mercado - materias primas - de mayor volatilidad de precios y menor valor agregado.
knitr::include_graphics(here::here("Plots", "palma_refinado_destinos.png"))
Hasta este punto, nuestro análisis se ha planteado desde el punto de vista de productores y exportadores. En esa sección se cambia de perspectiva, y el mercado se analiza desde el punto de vista de los importadores.
Una nota metodológica: UN COMTRADE contiene tanto los datos reportados por exportadores como los reportados por importadores, y por diversas razones esos datos pueden mostrar discrepancias. La existencia de aranceles, así como de diferencias en el tratamiento arancelario de distintos renglones del Sistema Armonizado pueden contribuir, entre otras causas, a estas discrepancias.
Por esta razón, y para asegurar una estricta comparabilidad de las cifras, en esta sección seguimos utilizando la misma base de datos que en las dos anteriores, es decir, los datos reportados por los exportadores, pero ahora agrupada no por por país exportador sino por país importador.
La Figura 22 muestra el origen de las importaciones de aceite de palma crudo de los principales importadores (según el monto de las importaciones en 2023). Los importadores están ordenados de mayor a menor según el valor de las importaciones.
Un primer rasgo del proceso de cambio en el mercado de exportaciones de aceite crudo entre 2010 y 2025 es la reducción de la participación de Indonesia en todos los mercados en los que tenía un predominio indisputable en 2010: India, Países Bajos, Kenia, España, Italia, Malasia e Indonesia. Esto es completamente congruente con la estrategia de estimular las exportaciones de aceite refinado y productos derivados del aceite de palma, y desincentivar la exportación de aceite crudo.
Como consecuencia de lo anterior, todos los países incluidos en el gráfico, con la excepción del Reino Unido y Bélgica tiene un portafolio de fuentes de abastecimiento mucho más diversificado en 2023 que en 2025. Desde el punto de vista de los exportadores, esto es lo mismo que decir que hay una competencia muy fuerte en todos los mercados de destino.
Los países centroamericanos tienen presencia en los mercados de importación de los Países Bajos, México, España, Italia y Alemania. En todos ellos Guatemala es el exportador de mayor peso. Costa Rica ocupa la tercera posición o posiciones inferiores en esos mismos mercados.
Por último, la figura pone en evidencia el papel de los Países Bajos como centro de re exportación: es el principal origen del aceite crudo importado por Alemania, en donde tiene una participación del 56% y tiene una participación del 7% tanto en el Reino Unido como en Bélgica.
# Chunk único y autocontenido para toda la Sección 4: recarga `palm` de forma
# independiente (la Etapa B, en plot_sec3, hace rm(palm) al terminar), y
# cubre crudo y refinado juntos porque comparten rank_import/años_rank_m/
# años_treemap/n_top_origen/otros_lab_origen. Se corre línea por línea; una
# vez guardados los PNG, este chunk pasa a echo=TRUE, eval=FALSE.
palm <- readRDS(here::here("Data", "comtrade_palm_bilateral_hs6_2010_2024.rds")) |>
as_tibble() |>
select(
ref_year, cmd_code, reporter_desc,
destino = partner_desc,
valor_usd = primary_value,
wgt_kg = net_wgt
) |>
filter(destino != "World", ref_year >= año_min, ref_year <= año_max_hs6) |>
mutate(
volumen_t = wgt_kg / 1000,
aceite = unname(c("151110" = "crudo", "151190" = "refinado")[cmd_code])
) |>
select(-wgt_kg, -cmd_code)
stopifnot(!anyNA(palm$aceite))
años_rank_m <- (año_max_hs6 - 1):año_max_hs6
# Ventana de dos años, no los tres del lado exportador: acá interesa la
# composición reciente, no aplanar un posible año atípico.
años_treemap <- c(año_min, año_max_hs6)
n_top_origen <- 10
otros_lab_origen <- "Resto"
rank_import <- palm |>
filter(ref_year %in% años_rank_m) |>
summarise(valor = sum(valor_usd, na.rm = TRUE), .by = c(aceite, destino)) |>
arrange(aceite, desc(valor)) |>
mutate(
rango = row_number(),
part = valor / sum(valor),
part_acum = cumsum(part),
.by = aceite
)
message("Cobertura acumulada, top 15 importadores por tipo de aceite:")
rank_import |>
filter(rango <= 30) |>
transmute(aceite, rango, destino,
part_pct = round(part * 100, 1),
acum_pct = round(part_acum * 100, 1)) |>
print(n = Inf)
# --- Figura 26: crudo ---------------------------------------------------------
importadores_crudo <- rank_import |>
filter(aceite == "crudo", rango <= n_top) |>
select(destino, rango)
rank_origen_crudo <- palm |>
filter(aceite == "crudo") |>
semi_join(importadores_crudo, by = "destino") |>
filter(ref_year %in% años_rank_m) |>
summarise(valor = sum(valor_usd, na.rm = TRUE), .by = c(destino, reporter_desc)) |>
arrange(destino, desc(valor)) |>
mutate(rango = row_number(), .by = destino)
origenes_sel_crudo <- rank_origen_crudo |>
filter(rango <= n_top_origen) |>
select(destino, reporter_desc) |>
mutate(en_top = TRUE)
niveles_importador_crudo <- importadores_crudo |> arrange(rango) |> pull(destino) |> es_pais()
datos_treemap_crudo <- palm |>
filter(aceite == "crudo") |>
semi_join(importadores_crudo, by = "destino") |>
filter(ref_year %in% años_treemap) |>
left_join(origenes_sel_crudo, by = c("destino", "reporter_desc")) |>
mutate(
origen = if_else(is.na(en_top), otros_lab_origen, es_pais(reporter_desc)),
importador = factor(es_pais(destino), levels = niveles_importador_crudo)
) |>
summarise(valor_usd = sum(valor_usd, na.rm = TRUE),
.by = c(importador, ref_year, origen)) |>
mutate(part = valor_usd / sum(valor_usd), .by = c(importador, ref_year))
saveRDS(datos_treemap_crudo, here::here("Data", "palma_crudo_importadores_origenes.rds"))
message("Filas por importador y año (top 10 + Resto -> hasta 11):")
datos_treemap_crudo |> count(importador, ref_year) |>
summarise(min_filas = min(n), max_filas = max(n)) |> print()
local({
# Paleta fija por país de origen, no por posición dentro del panel: así
# Indonesia es el mismo azul en todos los paneles.
origenes_todos <- datos_treemap_crudo |>
filter(origen != otros_lab_origen) |>
distinct(origen) |>
arrange(origen) |>
pull(origen)
colores_origen <- setNames(rep_len(paleta_origen, length(origenes_todos)), origenes_todos)
colores_origen[otros_lab_origen] <- gris_residuo
p <- ggplot(
datos_treemap_crudo,
aes(area = part, fill = origen,
label = if_else(part >= label_min_pct,
paste0(origen, "\n", pct_es(part)), ""))
) +
geom_treemap(colour = "white", size = 0.4) +
geom_treemap_text(colour = "white", place = "centre",
grow = FALSE, size = 10, reflow = TRUE, lineheight = 0.9) +
facet_grid(importador ~ ref_year, switch = "y") +
scale_fill_manual(values = colores_origen) +
labs(
title = paste0("Figura 22. Origen del aceite de palma crudo importado, ",
año_min, " y ", año_max_hs6),
subtitle = paste0("Top-", n_top, " importadores; top-", n_top_origen,
" orígenes por importador, residuo en '", otros_lab_origen, "'."),
caption = caption_fuente("crudo")
) +
tema_drp +
theme(legend.position = "none",
strip.text.y.left = element_text(angle = 0),
panel.grid = element_blank(),
axis.text = element_blank(), axis.ticks = element_blank())
print(p)
ggsave(here::here("Plots", "palma_crudo_importadores_origen.png"),
p, width = 8.5, height = 11, dpi = 300, bg = "white")
})
rm(importadores_crudo, rank_origen_crudo, origenes_sel_crudo,
niveles_importador_crudo, datos_treemap_crudo)
# --- Figura 27: refinado -------------------------------------------------------
importadores_refinado <- rank_import |>
filter(aceite == "refinado", rango <= n_top) |>
select(destino, rango)
# Cobertura real del top-N en refinado, para el subtítulo: se calcula acá y no
# se escribe a mano, así que si `n_top` cambia el subtítulo no queda
# desactualizado en silencio.
cobertura_refinado <- rank_import |>
filter(aceite == "refinado", rango == n_top) |>
pull(part_acum) |>
(\(x) round(x * 100, 1))()
rank_origen_refinado <- palm |>
filter(aceite == "refinado") |>
semi_join(importadores_refinado, by = "destino") |>
filter(ref_year %in% años_rank_m) |>
summarise(valor = sum(valor_usd, na.rm = TRUE), .by = c(destino, reporter_desc)) |>
arrange(destino, desc(valor)) |>
mutate(rango = row_number(), .by = destino)
origenes_sel_refinado <- rank_origen_refinado |>
filter(rango <= n_top_origen) |>
select(destino, reporter_desc) |>
mutate(en_top = TRUE)
niveles_importador_refinado <- importadores_refinado |> arrange(rango) |> pull(destino) |> es_pais()
datos_treemap_refinado <- palm |>
filter(aceite == "refinado") |>
semi_join(importadores_refinado, by = "destino") |>
filter(ref_year %in% años_treemap) |>
left_join(origenes_sel_refinado, by = c("destino", "reporter_desc")) |>
mutate(
origen = if_else(is.na(en_top), otros_lab_origen, es_pais(reporter_desc)),
importador = factor(es_pais(destino), levels = niveles_importador_refinado)
) |>
summarise(valor_usd = sum(valor_usd, na.rm = TRUE),
.by = c(importador, ref_year, origen)) |>
mutate(part = valor_usd / sum(valor_usd), .by = c(importador, ref_year))
saveRDS(datos_treemap_refinado, here::here("Data", "palma_refinado_importadores_origenes.rds"))
message("Cobertura del top-", n_top, " en refinado: ", cobertura_refinado, "%")
local({
origenes_todos <- datos_treemap_refinado |>
filter(origen != otros_lab_origen) |>
distinct(origen) |>
arrange(origen) |>
pull(origen)
colores_origen <- setNames(rep_len(paleta_origen, length(origenes_todos)), origenes_todos)
colores_origen[otros_lab_origen] <- gris_residuo
p <- ggplot(
datos_treemap_refinado,
aes(area = part, fill = origen,
label = if_else(part >= label_min_pct,
paste0(origen, "\n", pct_es(part)), ""))
) +
geom_treemap(colour = "white", size = 0.4) +
geom_treemap_text(colour = "white", place = "centre",
grow = FALSE, size = 10, reflow = TRUE, lineheight = 0.9) +
facet_grid(importador ~ ref_year, switch = "y") +
scale_fill_manual(values = colores_origen) +
labs(
title = paste0("Figura 23. Origen del aceite de palma refinado importado, ",
año_min, " y ", año_max_hs6),
subtitle = paste0("Los top-", n_top, " importadores concentran ", cobertura_refinado,
"% del valor importado"),
caption = caption_fuente("refinado")
) +
tema_drp +
theme(legend.position = "none",
strip.text.y.left = element_text(angle = 0),
panel.grid = element_blank(),
axis.text = element_blank(), axis.ticks = element_blank())
print(p)
ggsave(here::here("Plots", "palma_refinado_importadores_origen.png"),
p, width = 8.5, height = 11, dpi = 300, bg = "white")
})
rm(palm, importadores_refinado, rank_origen_refinado, origenes_sel_refinado,
niveles_importador_refinado, datos_treemap_refinado, cobertura_refinado,
rank_import, años_rank_m, n_top_origen, otros_lab_origen, años_treemap)
knitr::include_graphics(here::here("Plots", "palma_crudo_importadores_origen.png"))
El panorama es completamente distinto en el caso del aceite de palma refinado. La lista de principales importadores es muy diferente, y los principales orígenes también lo son. La Figura 23 muestra estos datos.
Una primera diferencia con respecto al mercado de aceite crudo es que ningún país europeo se encuentra entre los principales importadores de aceite refinado, así como el peso de los países asiáticos en la lista de principales importadores: China, Pakistán, India, EUA, Bangladesh, Filipinas, Egipto, Rusia, Turquía y Vietnam.
En 2010, Indonesia y Malasia, considerados conjuntamente, suministraro más del 90% del aceite importado en todos los casos, con la excepción de Rusia. Este predominio se mantiene, de nuevo con la excepción de Rusia, en 2023, pero la distribución del mercado entre Indonesia y Malasia cambia sustancialmente: mientras que en 2010 Malasia era el principal origen en la mayor parte de los mercados de importación, con la notable excepción de la India, en 2023 Indonesia domina de manera aplastante en China, Pakistán, EUA, Bangladesh y Egipto. Solo en los mercados de Filipinas, Turquía y Vietnam sigue teniendo Malasia una participación mayor o igual al 40% del mercado.
La estrategia Indonesia de promover las exportaciones de aceite refinado y desincentivar las de aceite crudo ha sido, a la luz de la evidencia, un éxito contundente.
knitr::include_graphics(here::here("Plots", "palma_refinado_importadores_origen.png"))
Aunque en la Sección 2 de este informe se presentaron cifras sobre la producción de aceite de palma, hasta ahora no se ha prestado atención ni al concepto de oferta total en cada país, que consiste en la suma de la producción propia más las importaciones, ni a su asignación ya sea a exportaciones o mercado doméstico, y dentro de este último, a usos alimentarios o industriales.
Este aspecto del mercado del mercado es el tema central de esta sección.
Antes de discutir los datos es importante notar una diferencia sustancial con respecto a los de las secciones anteriores, en las que siempre se tratron por separado el aceite crudo y el aceite refinado. La información que usamos en esta sección proviene de las bases de datos del Departamento de Agricultura de EUA, que no hace esa distinción.
A la luz de algunos comentarios previos podría pensarse en que tratar el aceite de palma sin separar crudo de refinado consiste un error de bulto, que induce, como antes se explicó, en doble contabilidad, pero no es así: recordemos que desde el inicio se planteó que a nivel agregado no se pueden sumar válidamente los datos de crudo y refinado, pues se incurriría en doble contabilidad; este problema no existe cuando se trata de los datos de países individuales, que es lo que se presenta a lo largo de esta sección.
Esta sección incluye otro cambio metodológico importante con respecto a las anteriores, en las cuales el énfasis se ha puesto en los cambios en el mercado de aceite de palma “de punta a punta”, es decir, entre 2010 y 2023, pero una rápida mirada a los gráficos muestra que el ritmo y las tendencias del cambio no han sido uniformes en este lapso.
De hecho, ya en las figuras 16 y 17 mostramos líneas de tendencia para dos sub períodos distintos y enfatizamos el cambio que se produjo en 2016, fecha a la cual crecieron de manera marcada tanto las exportaciones de aceite crudo como las de refinado, pero el punto de quiebre fue identificado mediante inspección, y las lineas de tendencia son meramente ilustrativas.
Una terceras diferencia es la cobertura temporal: tenemos datos que van desde 2000 hasta 2025, por una parte porque en la base de datos de USDA hay datos completos hasta esta última fecha, y por otra porque para la estimación estadística de puntos de quiebre era necesario contar con más observaciones que las utilizadas en las secciones anteriores.
En esta sección, en contraste con las anteriores, se presta cuidados atención precisamente a esos puntos de quiebre en las tendencias de mercado, pero además, se usan técnicas estadísticas para identificarlos.
# Chunk único y autocontenido para toda la Sección 5. obtener_quiebre(),
# caption_quiebres y col_quiebre ya viven en setup -- no se redefinen acá.
# Se corre línea por línea; una vez guardados los PNG, este chunk pasa a
# echo=TRUE, eval=FALSE.
usda_palm_tidy <- readRDS(here::here("Data", "usda_palm_tidy.rds"))
usda_palm_tidy <- usda_palm_tidy |> mutate(marketYear = as.integer(marketYear))
# --- nombres de país en español ---------------------------------------------
# countryName llega en inglés desde USDA PSD. Se traduce acá, una sola vez,
# para que quede consistente en rankings, agrupaciones, facets y subtítulos
# más abajo. Lista cubre los exportadores plausibles del top-15; países no
# listados conservan su nombre original (.default) en vez de volverse NA.
nombres_es <- c(
"Indonesia" = "Indonesia",
"Malaysia" = "Malasia",
"Thailand" = "Tailandia",
"Colombia" = "Colombia",
"Nigeria" = "Nigeria",
"Guatemala" = "Guatemala",
"Honduras" = "Honduras",
"Ecuador" = "Ecuador",
"Costa Rica" = "Costa Rica",
"Papua New Guinea" = "Papúa Nueva Guinea",
"Brazil" = "Brasil",
"Cote d'Ivoire" = "Costa de Marfil",
"Cambodia" = "Camboya",
"Philippines" = "Filipinas",
"Peru" = "Perú"
)
usda_palm_tidy <- usda_palm_tidy |>
mutate(countryName = dplyr::recode(countryName, !!!nombres_es, .default = countryName))
# --- Top-15 exportadores, base USDA -----------------------------------------
n_top_usda <- 15
año_max_usda <- max(usda_palm_tidy$marketYear, na.rm = TRUE)
años_rank_usda <- (año_max_usda - rank_window + 1):año_max_usda
top15_exportadores <- usda_palm_tidy |>
filter(marketYear %in% años_rank_usda) |>
summarise(exportaciones = sum(exportaciones, na.rm = TRUE), .by = countryName) |>
arrange(desc(exportaciones)) |>
slice_head(n = n_top_usda)
# --- dos grupos de seis países, en el orden del ranking de exportadores
# Se filtra el top-15 a los países con al menos un año utilizable desde 2000
# y luego se toman los primeros 12 de esa lista filtrada (ya ordenada por
# exportaciones desc), para formar dos grupos de seis.
paises_validos <- usda_palm_tidy |>
filter(marketYear >= 2000) |>
mutate(exp_produccion = exportaciones / produccion,
exp_oferta = exportaciones / oferta_total) |>
filter((!is.na(exp_produccion) & is.finite(exp_produccion)) |
(!is.na(exp_oferta) & is.finite(exp_oferta))) |>
distinct(countryName) |>
pull(countryName)
paises_incluidos <- top15_exportadores$countryName[
top15_exportadores$countryName %in% paises_validos
][1:12]
grupos_paises <- split(paises_incluidos, ceiling(seq_along(paises_incluidos) / 6))
# --- Figuras 24-25: exportaciones sobre producción y sobre oferta total -----
razones_top15 <- usda_palm_tidy |>
filter(countryName %in% paises_incluidos, marketYear >= 2000) |>
mutate(
marketYear = as.integer(marketYear),
countryName = factor(countryName, levels = paises_incluidos),
exp_produccion = exportaciones / produccion,
exp_oferta = exportaciones / oferta_total
) |>
select(countryName, marketYear, exp_produccion, exp_oferta) |>
pivot_longer(c(exp_produccion, exp_oferta), names_to = "razon", values_to = "valor") |>
filter(!is.na(valor), is.finite(valor))
quiebres <- razones_top15 |>
summarise(quiebre = obtener_quiebre(pick(marketYear, valor)), .by = c(countryName, razon))
tendencias <- razones_top15 |>
left_join(quiebres, by = c("countryName", "razon")) |>
mutate(tramo = if_else(is.na(quiebre) | marketYear <= quiebre, "antes", "despues")) |>
mutate(ajuste = fitted(lm(valor ~ marketYear)), .by = c(countryName, razon, tramo))
todos_los_años <- min(razones_top15$marketYear):max(razones_top15$marketYear)
años_rotulados <- seq(min(todos_los_años), max(todos_los_años), by = 5)
lab_razon <- c(exp_produccion = "Export. / Producción", exp_oferta = "Export. / Oferta total")
graficar_panel <- function(paises, n_grupo, numero) {
ggplot(filter(razones_top15, countryName %in% paises), aes(marketYear, valor)) +
geom_vline(xintercept = todos_los_años, colour = "grey92", linewidth = 0.5) +
geom_line(linewidth = 0.9, colour = "#2E5C8A") +
geom_line(data = filter(tendencias, countryName %in% paises),
aes(y = ajuste, group = tramo),
colour = "red", linetype = "dashed", linewidth = 0.7) +
geom_vline(data = filter(quiebres, countryName %in% paises, !is.na(quiebre)),
aes(xintercept = quiebre),
colour = col_quiebre, linetype = "dotted", linewidth = 0.8) +
facet_grid(countryName ~ razon, scales = "free_y", switch = "y",
labeller = labeller(razon = lab_razon)) +
scale_x_continuous(breaks = años_rotulados) +
labs(
title = paste0("Figura ", numero, ". Exportaciones sobre producción y sobre oferta total, top exportadores (grupo ",
n_grupo, " de 2)"),
subtitle = paste(paises, collapse = ", "),
x = NULL, y = NULL,
caption = caption_quiebres
) +
tema_drp +
theme(
strip.placement = "outside",
strip.background = element_rect(fill = "#DCEEF7", colour = "black"),
panel.grid.major.x = element_blank(),
strip.text.y = element_text(size = 7),
plot.title = element_text(size = 11),
plot.subtitle = element_text(size = 8)
)
}
panel1 <- graficar_panel(grupos_paises[[1]], 1, 24)
panel2 <- graficar_panel(grupos_paises[[2]], 2, 25)
print(panel1)
print(panel2)
ggsave(here::here("Plots", "usda_razones_export_grupo1.png"),
panel1, width = 8.5, height = 10, dpi = 300, bg = "white")
ggsave(here::here("Plots", "usda_razones_export_grupo2.png"),
panel2, width = 8.5, height = 10, dpi = 300, bg = "white")
rm(razones_top15, quiebres, tendencias, todos_los_años, años_rotulados,
lab_razon, graficar_panel, panel1, panel2)
# --- Figuras 26-27: consumo doméstico: oferta y uso industrial --------------
paneles_consumo <- usda_palm_tidy |>
filter(countryName %in% paises_incluidos, marketYear >= 2000) |>
mutate(
marketYear = as.integer(marketYear),
countryName = factor(countryName, levels = paises_incluidos),
consumo_oferta = consumo_domestico / oferta_total,
uso_industrial_pct = uso_industrial / consumo_domestico
) |>
select(countryName, marketYear, consumo_oferta, uso_industrial_pct) |>
pivot_longer(c(consumo_oferta, uso_industrial_pct), names_to = "razon", values_to = "valor") |>
filter(!is.na(valor), is.finite(valor))
quiebres_consumo <- paneles_consumo |>
summarise(quiebre = obtener_quiebre(pick(marketYear, valor)), .by = c(countryName, razon))
tendencias_consumo <- paneles_consumo |>
left_join(quiebres_consumo, by = c("countryName", "razon")) |>
mutate(tramo = if_else(is.na(quiebre) | marketYear <= quiebre, "antes", "despues")) |>
mutate(ajuste = fitted(lm(valor ~ marketYear)), .by = c(countryName, razon, tramo))
todos_los_años <- min(paneles_consumo$marketYear):max(paneles_consumo$marketYear)
años_rotulados <- seq(min(todos_los_años), max(todos_los_años), by = 5)
lab_razon_consumo <- c(consumo_oferta = "Consumo doméstico / Oferta total",
uso_industrial_pct = "Uso industrial / Consumo doméstico")
graficar_panel_consumo <- function(paises, n_grupo, numero) {
ggplot(filter(paneles_consumo, countryName %in% paises), aes(marketYear, valor)) +
geom_vline(xintercept = todos_los_años, colour = "grey92", linewidth = 0.5) +
geom_line(linewidth = 0.9, colour = "#2E5C8A") +
geom_line(data = filter(tendencias_consumo, countryName %in% paises),
aes(y = ajuste, group = tramo),
colour = "red", linetype = "dashed", linewidth = 0.7) +
geom_vline(data = filter(quiebres_consumo, countryName %in% paises, !is.na(quiebre)),
aes(xintercept = quiebre),
colour = col_quiebre, linetype = "dotted", linewidth = 0.8) +
facet_grid(countryName ~ razon, scales = "free_y", switch = "y",
labeller = labeller(razon = lab_razon_consumo)) +
scale_x_continuous(breaks = años_rotulados) +
labs(
title = paste0("Figura ", numero, ". Consumo doméstico: oferta y uso industrial, top exportadores (grupo ",
n_grupo, " de 2)"),
subtitle = paste(paises, collapse = ", "),
x = NULL, y = NULL,
caption = caption_quiebres
) +
tema_drp +
theme(
strip.placement = "outside",
strip.background = element_rect(fill = "#DCEEF7", colour = "black"),
panel.grid.major.x = element_blank(),
strip.text.y = element_text(size = 7),
plot.title = element_text(size = 11),
plot.subtitle = element_text(size = 8)
)
}
panel1 <- graficar_panel_consumo(grupos_paises[[1]], 1, 26)
panel2 <- graficar_panel_consumo(grupos_paises[[2]], 2, 27)
print(panel1)
print(panel2)
ggsave(here::here("Plots", "usda_consumo_industrial_grupo1.png"),
panel1, width = 8.5, height = 10, dpi = 300, bg = "white")
ggsave(here::here("Plots", "usda_consumo_industrial_grupo2.png"),
panel2, width = 8.5, height = 10, dpi = 300, bg = "white")
# --- Limpieza final ------------------------------------------------------------
rm(usda_palm_tidy, nombres_es, n_top_usda, año_max_usda, años_rank_usda,
top15_exportadores, paises_validos, paises_incluidos, grupos_paises,
paneles_consumo, quiebres_consumo, tendencias_consumo, todos_los_años,
años_rotulados, lab_razon_consumo, graficar_panel_consumo,
panel1, panel2)
Abordamos primero el tema de la relación entre exportaciones y oferta total, así como entre exportaciones y producción doméstica. La distinción es importante: muchas veces en las discusiones sobre desarrollo económico se plantea la necesidad de que los países que aspiran a mayores niveles de ingreso y bienestar dejen de especializarse en la exportación de materias primas, y que en vez de ello, agreguen valor mediante la industrialización y procesamiento de la materia prima que producen. El economista Ricardo Hausmann siempre plantea la pregunta: ¿por qué limitarse a las materias primas que se producen domésticamente? Bélgica produce chocolates de la más alta calidad utilizando materia prima cien por ciento importada; Japón se convirtió en una potencia automovilística sin contar con yacimientos de hierro, en una época en que los carros se fabricaban con acero, y sigue siendo una potencia en la producción de maquinaria y equipo de acero.
De la misma manera, los países que han logrado incursionar con éxito en los mercados de productos derivados de aceite de palma (así como aceite refinado, pero los datos de USDA no nos permiten analizar este producto por separado) no ven limitadas sus exportaciones por la disponibilidad de materia prima propia, sino que pueden ser al mismo tiempo productores y exportadores de aceite.
Examinamos, entonces, la relación entre las exportaciones y la oferta total (producción propia más importaciones) así como entre las exportaciones y la producción doméstica, empezando con los dos países más importantes en este mercado: Indonesia y Malasia.
En el caso de Malasia, las exportaciones representan cerca del 40% de la oferta total, y algo más del 50% de la oferta doméstica. Es decir, aunque la producción doméstica sería suficiente para atender todas las exportaciones, Indonesia importa aceite, y de la oferta total dedica el 60%, aproximadamente, al mercado interno. Los usos de ese 60% se discuten un poco más adelante.
Pero las afirmaciones anteriores se refiere a los datos de 2025: entre 2000 y 2016 el porcentaje de la oferta total y de la producción que se exportaba era cada vez mayor, pero la tendencia se revierte, de manera muy marcada, a partir de ese último año. Es decir, es solo tras incursionar con éxito en los mercados de exportación que se reduce el porcentaje exportado. Pero nótese que el origen de la política que promueve la industrialización y desincentiva la exportación de aceite crudo tuvo sus orígenes entre 2010 y 2011. Pasaron seis años antes de que la estrategia rindiera sus frutos (ya en 2004 se había establecido un impuesto a la exportacion de aceite crudo, pero en aquel momento el objetivo era la estabilización de los precios internos y la protección de los consumidores domésticos, no la industrialización)(Rifin, 2010).
En Malasia se produce un cambio semejante, que empieza incluso antes, pero con resultados mucho más modestos. Más del 70% de la oferta total y más del 80% de la producción se exportó en 2025.
El constaste con Tailandia, Colombia y Costa Rica es claro: en estos tres países, los porcentajes que se destinan a la exportaciones todavía están creciendo, aunque a un ritma más bajo que a principio de los 2000.
Llama la atención que dos países centroamericanos, Guatemala y Honduras, están reduciendo el porcentaje tanto de la oferta total como de la producción doméstica que se dedica a la exportación.
knitr::include_graphics(here::here("Plots", "usda_razones_export_grupo1.png"))
knitr::include_graphics(here::here("Plots", "usda_razones_export_grupo2.png"))
¿Y cómo se utiliza el porcentaje de la oferta total y el de la producción local que se destina al consumo doméstico? Las figuras 25 y 26 permiten responder esa pregunta. En la primera columna de ambas figuras se muestra el porcentaje de la oferta total que se destina al consumo doméstico; en la segunda, el porcentaje del uso doméstico que se destina a usos industriales.
Empezando de nuevo por Indonesia y Malasia, es clara la importancia creciente del consumo doméstico en Indonesia, y su crecimiento, pero muy moderado y desde un nivel inicial más bajo en Malasia. La información más interesante es la que se presenta en la segunda columna: en Indonesia el porcentaje de uso doméstico destinado a la industrialización crece muy rápidamente a partir de 2009, y alanccs un nivel cercano al 70% en 2025. En Indonesia, no hay mayor tendencia al crecimiento de 2009 en adelante, pero el porcentaje es estable y elevado: de nuevo, cercano al 70%.
En los tres países centroamericanos incluidos en el gráfico se presenta el patrón inverso: Guatemala no industrializa el aceite destinado al consumo doméstico; Honduras industrializa porcentaje decreciente de 2018 en adelante, que llega a apenas un 30% en 2025, y en Costa Rica la tendencia no solo es decreciente de 2005 en adelante, sino que el porcentaje es apenas superior al 10% en 2025.
Indonesia, Malasia, Guatemala, Honduras y Costa Rica son productores de aceite de palma, pero no están jugando el mismo juego. Aún dejando de lado las diferencias en escala, los dos primeros países son cada vez más fabricantes de productos derivados del aceite de palma, y los tres últimos productores de materia prima.
knitr::include_graphics(here::here("Plots", "usda_consumo_industrial_grupo1.png"))
knitr::include_graphics(here::here("Plots", "usda_consumo_industrial_grupo2.png"))
EN CONSTRUCCIÓN
EN CONSTRUCCIÓN
Abdulla, I. et al. (2014). Impact of CPO Export Duties on Malaysian Palm Oil Industry. American Journal of Applied Sciences, 11 (8). https://thescipub.com/pdf/ajassp.2014.1301.1309.pdf
Bernama. (2025). Malaysia’s Oil Plam Replanting Lags Target. Govt Steps Us Efforts. Joharin. https://www.bernama.com/en/news.php?id=2396194
COMEXPALMA-SADER (2019). Sistema Producto Nacional Palma de Aceite. https://comexpalma.org/wp-content/uploads/Ficha-Tecnica-Informativa-Situacion-2019.pdf
FEMEXPALMA (2025). Anuario Estadístico 2025. Explora México Palmero en Cifras. https://femexpalma.com.mx/wp-content/uploads/2025/10/ANUARIO-ESTADISTICO-FEMEXPALMA-2025-.pdf
Gaveau, D. et al. (2021). Slowing deforestatin in Indonesia follows declining oil palm expansion and lower oil prices. Plos One. file:///C:/Users/jorge/AppData/Local/Temp/MicrosoftEdgeDownloads/20140237-bb0c-41ad-801a-3a10da713820/journal.pone.0266178.pdf
Guindon, Michael (2021). Deforestation is growing byt palm oil is still a major driver. Dialogue Earth. https://dialogue.earth/en/forests/palm-oil-and-deforestation-today/
Haisawit, B. (2026). PSR-Partnership Integration, the Government’s New Approach to Meet Replanting Targets”https://haisawit.co.id/news/detail/integrasi-psr-dan-kemitraan-cara-baru-pemerintah-kejar-target-peremajaan
Haman, Steffi (2024). The impact of Indonesia´s ban on palm oil exports reverberated across the globe. The Conversation. https://theconversation.com/the-impact-of-indonesias-ban-on-palm-oil-exports-reverberated-across-the-globe-182501 https://www.czapp.com/analyst-insights/aging-palm-oil-trees-in-asia-could-cause-supply-deficit/
Iacurci, Greg (2022). Sunflowers, war and drought. Why the price of margaringe and butter spiked 32%. CNBC. https://www.cnbc.com/2022/10/17/sunflowers-war-and-oil-why-margarine-butter-prices-have-risen.html
Isaac-Márquez, R. (2021). La expansión del cultivo de palma de aceite en Campeche. De los pequeños productores a la agroindustria transnacional. Región y Sociedad. Vol. 33. https://www.scielo.org.mx/scielo.php?script=sci_arttext&pid=S1870-39252021000100101
Kharina, A. et al. (2016). Biofuel Policy in Indonesia: overview and status report. ICCT White Paper. https://theicct.org/sites/default/files/publications/Indonesia%20Biofuels%20Policy_ICCT_08082016.pdf
Lestary, Y.S et al. (2025) Policy Strategy to Stimulate Indonesia’s Palm Oil Downstream Industries. The Journal of Indonesian Sustainable Development Planning. Vol. 6, N. 2. file:///C:/Users/jorge/AppData/Local/Temp/MicrosoftEdgeDownloads/38586b78-06c6-4339-8902-cffe7d6f7bf2/726-Research%20Paper-4155-1-10-20250830.pdf
Masika, Fred (2026). Analysis of Agronomic Traites Influence Frech Fruit Bunch Weight and Oil Expraction Rate in Oil Palm in Uganda. Mendeley Data. https://data.mendeley.com/datasets/kypsvxzz54/1
OECD-FAO (2026) Agricultural Outlook 2026-2035. https://www.oecd.org/content/dam/oecd/en/publications/reports/2026/06/oecd-fao-agricultural-outlook-2026-2035_5610f218/47874669-en.pdf
Persumsam, K. (2025). Accelerating the People’s Oil Palm Replanting Program (PSR) in Indonesia: Challenges and Opportunities. IPOSS. https://iposs.co.id/en/policy/akselerasi-program-peremajaan-sawit-rakyat-psr-di-indonesia-tantangan-dan-peluang
Poku, K. (2002). Small-scale Palm Oil processing in Africa. https://www.fao.org/4/y4355e/y4355e00.htm
Rifin, A. (2010). The Effecto of Export Tax on Indonesia’s Crude Palm Oil (CPO) Export Competiveness. Asian Economic Bulletin. https://www.researchgate.net/publication/235980339_The_Effect_of_Export_Tax_on_Indonesia's_Crude_Palm_Oil_CPO_Export_Competitiveness
Rahmanulloh, A. (2024). Biofuels Annual. Indonesia. USDA Foreing Agricultural Service, Global Agricultural Information Network. https://apps.fas.usda.gov/newgainapi/api/Report/DownloadReportByFileName?fileName=Biofuels+Annual_Jakarta_Indonesia_ID2024-0018
Ruswanto, A. et al.(2020). Palm oil yield potency on different level of ripening and storage time bases on fruits percentage and fresh fruit bunches. https://iopscience.iop.org/article/10.1088/1755-1315/443/1/012005/pdf
Torrebiarte, A. (2024). Aging Palm Oil Trees in Asia Could Cause Supply Deficit.
Trostle, Ronald (2011). Why Another Food Commodity Price Spike? USDA, ERS, Amber Waves, https://www.ers.usda.gov/amber-waves/2011/september/commodity-price-spike
Trostle, Ronald et al.(2011) Why Have Food Commodity Prices Ricen Again? USDA. WRS-1103. https://ers.usda.gov/sites/default/files/_laserfiche/outlooks/40481/7392_wrs1103.pdf?v=37497
Wirawan, S.S. et al (2024). Biodiesel implementation in Indonesia: Experiencies and future perspectivs. Eslevier. Renewable and Sustainable Energy Reviwus. N. 189. https://www.sciencedirect.com/science/article/pii/S1364032123007694
Wulandri, W, and Bagus, E. (2026). Malaysia’s palm oil paradox. East Asia Forum. https://eastasiaforum.org/2026/05/23/malaysias-palm-oil-paradox/
UN Comtrade (paquete comtradr).
Flujos bilaterales de comercio de aceite de palma crudo (HS 1511.10) y
refinado (HS 1511.90), 2010-2023 (2024 excluido por cobertura incompleta
de reportantes), y comercio agregado de aceites vegetales a nivel HS4
(palma, soya, colza/canola, girasol/algodón, coco/palmiste).
USDA FAS, PSD Online. Producción, oferta, consumo doméstico, uso industrial y exportaciones de aceite de palma por país, series desde 2000.
FAOSTAT. Área cosechada de fruta de palma aceitera (ítem 254), utilizada junto con USDA para calcular productividad agrícola y tasa de extracción.
ILOSTAT. Salario mensual promedio en el sector
agrícola, Costa Rica e Indonesia (indicador
EAR_EMTA_SEX_ECO_CUR_NB_A).
FRED (Reserva Federal de St. Louis), como plataforma de distribución de:
Statista. Precios históricos y proyectados del aceite de palma a nivel mundial, 2014-2027 (US$/tonelada).
OECD (SDMX). (consultado / en preparación — confirmar alcance exacto de lo ya incorporado al documento vs. lo que sigue pendiente).