This guide shows the 0.4 workflow for keeping official statistics connected to their source, selected dimensions, observation symbols, and collection context. All service requests below are examples that you run deliberately; building this vignette does not access the network.
| Service | Use | Identifier |
|---|---|---|
PXWeb, data.1212.mn |
Published statistical tables | DT_NSO_... |
Public data portal, data.nso.mn |
Experimental aggregate series and datamart discovery | portal:DT_NSO_... in discovery results |
Metadata catalog, metadata.nso.mn |
Definitions, forms, classifications and relationships | A typed numeric ID |
A shared title or table-like identifier does not establish that two
services publish the same measure. Geographic codes also belong to their
source. For example, the sampled portal GDP series uses national code
CO9999; the reviewed PXWeb resident-population template
uses national code 0.
nso_indicators() searches a small bundled registry of
reviewed PXWeb concepts. Inspect the definition, unit status, validation
date, and caveats before fetching. The query template fixes the
substantive selections; period labels are supplied separately. It does
not guess that a similarly named portal series is equivalent.
old_options <- nso_options(mongolstats.lang = "en")
nso_indicators("GDP")
concept <- nso_indicator("gdp_current")
concept[c("name", "definition", "unit", "unit_status", "verified_at", "caveats")]
query <- nso_indicator_query("gdp_current", periods = c("2023", "2024"))
gdp <- nso_fetch(query, labels = "both")
# Both sexes and national total are the reviewed defaults.
population_query <- nso_indicator_query("resident_population", periods = "2024")
options(old_options)Use period labels such as "2024", rather than PXWeb
positional time codes: code "0" can refer to a different
year after the next update. A source label ending in * is
preserved. Read the source’s explanation of that mark before assigning a
revision status or converting the published number’s scale.
Fetch results remain ordinary tibbles. Their provenance attribute
records source identity, request URL, selections, retrieval time,
available source metadata, and a metadata fingerprint.
nso_table_info() provides a compact view;
nso_provenance() exposes the full manifest, including
failures in a batch.
nso_table_info(gdp)
manifest <- nso_provenance(gdp)
manifest$records[[1]]$selections
manifest$failures
nso_citation(gdp)
# Metadata-only lookup: no observations are requested.
nso_table_info("DT_NSO_0500_001V1")An absent source statement, update date, or unit remains missing. A metadata-only lookup can contain less information than a data response. Citations acknowledge the source; the package’s software license does not determine the data’s reuse conditions. Consult NSO’s terms and the relevant source record.
Numeric NA alone cannot distinguish a missing
observation from source symbols such as ...
nso_value_status() returns observation keys, the original
value_raw, and value_status:
"observed" for finite numbers, "missing" for
empty or missing fields, and "symbol" for other text. A
symbol’s meaning is not inferred. Retain these records before filtering
or transforming data.
status <- nso_value_status(gdp)
status[status$value_status != "observed", , drop = FALSE]
nso_check_data(
gdp,
keys = "Year",
period = "Year",
expected_periods = c("2023", "2024")
)This example uses English PXWeb dimension names; inspect
names(gdp) when using another fetch language. Optional
unit and geography_level arguments name
columns already present in your data. The checker reports concerns
without changing values. No reported concerns does not establish that
populations, units, or geographic levels are comparable.
Transformations and CSV exports can discard attributes. Save the provenance sidecar and original status table separately. The JSON manifest contains source and request context, not the statistical observations or their raw symbols.
# Choose an enduring project directory; use a new run directory for each export.
export_dir <- file.path("outputs", "nso", format(Sys.Date(), "%Y-%m-%d"))
dir.create(export_dir, recursive = TRUE, showWarnings = FALSE)
# Do not overwrite a previous run accidentally.
targets <- file.path(export_dir, c("gdp.csv", "gdp.rds", "value-status.rds", "provenance.json", "analysis-context.rds"))
stopifnot(!any(file.exists(targets)))
saveRDS(gdp, file.path(export_dir, "gdp.rds"))
analysis_context <- list(
saved_at = format(Sys.time(), tz = "UTC", usetz = TRUE),
data_sha256 = digest::digest(gdp, algo = "sha256"),
session = utils::sessionInfo(),
code_revision = Sys.getenv("ANALYSIS_CODE_REVISION", unset = NA_character_),
manual_recodes = character()
)
saveRDS(analysis_context, file.path(export_dir, "analysis-context.rds"))
utils::write.csv(gdp, file.path(export_dir, "gdp.csv"), row.names = FALSE)
saveRDS(nso_value_status(gdp), file.path(export_dir, "value-status.rds"))
nso_write_manifest(gdp, file.path(export_dir, "provenance.json"))
saved_manifest <- nso_read_manifest(file.path(export_dir, "provenance.json"))
nso_table_info(saved_manifest)
nso_citation(saved_manifest)
readRDS(file.path(export_dir, "value-status.rds"))nso_write_manifest() refuses to overwrite a file unless
overwrite = TRUE is explicit. The RDS file preserves the
original R types and attributes. Record the analysis code revision and
any manual recodes explicitly. A metadata fingerprint alone cannot
reproduce observations after source revisions.
The other tutorials load the inspectable teaching helpers shipped at
system.file("examples", "analysis-helpers.R", package = "mongolstats").
They check expected unit/month grids, unique keys, common periods,
complete age strata and positive denominators before calculating
estimates. Missing source observations remain unknown.
nso_check_data() reports concerns; an empty report does not
prove that an analytical specification has been met.
Keep the original fetched object, its nso_value_status()
result and provenance before transformations. Save the validated
analytical data and any recoding rules alongside the outputs above.
Historical teaching snapshots without retrieval dates or raw symbols
cannot acquire that missing information retrospectively.
The metadata catalog connects databases, tables, questionnaire
fields, forms, and classifications. Its indicator type can
be a question in a collection form rather than a published series.
Numeric catalog IDs do not identify PXWeb tables. Search coverage and
pagination attributes describe what was returned, not a verified
complete inventory.
hits <- nso_metadata_search("хүн ам", type = "all")
attr(hits, "coverage")
attr(hits, "pagination")
organizations <- nso_metadata_search(type = "organization")
databases <- nso_metadata_search(organization = 1, page = 1)
attr(databases, "pagination")
database <- nso_metadata("database", 526, include_raw = TRUE)
database$methodology
database$access
nso_related(database)
field <- nso_metadata("indicator", 12925, include_raw = TRUE)
field$quality_flags
field$context$unit
field$context$value_type
field$date_fields
nso_related(field)The numeric IDs here are concrete examples from inspected catalog
records; choose records relevant to your analysis.
nso_related() reads embedded relationships without further
requests. Fetch a full supported record with
nso_metadata(type, id); embedded details may be partial.
Quality flags preserve suspect source fields for review rather than
silently correcting them.
forms <- nso_forms(database_id = 526, include_raw = TRUE)
forms$records
form <- nso_metadata("form", 1024, include_raw = TRUE)
form$dates
form$years
form$date_fields
form$context
form$quality_flags
classification <- nso_classification(3446, include_raw = TRUE)
attr(classification, "completeness")
attr(classification, "quality_flags")
attr(classification, "metadata")$version
nso_metadata_dictionary("frequency")
nso_metadata_dictionary("collection-method")
nso_metadata_dictionary("licence")Classification codes remain character strings. An empty codebook does not prove that the classification has no categories, and a nonempty one does not prove completeness. A licence or security category describes the catalog record; it does not grant access to underlying records. Missing official translations remain missing.
Local PXWeb discovery uses the bundled or session index. Its entry count can include the same table under several paths. Live keyword search returns a source-defined search window; it does not rebuild the complete index.
nso_catalogue_status()
nso_search("population", fixed = TRUE)
live_hits <- nso_search("population", live = TRUE)
attr(live_hits, "catalogue")
config <- nso_api_config(refresh = TRUE)
config[c("maxCells", "maxValues", "origin", "status")]The package splits data queries by the cell limit and applies
conservative request pacing. maxValues describes the
metadata-value limit advertised by PXWeb; it is not a data-query
selection limit. Configuration can fall back to defaults or a stale
cache, so inspect status. Processes on one computer share
request pacing; other computers using the same public address need
coordination.
The portal registry is experimental. Inspect its
queryable, quality_flags, and grouping
dimensions; rows with invalid or missing IDs remain discoverable but
cannot be queried. Portal request parameters are separate from the
curated PXWeb templates, and the source’s summary narratives are not
observations.
portal_catalog <- nso_indicators(source = "portal", refresh = TRUE)
portal_catalog[c("id", "name", "unit", "queryable", "quality_flags")]
nso_indicator("portal:DT_NSO_0000_4_4")
portal_gdp <- nso_portal_data(
"DT_NSO_0000_4_4",
area = "1",
dimension = "code",
graph_type = "line",
periods = "2024",
labels = "both"
)
portal_gdp[c("source_id", "period", "code", "code_mn", "code_en", "value", "unit")]
nso_check_data(portal_gdp, keys = c("period", "code", "code1"), unit = "unit")
nso_table_info(portal_gdp)area, dimension, and
graph_type are explicit source request parameters; the GDP
example does not establish their meaning for every indicator. Period
filtering is performed after retrieval and matches the source label
exactly. Codes are retained for every label choice. Missing English
labels stay NA; unknown geography codes are preserved.
Unpadded periods such as 2025-1 retain their label but
remain undated when month-versus-quarter meaning is ambiguous.
datamarts <- nso_portal_datamarts()
datamarts[c("id", "name", "years", "source", "query_supported")]Datamart support provides catalog discovery and presentation
configuration only. The reported year range is source text, not verified
coverage. query_supported is FALSE: a stable
developer contract for aggregate queries has not been verified, and this
interface does not retrieve underlying individual records.