| Title: | Access to USAspending Data in a DuckLake |
|---|---|
| Description: | Provides a connection to USAspending data in a DuckLake, allowing users to perform bulk analyses difficult to achieve with the USAspending API. |
| Authors: | Grant Witness [aut, cre] |
| Maintainer: | Grant Witness <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.1.0 |
| Built: | 2026-09-18 09:46:55 UTC |
| Source: | https://usaspending.grant-witness.us/r-package/duckspending.git |
S3 method for connections::connection_view(). Builds an
rscontract::rscontract_spec() that wires the pane's drill-down to
pane_object_list() and pane_object_columns() so the IDE sees a
filtered, user-facing view of the DuckLake.
connection_view.duckspending_connection( con, connection_code = "", host = "", name = "", connection_id = "" )connection_view.duckspending_connection( con, connection_code = "", host = "", name = "", connection_id = "" )
con |
A |
connection_code |
Optional connection code shown by the IDE. |
host, name, connection_id
|
The result of rscontract::rscontract_open(), invisibly.
Caches the snapshot's catalog locally (if needed), ATTACHes it under
a hidden alias, and creates a top-level schema named after the date
with one view per user table. After this call the snapshot is queryable
as <conn>.<YYYYMMDD>.<table>.
duckspending_attach(snapshot, conn = duckspending_connection())duckspending_attach(snapshot, conn = duckspending_connection())
snapshot |
Snapshot identifier (YYYYMMDD character, |
conn |
A |
If conn is the package's cached default connection (the one
duckspending_connection() returns with no args), the cache entry is
updated in place so subsequent default-arg callers see the new state.
conn, invisibly, with the new snapshot in its metadata.
Currently-attached snapshots on a connection
duckspending_attached(conn = duckspending_connection())duckspending_attached(conn = duckspending_connection())
conn |
A |
Character vector of YYYYMMDD dates, newest first.
Calls cache_httpfs_clear_cache() on the underlying DuckDB session to
delete all cached parquet blocks from disk. Useful when you want to force
fresh fetches or reclaim disk space.
duckspending_clear_cache(conn = duckspending_connection())duckspending_clear_cache(conn = duckspending_connection())
conn |
A |
Has no effect (with a message) if the connection was opened with
cache = FALSE or if the cache_httpfs extension failed to load.
conn, invisibly.
Opens a DuckDB connection with one or more monthly DuckLake snapshots
attached. Each attached snapshot is exposed as a top-level schema named
after its date ("20260206", "20260306", ...). A latest schema
mirrors the newest attached snapshot for convenience.
duckspending_connection( snapshots = "latest", base_url = default_base_url(), catalog_dir = tools::R_user_dir("duckspending", which = "cache"), download_catalog = TRUE, open_pane = TRUE, cache = .duckspending_cache_default(), new_conn = FALSE )duckspending_connection( snapshots = "latest", base_url = default_base_url(), catalog_dir = tools::R_user_dir("duckspending", which = "cache"), download_catalog = TRUE, open_pane = TRUE, cache = .duckspending_cache_default(), new_conn = FALSE )
snapshots |
Snapshot selector. One of:
|
base_url |
Base URL of the public archive. Override for testing
via |
catalog_dir |
Local cache directory for snapshot catalog files. |
download_catalog |
Logical; when |
open_pane |
Logical; when |
cache |
Logical; when |
new_conn |
Logical; when |
By default a single snapshot — the newest one announced by the public
manifest — is attached. To attach a specific set, pass snapshots = ....
The first call with default arguments caches its connection in a
package-level environment; subsequent default calls reuse it, so all
the other duckspending_* helpers that default conn = duckspending_connection()
share a single underlying DuckDB session. Calls with non-default
arguments are not cached.
A duckspending_connection (duckdb_connection subclass).
## Not run: con <- duckspending_connection() duckspending_tbl("subaward_search") # uses the cached default DBI::dbDisconnect(con, shutdown = TRUE) ## End(Not run)## Not run: con <- duckspending_connection() duckspending_tbl("subaward_search") # uses the cached default DBI::dbDisconnect(con, shutdown = TRUE) ## End(Not run)
Three modes:
With no table, returns one row per user-facing table in each
attached snapshot (plus the latest alias).
With a table, returns a column-level summary for that table in
the requested snapshot (defaults to latest).
duckspending_describe( table = NULL, snapshot = NULL, descriptions = duckspending_descriptions(), include_source = FALSE, conn = duckspending_connection() )duckspending_describe( table = NULL, snapshot = NULL, descriptions = duckspending_descriptions(), include_source = FALSE, conn = duckspending_connection() )
table |
Optional table name. When |
snapshot |
Snapshot selector for the column-level mode.
|
descriptions |
Optional list returned by
|
include_source |
If |
conn |
A |
Internal bookkeeping (DuckLake metadata, hidden _dl_* databases,
_snapshots marker, DuckDB metadata schemas) is filtered out.
A tibble.
Descriptions live in a JSON file at the bucket root next to the catalog
(default URL is derived from the production catalog URL). When the file
is unreachable (e.g. not yet published, transient network error),
returns NULL so callers can fall back to schema-only output.
duckspending_descriptions( url = NULL, dir = tools::R_user_dir("duckspending", which = "cache"), refresh = FALSE )duckspending_descriptions( url = NULL, dir = tools::R_user_dir("duckspending", which = "cache"), refresh = FALSE )
url |
URL or local path to a descriptions JSON. Defaults to
|
dir |
Directory to cache the file in. |
refresh |
Force a re-check this session (ignores the per-session memoisation). The conditional ETag/Last-Modified check still applies, so a still-fresh remote file isn't re-downloaded. |
The file is cached under tools::R_user_dir() and refreshed
conditionally via the ETag / Last-Modified headers: the first call
per R session sends a HEAD request, and a GET only follows when the
remote validators differ from the cached ones. Subsequent calls in the
same session reuse the cached parse without any HTTP traffic.
If the per-session check fails (e.g. no network), the failure is
silent: a cached copy is returned when available, NULL otherwise, and
the next call within the same session re-attempts the check — so a
transient outage doesn't permanently disable the help-text refresh.
Expected JSON shape:
{
"tables": {
"<schema>.<table>": {
"description": "...",
"columns": {"<column>": "..."}
}
}
}
A parsed list, or NULL if the file could not be fetched.
Drops the user-facing schema ("YYYYMMDD") and DETACHes the hidden
underlying catalog. Removes the snapshot from the connection metadata.
Refuses to detach the snapshot currently bound to latest.
duckspending_detach(snapshot, conn = duckspending_connection())duckspending_detach(snapshot, conn = duckspending_connection())
snapshot |
Snapshot identifier. |
conn |
A |
conn, invisibly.
Stamps attr(col, "label") on every column in data whose name has a
matching description in the USAspending descriptions dictionary. Both
Positron's Data Explorer and RStudio's View() honour attr(., "label")
and surface it under the column header — the same convention used by
the labelled and haven packages.
duckspending_label( data, table = NULL, descriptions = duckspending_descriptions() )duckspending_label( data, table = NULL, descriptions = duckspending_descriptions() )
data |
A data frame or tibble. |
table |
Optional table name. When supplied, only descriptions for
that table are used (unambiguous; recommended when you know the
source). When |
descriptions |
Optional list returned by |
Columns whose names aren't in the dictionary are left untouched.
data, with attr(., "label") set on matching columns.
Checks (in order): options(duckspending.label = ...), the
DUCKSPENDING_LABEL env var, and falls back to TRUE. The env var
is treated as falsy if set to "false", "0", "no", "off"
(case-insensitive); anything else (including unset-but-checked) is truthy.
duckspending_label_default()duckspending_label_default()
A single logical.
Convenience equivalent of duckspending_snapshots()[1]. Returns
NA_character_ if no manifest is reachable.
duckspending_latest( refresh = FALSE, base_url = default_base_url(), cache_dir = tools::R_user_dir("duckspending", which = "cache") )duckspending_latest( refresh = FALSE, base_url = default_base_url(), cache_dir = tools::R_user_dir("duckspending", which = "cache") )
refresh |
Logical; bypass the local cache and re-fetch. |
base_url |
Base URL (default: production). Override with
|
cache_dir |
Local cache directory. |
YYYYMMDD character scalar or NA_character_.
Fetches the small text manifest at
{base_url}/snapshots.txt and returns the date strings, newest first.
The manifest is cached in tools::R_user_dir("duckspending", "cache")
for one hour to keep repeat calls cheap.
duckspending_snapshots( refresh = FALSE, base_url = default_base_url(), cache_dir = tools::R_user_dir("duckspending", which = "cache"), ttl_seconds = 3600L )duckspending_snapshots( refresh = FALSE, base_url = default_base_url(), cache_dir = tools::R_user_dir("duckspending", which = "cache"), ttl_seconds = 3600L )
refresh |
Logical; bypass the local cache and re-fetch. |
base_url |
Base URL (default: production). Override with
|
cache_dir |
Local cache directory. |
ttl_seconds |
Cache TTL in seconds (default 1 hour). |
A character vector of YYYYMMDD dates, newest first. Empty character if the manifest is not found.
Each function below returns a non-collected dplyr table reference
(i.e. a tbl_lazy) for one of the headline tables in the archive.
They are thin wrappers around duckspending_tbl() that exist so the
table names users care about most are exported, autocompletable, and
discoverable via ?duckspending — you don't have to remember the
exact column-name spelling of subaward_search etc.
duckspending_subawards( snapshot = NULL, label = duckspending_label_default(), conn = duckspending_connection() ) duckspending_assistance_transactions( snapshot = NULL, label = duckspending_label_default(), conn = duckspending_connection() ) duckspending_procurement_transactions( snapshot = NULL, label = duckspending_label_default(), conn = duckspending_connection() ) duckspending_agencies( snapshot = NULL, label = duckspending_label_default(), conn = duckspending_connection() ) duckspending_recipients( snapshot = NULL, label = duckspending_label_default(), conn = duckspending_connection() )duckspending_subawards( snapshot = NULL, label = duckspending_label_default(), conn = duckspending_connection() ) duckspending_assistance_transactions( snapshot = NULL, label = duckspending_label_default(), conn = duckspending_connection() ) duckspending_procurement_transactions( snapshot = NULL, label = duckspending_label_default(), conn = duckspending_connection() ) duckspending_agencies( snapshot = NULL, label = duckspending_label_default(), conn = duckspending_connection() ) duckspending_recipients( snapshot = NULL, label = duckspending_label_default(), conn = duckspending_connection() )
snapshot |
Optional snapshot selector (YYYYMMDD, |
label |
Whether to attach column descriptions as |
conn |
A |
Everything is lazy: build a dplyr pipeline and call
dplyr::collect() when you want the result in R, or run
dplyr::show_query() to inspect the SQL. To use the legacy raw
tables not listed here, call duckspending_tbl() directly.
A tbl_lazy reference.
duckspending_subawards(): Sub-award table
(subaward_search) — one row per disclosed sub-award.
duckspending_assistance_transactions(): Federal Assistance (FABS)
transactions — source_assistance_transaction.
duckspending_procurement_transactions(): Federal Procurement (FPDS)
transactions — source_procurement_transaction.
duckspending_agencies(): Toptier agencies
(toptier_agency) — one row per department/agency at the top of
the federal hierarchy.
duckspending_recipients(): Recipient profile table
(recipient_profile) — one row per known funding recipient with
rolled-up totals.
This help topic is rendered dynamically from
<base>/descriptions.json on the public archive, so it always
reflects the descriptions currently shipping alongside the catalog –
no package release is required when descriptions change.
The table below lists every user-facing table in the archive
together with a short description. Column-level descriptions are
available via duckspending_describe().
If the descriptions JSON is unreachable (network outage, file not
yet published) the table will say so and you can still inspect the
schema interactively with duckspending_describe().
Descriptions are not currently available — the JSON file could not be fetched. Use duckspending_describe()on a live connection for schema details.
duckspending_describe() for live, column-level details on
a connected DuckLake; duckspending_descriptions() for the raw
parsed JSON.
Returns a non-collected dplyr table reference to <snapshot>.<name>,
where <snapshot> defaults to the connection's latest schema. Verifies
the table exists first so users get a clear error instead of a deferred
SQL failure.
duckspending_tbl( name, snapshot = NULL, label = duckspending_label_default(), conn = duckspending_connection() )duckspending_tbl( name, snapshot = NULL, label = duckspending_label_default(), conn = duckspending_connection() )
name |
Table name (no quoting needed). |
snapshot |
Optional snapshot selector. One of:
|
label |
Whether to attach column descriptions as |
conn |
A |
A tbl_lazy (dbplyr) reference to the table.
Thin convenience wrapper around connections::connection_view() that
dispatches to the duckspending_connection S3 method. Useful after
creating a connection with open_pane = FALSE, or to re-open the
pane after closing it.
duckspending_view(conn = duckspending_connection())duckspending_view(conn = duckspending_connection())
conn |
A |
conn, invisibly.