| Title: | Client for the NHS Business Services Authority Open Data Portal |
|---|---|
| Description: | A low-level client for the National Health Service Business Services Authority (NHSBSA) Open Data Portal <https://opendata.nhsbsa.net>, a 'CKAN' data catalogue. Provides thin wrappers around the portal's API actions for listing datasets, retrieving metadata, querying the datastore and downloading resource files. Results are returned as plain data (tibbles and lists) for the caller to interpret. |
| Authors: | Alasdair Warwick [aut, cre, cph] (ORCID: <https://orcid.org/0000-0002-0800-2890>) |
| Maintainer: | Alasdair Warwick <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.1.0 |
| Built: | 2026-10-07 11:47:31 UTC |
| Source: | https://github.com/rmgpanw/nhsbsa |
Wraps the CKAN datastore_search action to read the rows of a datastore
resource. One argument is provided for each documented API parameter.
nhsbsa_datastore_search( resource_id, q = NULL, distinct = NULL, plain = NULL, language = NULL, limit = NULL, offset = NULL, fields = NULL, sort = NULL, filters = NULL, include_total = NULL, .return_raw = FALSE )nhsbsa_datastore_search( resource_id, q = NULL, distinct = NULL, plain = NULL, language = NULL, limit = NULL, offset = NULL, fields = NULL, sort = NULL, filters = NULL, include_total = NULL, .return_raw = FALSE )
resource_id |
Character scalar. The resource to query. The NHSBSA
datastore identifies a resource by its name (the |
q |
A full-text query (a character scalar, or a named list for a
per-field search). Accepted for API completeness but not applied by this
portal; use |
distinct |
Logical. Return only rows that are distinct across the
selected |
plain |
Logical. Controls how a |
language |
Character scalar. The text-search language (e.g. |
limit |
Integer. Maximum number of rows to return in this request. |
offset |
Integer. Number of rows to skip, for paging. |
fields |
Character vector. The fields to return, in order. |
sort |
Character scalar or vector. Sort clause(s), e.g. |
filters |
Named list. Field-value pairs to filter on. Accepted for API
completeness but not applied by this portal; use
|
include_total |
Logical. Include the total match count in the response?
Required for the incomplete-results warning; defaults to the API default
( |
.return_raw |
Logical. If |
Use this function to read rows — choosing and ordering columns with
fields, sorting with sort, and paging with limit/offset. To filter
by value or to aggregate, use nhsbsa_datastore_search_sql() instead (see
Details).
The CKAN datastore returns at most one page of rows per request (the server
enforces a maximum limit). When more rows exist than are returned, a warning
of class nhsbsa_incomplete_results is signalled describing how to page
through the rest by increasing offset.
CKAN's datastore_search defines filters (exact field matching) and q
(full-text search) parameters, which this function exposes for API
completeness. This portal's datastore does not apply them — a query using
filters or q returns no matching rows — so to filter by value, aggregate
or compute expressions, use nhsbsa_datastore_search_sql() with a SQL
WHERE/GROUP BY clause. See vignette("nhsbsa") for worked examples.
A tibble with one row per record. With .return_raw = TRUE, the
parsed response envelope as a list (including total and fields).
nhsbsa_datastore_search_sql() to filter or aggregate with SQL,
nhsbsa_download_resource() to download the whole resource file.
# Read selected columns, sorted (field names are case-sensitive) nhsbsa_datastore_search( resource_id = "EPD_202401", fields = c("PCO_CODE", "BNF_CHEMICAL_SUBSTANCE", "ITEMS"), sort = "ITEMS desc", limit = 5 ) # Distinct values of a column nhsbsa_datastore_search( resource_id = "EPD_202401", fields = "PCO_CODE", distinct = TRUE, limit = 5 ) # Page through rows with `limit` and `offset` nhsbsa_datastore_search(resource_id = "EPD_202401", fields = "ITEMS", limit = 5) nhsbsa_datastore_search( resource_id = "EPD_202401", fields = "ITEMS", limit = 5, offset = 5 ) # Use the raw envelope to read the total number of rows raw <- nhsbsa_datastore_search( resource_id = "EPD_202401", limit = 1, .return_raw = TRUE ) raw$result$total# Read selected columns, sorted (field names are case-sensitive) nhsbsa_datastore_search( resource_id = "EPD_202401", fields = c("PCO_CODE", "BNF_CHEMICAL_SUBSTANCE", "ITEMS"), sort = "ITEMS desc", limit = 5 ) # Distinct values of a column nhsbsa_datastore_search( resource_id = "EPD_202401", fields = "PCO_CODE", distinct = TRUE, limit = 5 ) # Page through rows with `limit` and `offset` nhsbsa_datastore_search(resource_id = "EPD_202401", fields = "ITEMS", limit = 5) nhsbsa_datastore_search( resource_id = "EPD_202401", fields = "ITEMS", limit = 5, offset = 5 ) # Use the raw envelope to read the total number of rows raw <- nhsbsa_datastore_search( resource_id = "EPD_202401", limit = 1, .return_raw = TRUE ) raw$result$total
Wraps the CKAN datastore_search_sql action, which runs a read-only SQL query
against the datastore. The sql string is sent to the API verbatim; paging is
the caller's responsibility (via LIMIT/OFFSET in the query).
nhsbsa_datastore_search_sql(resource_id, sql, .return_raw = FALSE)nhsbsa_datastore_search_sql(resource_id, sql, .return_raw = FALSE)
resource_id |
Character scalar. The resource the query targets. The
NHSBSA datastore requires this alongside |
sql |
Character scalar. A single read-only SQL |
.return_raw |
Logical. If |
A tibble with one row per record returned by the query. With
.return_raw = TRUE, the parsed response envelope as a list.
nhsbsa_datastore_search() for a parameterised search.
# Select specific columns nhsbsa_datastore_search_sql( resource_id = "EPD_202401", sql = "SELECT YEAR_MONTH, PCO_CODE, ITEMS FROM `EPD_202401` LIMIT 10" ) # Filter by value with a WHERE clause (the reliable way to filter) nhsbsa_datastore_search_sql( resource_id = "EPD_202401", sql = "SELECT PCO_CODE, BNF_CHEMICAL_SUBSTANCE, ITEMS FROM `EPD_202401` WHERE PCO_CODE = 'W2U3Z' LIMIT 10" ) # Aggregate server-side: total items prescribed per organisation nhsbsa_datastore_search_sql( resource_id = "EPD_202401", sql = "SELECT PCO_CODE, SUM(ITEMS) AS items FROM `EPD_202401` GROUP BY PCO_CODE ORDER BY items DESC LIMIT 10" )# Select specific columns nhsbsa_datastore_search_sql( resource_id = "EPD_202401", sql = "SELECT YEAR_MONTH, PCO_CODE, ITEMS FROM `EPD_202401` LIMIT 10" ) # Filter by value with a WHERE clause (the reliable way to filter) nhsbsa_datastore_search_sql( resource_id = "EPD_202401", sql = "SELECT PCO_CODE, BNF_CHEMICAL_SUBSTANCE, ITEMS FROM `EPD_202401` WHERE PCO_CODE = 'W2U3Z' LIMIT 10" ) # Aggregate server-side: total items prescribed per organisation nhsbsa_datastore_search_sql( resource_id = "EPD_202401", sql = "SELECT PCO_CODE, SUM(ITEMS) AS items FROM `EPD_202401` GROUP BY PCO_CODE ORDER BY items DESC LIMIT 10" )
Resolves a single resource within a dataset and streams its file to disk.
This is the file-download counterpart to the datastore row-query functions
(nhsbsa_datastore_search() and friends): it fetches the whole resource file
(e.g. a CSV) rather than running a query.
nhsbsa_download_resource( dataset_id, directory, resource_id = NULL, pattern = NULL, overwrite = FALSE, quiet = FALSE )nhsbsa_download_resource( dataset_id, directory, resource_id = NULL, pattern = NULL, overwrite = FALSE, quiet = FALSE )
dataset_id |
Character scalar. The dataset identifier, as returned by
|
directory |
Character scalar. The directory to download into. Required; there is no default, and the directory must already exist. Use tempdir() for a throwaway location. |
resource_id |
Character scalar. The identifier of the resource to
download. Takes precedence over |
pattern |
Character scalar. A regular expression matched (case-insensitively) against resource names to select a single resource. |
overwrite |
Logical. Overwrite the file if it already exists in
|
quiet |
Logical. Suppress informational messages? Defaults to |
Exactly one resource must be identified. Supply either resource_id or a
pattern that matches a single resource name; if neither is given and the
dataset has more than one resource, an error is raised.
The file is saved into directory under its own name (the file name from the
resource's download URL, e.g. bnf_code_current_202503_version_88.csv).
The path to the downloaded file, invisibly.
nhsbsa_list_resources() to discover resources.
resources <- nhsbsa_list_resources("bnf-code-information-current-year") # Identify a resource by a pattern matching a single resource name path <- nhsbsa_download_resource( "bnf-code-information-current-year", pattern = resources$name[[1]], directory = tempdir() ) path # ...or by its exact id. An existing file is not re-downloaded unless # `overwrite = TRUE`, so this call short-circuits and returns the path. nhsbsa_download_resource( "bnf-code-information-current-year", resource_id = resources$id[[1]], directory = tempdir() )resources <- nhsbsa_list_resources("bnf-code-information-current-year") # Identify a resource by a pattern matching a single resource name path <- nhsbsa_download_resource( "bnf-code-information-current-year", pattern = resources$name[[1]], directory = tempdir() ) path # ...or by its exact id. An existing file is not re-downloaded unless # `overwrite = TRUE`, so this call short-circuits and returns the path. nhsbsa_download_resource( "bnf-code-information-current-year", resource_id = resources$id[[1]], directory = tempdir() )
Wraps the CKAN group_list action to list the groups (thematic collections)
that datasets can belong to.
nhsbsa_group_list(all_fields = NULL, .return_raw = FALSE)nhsbsa_group_list(all_fields = NULL, .return_raw = FALSE)
all_fields |
Logical. If |
.return_raw |
Logical. If |
A character vector of group names. If all_fields = TRUE, a list of
group records. With .return_raw = TRUE, the parsed response envelope as a
list.
nhsbsa_organization_list(), nhsbsa_tag_list().
nhsbsa_group_list()nhsbsa_group_list()
A convenience wrapper around nhsbsa_package_show() that returns a dataset's
resources as a tibble, optionally filtered by a pattern matched against the
resource name. This is the most direct way to discover the resources (and
their download URLs) available for a dataset.
nhsbsa_list_resources(dataset_id, pattern = NULL)nhsbsa_list_resources(dataset_id, pattern = NULL)
dataset_id |
Character scalar. The dataset identifier, as returned by
|
pattern |
Character scalar. An optional regular expression; only
resources whose |
If you have already fetched the dataset metadata with nhsbsa_package_show(),
calling tibble::as_tibble() on it gives the same table without a second
request (but without the pattern filter).
A tibble with one row per resource and columns name, id,
format, created, last_modified, url and size.
nhsbsa_download_resource() to download a resource file;
nhsbsa_package_show() (with tibble::as_tibble()) for the same table from
already-fetched metadata.
# All resources for a dataset nhsbsa_list_resources("english-prescribing-data-epd") # Only resources whose name matches a pattern nhsbsa_list_resources("english-prescribing-data-epd", pattern = "202401")# All resources for a dataset nhsbsa_list_resources("english-prescribing-data-epd") # Only resources whose name matches a pattern nhsbsa_list_resources("english-prescribing-data-epd", pattern = "202401")
Wraps the CKAN organization_list action to list the organisations that
publish datasets on the portal.
nhsbsa_organization_list(all_fields = NULL, .return_raw = FALSE)nhsbsa_organization_list(all_fields = NULL, .return_raw = FALSE)
all_fields |
Logical. If |
.return_raw |
Logical. If |
A character vector of organisation names. If all_fields = TRUE, a
list of organisation records. With .return_raw = TRUE, the parsed response
envelope as a list.
nhsbsa_group_list(), nhsbsa_tag_list().
# Organisation names nhsbsa_organization_list() # Richer records (title, description, dataset count, ...) for each organisation orgs <- nhsbsa_organization_list(all_fields = TRUE) orgs[[1]]$title# Organisation names nhsbsa_organization_list() # Richer records (title, description, dataset count, ...) for each organisation orgs <- nhsbsa_organization_list(all_fields = TRUE) orgs[[1]]$title
Wraps the CKAN package_list action to return the identifiers of every
dataset published on the NHSBSA Open Data Portal.
nhsbsa_package_list(.return_raw = FALSE)nhsbsa_package_list(.return_raw = FALSE)
.return_raw |
Logical. If |
A character vector of dataset identifiers. With .return_raw = TRUE,
the parsed response envelope as a list.
nhsbsa_package_show() for a dataset's metadata,
nhsbsa_package_search() to search datasets.
datasets <- nhsbsa_package_list() length(datasets) head(datasets)datasets <- nhsbsa_package_list() length(datasets) head(datasets)
Wraps the CKAN package_search action, a Solr-backed search over datasets.
nhsbsa_package_search( q = NULL, fq = NULL, sort = NULL, rows = NULL, start = NULL, .return_raw = FALSE )nhsbsa_package_search( q = NULL, fq = NULL, sort = NULL, rows = NULL, start = NULL, .return_raw = FALSE )
q |
Character scalar. The Solr query string (e.g. |
fq |
Character scalar. A Solr filter query. |
sort |
Character scalar. Sort order, e.g. |
rows |
Integer. Maximum number of datasets to return. |
start |
Integer. Offset into the result set, for paging. |
.return_raw |
Logical. If |
A list with the search count and matching datasets in results,
with class nhsbsa_package_search and a
print() method; tibble::as_tibble() turns
the results into one row per dataset. With .return_raw = TRUE, the parsed
response envelope as a plain list.
# Free-text search hits <- nhsbsa_package_search(q = "prescribing", rows = 5) hits tibble::as_tibble(hits) # Filter by tag (as clicking a tag on the website does) and sort the results nhsbsa_package_search( fq = 'tags:"Prescribing"', sort = "metadata_modified desc", rows = 5 ) # Page through results with `rows` and `start` nhsbsa_package_search(q = "dental", rows = 10, start = 10)# Free-text search hits <- nhsbsa_package_search(q = "prescribing", rows = 5) hits tibble::as_tibble(hits) # Filter by tag (as clicking a tag on the website does) and sort the results nhsbsa_package_search( fq = 'tags:"Prescribing"', sort = "metadata_modified desc", rows = 5 ) # Page through results with `rows` and `start` nhsbsa_package_search(q = "dental", rows = 10, start = 10)
Wraps the CKAN package_show action to return the full metadata for a single
dataset, including its list of resources (downloadable files and datastore
tables).
nhsbsa_package_show(id, .return_raw = FALSE)nhsbsa_package_show(id, .return_raw = FALSE)
id |
Character scalar. The dataset identifier or name, as returned by
|
.return_raw |
Logical. If |
A list of dataset metadata, with class nhsbsa_package and a
print() method; tibble::as_tibble() turns it into
a table of its resources. With .return_raw = TRUE, the parsed response
envelope as a plain list.
nhsbsa_list_resources() for a tidy table of a dataset's resources.
metadata <- nhsbsa_package_show("english-prescribing-data-epd") metadata metadata$title # The dataset's resources as a tibble tibble::as_tibble(metadata)metadata <- nhsbsa_package_show("english-prescribing-data-epd") metadata metadata$title # The dataset's resources as a tibble tibble::as_tibble(metadata)
Wraps the CKAN resource_show action to return the metadata for a single
resource (a file or datastore table).
nhsbsa_resource_show(id, .return_raw = FALSE)nhsbsa_resource_show(id, .return_raw = FALSE)
id |
Character scalar. The resource identifier. |
.return_raw |
Logical. If |
A list of resource metadata, with class nhsbsa_resource and a
print() method. With .return_raw = TRUE, the
parsed response envelope as a plain list.
resources <- nhsbsa_list_resources("english-prescribing-data-epd") meta <- nhsbsa_resource_show(resources$id[[1]]) meta$name meta$datastore_activeresources <- nhsbsa_list_resources("english-prescribing-data-epd") meta <- nhsbsa_resource_show(resources$id[[1]]) meta$name meta$datastore_active
Wraps the CKAN tag_list action to list the tags applied to datasets. These
are the same tags shown on the portal website; you can filter datasets by a
tag with nhsbsa_package_search() (see vignette("nhsbsa")).
nhsbsa_tag_list(query = NULL, vocabulary_id = NULL, .return_raw = FALSE)nhsbsa_tag_list(query = NULL, vocabulary_id = NULL, .return_raw = FALSE)
query |
Character scalar. Restrict the results to tags containing this string. |
vocabulary_id |
Character scalar. Restrict the results to tags in a particular CKAN tag vocabulary. |
.return_raw |
Logical. If |
A character vector of tags. With .return_raw = TRUE, the parsed
response envelope as a list.
nhsbsa_package_search() to find datasets by tag.
# All tags tags <- nhsbsa_tag_list() length(tags) # Only tags containing a given string nhsbsa_tag_list(query = "prescribing")# All tags tags <- nhsbsa_tag_list() length(tags) # Only tags containing a given string nhsbsa_tag_list(query = "prescribing")
Some nhsbsa functions return classed lists with a tailored
print() method and a tibble::as_tibble() method for turning
them into a table:
## S3 method for class 'nhsbsa_package' print(x, ...) ## S3 method for class 'nhsbsa_resource' print(x, ...) ## S3 method for class 'nhsbsa_package_search' print(x, ...) ## S3 method for class 'nhsbsa_package' as_tibble(x, ...) ## S3 method for class 'nhsbsa_package_search' as_tibble(x, ...)## S3 method for class 'nhsbsa_package' print(x, ...) ## S3 method for class 'nhsbsa_resource' print(x, ...) ## S3 method for class 'nhsbsa_package_search' print(x, ...) ## S3 method for class 'nhsbsa_package' as_tibble(x, ...) ## S3 method for class 'nhsbsa_package_search' as_tibble(x, ...)
x |
An object returned by the relevant |
... |
Ignored, for S3 method consistency. |
nhsbsa_package_show() returns an nhsbsa_package; as_tibble() returns
its resources (one row per file). This is the same table as
nhsbsa_list_resources(), but built from metadata you have already
fetched, so it avoids a second request (and does not filter by pattern).
nhsbsa_resource_show() returns an nhsbsa_resource.
nhsbsa_package_search() returns an nhsbsa_package_search; as_tibble()
returns one row per matching dataset.
These objects are still plain lists, so $, [[ and utils::str() work as
usual. Pass .return_raw = TRUE to the originating function, or use
unclass(), to get the underlying list without a class.
The print() methods return x invisibly. The as_tibble() methods
return a tibble.
pkg <- nhsbsa_package_show("english-prescribing-data-epd") pkg tibble::as_tibble(pkg) hits <- nhsbsa_package_search(q = "prescribing", rows = 5) hits tibble::as_tibble(hits)pkg <- nhsbsa_package_show("english-prescribing-data-epd") pkg tibble::as_tibble(pkg) hits <- nhsbsa_package_search(q = "prescribing", rows = 5) hits tibble::as_tibble(hits)