This vignette covers finding a survey, reading its documentation and understanding what you are and are not allowed to do with it.
Every code chunk that contacts the archive is shown but not run, so that building this vignette never depends on a live service.
What is supported
knbs_sources() reports what the package knows about each
source and how far it has been verified. Nothing here makes a
request:
knbs_sources(operation = "search_surveys")
#> # A tibble: 2 × 8
#> source_id source_name source_type operations stability authentication
#> <chr> <chr> <chr> <list> <chr> <chr>
#> 1 kenada Kenya National Da… survey_cat… <chr [4]> experime… none
#> 2 fake_source Offline test sour… fake <chr [6]> discovery none
#> # ℹ 2 more variables: last_verified <date>, base_url <chr>The survey catalogue is the Kenya National Data Archive, which
exposes a JSON API. It is registered as experimental: the
endpoints are verified and covered by tests, but the archive does not
document the API, so it could change without notice. If it does, the
package raises a knbs_error_schema_changed rather than
returning something plausible.
Finding a survey
studies <- knbs_search_surveys("household budget")
studiesYou can filter by reference year, by producer and by access type:
knbs_search_surveys(year = c(2015, 2020))
knbs_search_surveys(access = "public_use", limit = 10)Three columns come back as NA from a search:
acronym, geographic_coverage and
unit_of_analysis. They live in the study record rather than
the catalogue index, and filling them in would mean one extra request
per row. knbs_survey_metadata() retrieves them.
Reading a study’s documentation
meta <- knbs_survey_metadata("KEN-KNBS-KIHBS-2015-2016-v01")
metaThe printed record shows the title, reference period, producer,
geographic coverage, unit of analysis and access type. The full
descriptive sections are in meta$sections;
include narrows them:
knbs_survey_metadata("KEN-KNBS-KIHBS-2015-2016-v01", include = c("scope", "access"))These records are DDI documents, in which sampling, data collection
and processing all live in a single method section, so
asking for any one of those returns that section.
You do not have to know the exact identifier. Give it something recognisable and it will search the catalogue; if more than one study matches you get an error listing the candidates rather than a silently chosen “best” match.
Searching variables
Variable metadata are available without downloading any microdata:
knbs_variables("KEN-KNBS-KIHBS-2015-2016-v01", search = "expenditure")
knbs_variables("KEN-KNBS-KIHBS-2015-2016-v01", file = "HH_Information")search matches variable names and labels, and matches
nothing else. If a concept you expect is missing, it is worth listing
all the variables and looking at the labels the study actually uses
before concluding the search is broken.
Question text, universe, concept and value labels each cost one request per variable, so they are empty unless you ask:
knbs_variables(
"KEN-KNBS-KIHBS-2015-2016-v01",
search = "county",
details = TRUE
)That is capped at 100 variables. Narrow the selection first rather than raising the cap.
Some studies are catalogued with no variable documentation at all — including, at the time of writing, the most recent one. That returns zero rows, which is an answer rather than a failure.
Files, and what you may do with them
knbs_survey_files("KEN-KNBS-KIHBS-2015-2016-v01")Two columns matter most:
-
access_typedescribes the archive’s terms.public_usemeans public-use files exist. It does not mean they can be downloaded without an account. -
downloadabledescribes what this package will do. At present it isFALSEfor every file from every supported source.
This lists data files only. Questionnaires, reports
and technical documents are not covered: the archive publishes no
machine-readable listing of them, so retrieving them would mean parsing
a web page, which this package does not do. Use the
catalogue_url column from
knbs_search_surveys() to open the study on the archive’s
own site, where the documentation is linked.
Downloading microdata
You cannot do this through knbsdata, and that is
deliberate:
knbs_download_microdata("KEN-KNBS-KIHBS-2015-2016-v01")
#> Error: Microdata from "kenada" cannot be downloaded programmatically.
#> x Every download requires an account with the archive.
#> i Register and request access at <https://statistics.knbs.or.ke/nada/index.php/home>.
#> i knbsdata does not automate sign-in, licence acceptance or approval workflows.The archive puts every download behind a login. The package does not
automate sign-in, licence acceptance or approval workflows, so the
function exists purely to fail clearly and point you at the official
process. Complete that process, download the files yourself, and read
them with knbs_read_microdata(), which reads Stata, SPSS
and Excel files and the data inside a .zip, keeping value
labels.
This matters for a subtler reason too. The gate is signalled by an
HTTP Refresh header rather than a redirect status, so a
client that only checks the status code sees 200 OK and an
empty body — and could report “no data” where the honest answer is “you
need an account”. The package treats that as an authentication
error.
Open microdata: the FinAccess surveys
Some surveys’ microdata are published for anyone to download. The FinAccess household survey, Kenya’s survey of financial inclusion by the Central Bank of Kenya, KNBS and FSD Kenya, is one: six rounds from 2006 to 2024, plus two waves of the FinAccess MSE Tracker Survey of micro and small enterprises. The archive catalogues these studies (and a 2019 round the portal has no files for), but lists no data files or variables for any of them, and gates its downloads behind an account as it does everywhere. The FinAccess portal publishes the files themselves, so they have their own functions.
# The catalogue ships with the package: listing it contacts nothing
knbs_finaccess_files(content = "data")
# Download and read the 2024 household survey (Stata, 160 MB)
fa <- knbs_read_microdata(knbs_download_finaccess("hh2024-stata", "data"))
knbs_cite(fa)The portal is a web page linking files on Google Drive, so the package keeps its own catalogue of them — names, sizes and SHA-256 checksums, every file opened and checked by hand — and holds each download to it: a file that has changed since is refused before anything large moves, and a transfer that arrives damaged is not kept. Running the same line again finds the file already downloaded, confirms its checksum and reads it without a request.
Each file gets a sidecar recording where it came from and the producers’ terms. The portal states no licence; FSD Kenya’s terms for the 2013 survey restrict the data to research and forbid redistribution without written agreement, so assume nothing wider.
knbs_read_microdata() keeps Stata and SPSS value labels
as haven::labelled() columns, and each variable’s question
text in its "label" attribute. The 2024 file has 20,871
respondents and 3,816 variables, so col_select is worth
knowing:
fa <- knbs_read_microdata("data/2024_Finaccess_Publicdata.dta",
col_select = c("county", "A13", "A18"))
attr(fa$A18, "label") # "A18. AGE OF RESPONDENT"
table(haven::as_factor(fa$A13)) # value labels as factor levels
# Respondents' counties as census codes, ready to join census tables
fa$geo_code <- knbs_county_code(haven::as_factor(fa$county))Handling errors
Every failure carries a specific condition class, so you can react to the particular problem rather than matching on message text:
result <- tryCatch(
knbs_survey_metadata("Kenya"),
knbs_error_ambiguous_resource = function(cnd) {
message("Several studies match; using the first.")
knbs_survey_metadata(cnd$matches[[1]])
},
knbs_error_resource_not_found = function(cnd) NULL,
knbs_error_source_unavailable = function(cnd) NULL
)The classes you are most likely to want are
knbs_error_ambiguous_resource (which carries the candidates
in $matches), knbs_error_resource_not_found,
knbs_error_authentication_required (which carries
$access_url), knbs_error_source_unavailable
and knbs_error_schema_changed. All of them inherit from
knbs_error, so you can catch that instead to handle any
package failure at once.
One practical note: catch error, not
condition. httr2 signals a benign
httr2_perform condition on every request, so a
tryCatch(..., condition = ) handler will catch that first
and never see your error.
Citing what you used
knbs_cite(meta)Where the archive states a required citation, that text is used and
the package adds the retrieval date and its own version.
knbs_metadata() shows the full provenance record behind any
object.
Caching
Catalogue responses are cached for 24 hours by default:
knbs_cache_info()
knbs_search_surveys("household budget", refresh = TRUE) # bypass the cache
knbs_cache_clear()Cache entries are checksummed and keyed partly on the package’s parser version, so upgrading the package invalidates anything a new parser would read differently.