| Title: | Client for the NHS Business Services Authority Open Data Portal |
| Version: | 0.1.0 |
| 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. |
| License: | MIT + file LICENSE |
| URL: | https://github.com/rmgpanw/nhsbsa, https://rmgpanw.github.io/nhsbsa/ |
| BugReports: | https://github.com/rmgpanw/nhsbsa/issues |
| Encoding: | UTF-8 |
| Language: | en-GB |
| RoxygenNote: | 7.3.3 |
| Depends: | R (≥ 4.1.0) |
| Imports: | cli, dplyr, httr2, jsonlite, purrr, rlang, stringr, tibble |
| Suggests: | curl, httptest2, knitr, rmarkdown, spelling, testthat (≥ 3.0.0), withr |
| Config/testthat/edition: | 3 |
| VignetteBuilder: | knitr |
| NeedsCompilation: | no |
| Packaged: | 2026-07-31 07:37:37 UTC; Alasdair |
| Author: | Alasdair Warwick |
| Maintainer: | Alasdair Warwick <alasdair.warwick.19@ucl.ac.uk> |
| Repository: | CRAN |
| Date/Publication: | 2026-08-07 22:00:02 UTC |
nhsbsa: 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.
Further reading
The portal is a standard CKAN catalogue. For background on the API this package wraps, see:
The portal's API page: https://opendata.nhsbsa.net/pages/api
The CKAN Action API reference: https://docs.ckan.org/en/latest/api/
vignette("nhsbsa") explains how the package maps onto what you see on the
portal website, and shows the different ways to query data.
Author(s)
Maintainer: Alasdair Warwick alasdair.warwick.19@ucl.ac.uk (ORCID) [copyright holder]
See Also
Useful links:
Report bugs at https://github.com/rmgpanw/nhsbsa/issues
nhsbsa condition constructors (internal helpers)
Description
Internal helpers for constructing structured nhsbsa error, warning and informational conditions.
Usage
nhsbsa_abort(
message,
class = NULL,
...,
call = rlang::caller_env(),
.envir = rlang::caller_env()
)
nhsbsa_warn(message, class = NULL, ..., .envir = rlang::caller_env())
nhsbsa_inform(message, class = NULL, ..., .envir = rlang::caller_env())
Arguments
message |
It is formatted via a call to |
class |
Optional character vector of additional classes to prepend before the nhsbsa base class. |
... |
Passed through to the underlying |
call |
Call environment (only used by |
.envir |
Environment to evaluate the glue expressions in. |
Details
These wrap the corresponding cli signalling functions
(cli::cli_abort(), cli::cli_warn(), cli::cli_inform()) and always
append an nhsbsa-specific base class (nhsbsa_error, nhsbsa_warning,
nhsbsa_message).
Additional custom classes may be optionally prepended via the class
argument, allowing callers to test for and handle specific conditions
programmatically.
The original named cli message vector is stored in cli_message so a
condition can be re-thrown to reproduce an identical message.
Methods for nhsbsa objects
Description
Some nhsbsa functions return classed lists with a tailored
print() method and a tibble::as_tibble() method for turning
them into a table:
Usage
## 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, ...)
Arguments
x |
An object returned by the relevant |
... |
Ignored, for S3 method consistency. |
Details
-
nhsbsa_package_show()returns annhsbsa_package;as_tibble()returns its resources (one row per file). This is the same table asnhsbsa_list_resources(), but built from metadata you have already fetched, so it avoids a second request (and does not filter bypattern). -
nhsbsa_resource_show()returns annhsbsa_resource. -
nhsbsa_package_search()returns annhsbsa_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.
Value
The print() methods return x invisibly. The as_tibble() methods
return a tibble.
Examples
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)
Search a resource's rows
Description
Wraps the CKAN datastore_search action to read the rows of a datastore
resource. One argument is provided for each documented API parameter.
Usage
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
)
Arguments
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 |
Details
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.
Value
A tibble with one row per record. With .return_raw = TRUE, the
parsed response envelope as a list (including total and fields).
See Also
nhsbsa_datastore_search_sql() to filter or aggregate with SQL,
nhsbsa_download_resource() to download the whole resource file.
Examples
# 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
Query a resource with SQL
Description
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).
Usage
nhsbsa_datastore_search_sql(resource_id, sql, .return_raw = FALSE)
Arguments
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 |
Value
A tibble with one row per record returned by the query. With
.return_raw = TRUE, the parsed response envelope as a list.
See Also
nhsbsa_datastore_search() for a parameterised search.
Examples
# 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"
)
Download a resource file
Description
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.
Usage
nhsbsa_download_resource(
dataset_id,
directory,
resource_id = NULL,
pattern = NULL,
overwrite = FALSE,
quiet = FALSE
)
Arguments
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 |
Details
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).
Value
The path to the downloaded file, invisibly.
See Also
nhsbsa_list_resources() to discover resources.
Examples
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()
)
List dataset groups
Description
Wraps the CKAN group_list action to list the groups (thematic collections)
that datasets can belong to.
Usage
nhsbsa_group_list(all_fields = NULL, .return_raw = FALSE)
Arguments
all_fields |
Logical. If |
.return_raw |
Logical. If |
Value
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.
See Also
nhsbsa_organization_list(), nhsbsa_tag_list().
Examples
nhsbsa_group_list()
List a dataset's resources as a tibble
Description
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.
Usage
nhsbsa_list_resources(dataset_id, pattern = NULL)
Arguments
dataset_id |
Character scalar. The dataset identifier, as returned by
|
pattern |
Character scalar. An optional regular expression; only
resources whose |
Details
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).
Value
A tibble with one row per resource and columns name, id,
format, created, last_modified, url and size.
See Also
nhsbsa_download_resource() to download a resource file;
nhsbsa_package_show() (with tibble::as_tibble()) for the same table from
already-fetched metadata.
Examples
# 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")
List publishing organisations
Description
Wraps the CKAN organization_list action to list the organisations that
publish datasets on the portal.
Usage
nhsbsa_organization_list(all_fields = NULL, .return_raw = FALSE)
Arguments
all_fields |
Logical. If |
.return_raw |
Logical. If |
Value
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.
See Also
nhsbsa_group_list(), nhsbsa_tag_list().
Examples
# Organisation names
nhsbsa_organization_list()
# Richer records (title, description, dataset count, ...) for each organisation
orgs <- nhsbsa_organization_list(all_fields = TRUE)
orgs[[1]]$title
List available datasets
Description
Wraps the CKAN package_list action to return the identifiers of every
dataset published on the NHSBSA Open Data Portal.
Usage
nhsbsa_package_list(.return_raw = FALSE)
Arguments
.return_raw |
Logical. If |
Value
A character vector of dataset identifiers. With .return_raw = TRUE,
the parsed response envelope as a list.
See Also
nhsbsa_package_show() for a dataset's metadata,
nhsbsa_package_search() to search datasets.
Examples
datasets <- nhsbsa_package_list()
length(datasets)
head(datasets)
Search datasets
Description
Wraps the CKAN package_search action, a Solr-backed search over datasets.
Usage
nhsbsa_package_search(
q = NULL,
fq = NULL,
sort = NULL,
rows = NULL,
start = NULL,
.return_raw = FALSE
)
Arguments
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 |
Value
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.
Examples
# 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)
Show a dataset's metadata
Description
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).
Usage
nhsbsa_package_show(id, .return_raw = FALSE)
Arguments
id |
Character scalar. The dataset identifier or name, as returned by
|
.return_raw |
Logical. If |
Value
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.
See Also
nhsbsa_list_resources() for a tidy table of a dataset's resources.
Examples
metadata <- nhsbsa_package_show("english-prescribing-data-epd")
metadata
metadata$title
# The dataset's resources as a tibble
tibble::as_tibble(metadata)
Perform a request against a CKAN action endpoint (internal)
Description
Builds the request for action, collecting query parameters from the calling
endpoint function's arguments, performs it with retry/backoff and returns the
parsed result element of the CKAN response envelope.
Usage
nhsbsa_query(action, call = rlang::caller_env())
Arguments
action |
Character scalar. The CKAN action to call (e.g.
|
call |
Environment to report in error messages. |
Value
The result element of the CKAN response, or — when the calling
function was invoked with .return_raw = TRUE — the full parsed response
envelope.
Show a resource's metadata
Description
Wraps the CKAN resource_show action to return the metadata for a single
resource (a file or datastore table).
Usage
nhsbsa_resource_show(id, .return_raw = FALSE)
Arguments
id |
Character scalar. The resource identifier. |
.return_raw |
Logical. If |
Value
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.
Examples
resources <- nhsbsa_list_resources("english-prescribing-data-epd")
meta <- nhsbsa_resource_show(resources$id[[1]])
meta$name
meta$datastore_active
List tags
Description
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")).
Usage
nhsbsa_tag_list(query = NULL, vocabulary_id = NULL, .return_raw = FALSE)
Arguments
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 |
Value
A character vector of tags. With .return_raw = TRUE, the parsed
response envelope as a list.
See Also
nhsbsa_package_search() to find datasets by tag.
Examples
# All tags
tags <- nhsbsa_tag_list()
length(tags)
# Only tags containing a given string
nhsbsa_tag_list(query = "prescribing")