The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.
This vignette reproduces a complete state-level trade extract similar to the one offered by the ComexStat web app, with the following combination requested in the “By Municipality” panel:
City-level data refers to the declarant’s tax residence, not the place where the goods were produced or purchased. The city endpoint only goes down to HS4 (heading) — full NCM and HS6 (subHeading) are not available for this view.
Brazilian state codes follow the IBGE convention (26 =
Pernambuco). If you don’t remember the code, query the table:
state_code <- 26 # Pernambuco
period_from <- "2026-01"
period_to <- "2026-12" # API returns up to the latest update
# These names are user-friendly aliases. The package translates each
# to the underlying API name (see `getting-started` vignette for the
# full mapping table):
# hs4 -> heading
# hs2 -> chapter
detalhes <- c("state", "city", "hs4", "section", "hs2", "country")
filtros <- list(state = state_code)The API serves one flow per request, so we make two calls and combine the results:
exp_pe <- comex_query_city(
flow = "export",
start_period = period_from,
end_period = period_to,
details = detalhes,
filters = filtros,
month_detail = TRUE,
metric_fob = TRUE,
metric_kg = TRUE
)
exp_pe$flow <- "export"
imp_pe <- comex_query_city(
flow = "import",
start_period = period_from,
end_period = period_to,
details = detalhes,
filters = filtros,
month_detail = TRUE,
metric_fob = TRUE,
metric_kg = TRUE
)
imp_pe$flow <- "import"
pe <- rbind(exp_pe, imp_pe)The resulting data frame has one row per month × city × HS4 × country × flow combination:
API responses come back as character. Convert metrics to numeric and
build a proper Date column for time-series analysis:
monthly <- aggregate(metricFOB ~ date + flow, data = pe, FUN = sum)
monthly_wide <- reshape(monthly, idvar = "date", timevar = "flow",
direction = "wide")
names(monthly_wide) <- c("date", "exports", "imports")
monthly_wide$balance <- monthly_wide$exports - monthly_wide$imports
monthly_wide
# Base-R plot
with(monthly_wide, {
plot(date, exports / 1e6, type = "b", pch = 19, col = "steelblue",
ylim = range(c(exports, imports), na.rm = TRUE) / 1e6,
xlab = "Month", ylab = "US$ millions",
main = "Pernambuco: exports vs imports, 2026")
lines(date, imports / 1e6, type = "b", pch = 17, col = "tomato")
legend("topleft", legend = c("Exports", "Imports"),
col = c("steelblue", "tomato"), pch = c(19, 17), bty = "n")
})The package returns the city as noMunMinsgUf
(e.g. “Goiana - PE”):
exports_by_city <- aggregate(metricFOB ~ noMunMinsgUf,
data = subset(pe, flow == "export"),
FUN = sum)
head(exports_by_city[order(-exports_by_city$metricFOB), ], 10)
imports_by_city <- aggregate(metricFOB ~ noMunMinsgUf,
data = subset(pe, flow == "import"),
FUN = sum)
head(imports_by_city[order(-imports_by_city$metricFOB), ], 10)exp_hs4 <- aggregate(
metricFOB ~ headingCode + heading,
data = subset(pe, flow == "export"),
FUN = sum
)
head(exp_hs4[order(-exp_hs4$metricFOB), ], 10)
imp_hs4 <- aggregate(
metricFOB ~ headingCode + heading,
data = subset(pe, flow == "import"),
FUN = sum
)
head(imp_hs4[order(-imp_hs4$metricFOB), ], 10)Because pe already contains the full set of details, any
deeper cut is just a matter of aggregate():
# Top product for each top destination
exp_country_hs4 <- aggregate(
metricFOB ~ country + heading,
data = subset(pe, flow == "export"),
FUN = sum
)
exp_country_hs4 <- exp_country_hs4[
order(exp_country_hs4$country, -exp_country_hs4$metricFOB),
]
do.call(rbind, lapply(
split(exp_country_hs4, exp_country_hs4$country),
function(x) head(x, 1)
))
# Top destination for each Pernambuco municipality
exp_city_country <- aggregate(
metricFOB ~ noMunMinsgUf + country,
data = subset(pe, flow == "export"),
FUN = sum
)
exp_city_country <- exp_city_country[
order(exp_city_country$noMunMinsgUf, -exp_city_country$metricFOB),
]
do.call(rbind, lapply(
split(exp_city_country, exp_city_country$noMunMinsgUf),
function(x) head(x, 1)
))To compare with previous years, just widen the date range and drop
month_detail:
yearly_exp <- comex_query_city(
flow = "export",
start_period = "2019-01",
end_period = "2026-12",
details = "state",
filters = list(state = state_code),
month_detail = FALSE
)
yearly_imp <- comex_query_city(
flow = "import",
start_period = "2019-01",
end_period = "2026-12",
details = "state",
filters = list(state = state_code),
month_detail = FALSE
)
yearly_exp$flow <- "export"; yearly_imp$flow <- "import"
yearly <- rbind(yearly_exp, yearly_imp)
yearly$metricFOB <- as.numeric(yearly$metricFOB)
yearly # one row per year × flowThe same code works for any Brazilian state — change only
state_code and the date range. To get the code
interactively:
For analyses that require finer product detail (NCM, HS6) or other
classifications (CGCE, SITC, ISIC), use [comex_query()] /
[comex_export()] / [comex_import()] on the
general endpoint — but those do not accept a city
filter.
These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.