Bug-fix release. Version 0.1.0 could not reach the current ATO release, and several functions returned the wrong table without saying so. Everything below is a fix; no user-facing arguments changed except where noted.
Every \donttest{} example that reaches Zenodo is wrapped
in try(). 1 block was affected. CRAN runs these in its
additional-issues donttest check, on build machines the upstream host
routinely refuses or rate-limits, and an example that could not reach it
was an ERROR rather than a printed condition. The
options(op) cache restore stays outside the
try() so it runs either way.
This is the CRAN Repository Policy requirement that a package using an internet resource fail gracefully when the resource is unavailable. It is the rule obr was archived under on 2026-08-22.
year = "latest" now resolves to it. Documentation that
named 2022-23 as the newest release has been updated, and the “latest”
wording no longer hardcodes a year.ato_ckan_search() joined the organisation filter and
the query terms with a +, which
URLencode(reserved = TRUE) escaped to %2B.
Solr read that as a literal character, so every filtered catalogue
search returned zero results. This broke year = "latest",
the default argument on 27 exported functions, for every one of them.
The terms are now joined with a space.
ato_fetch_xlsx() read sheet 1 of each workbook.
Nearly every ATO workbook opens with a “Notes” or “Information” sheet
and puts the table on the second, so most functions returned front
matter rather than data. Front-matter sheets are now detected by name
and skipped. ato_individuals() returns 846 rows instead of
17; ato_individuals_occupation() 3,771 instead of 16;
ato_tax_gaps() 1,187 instead of 16.
ato_ckan_resolve() returned the first resource
matching a single regex, in package order. The Snapshot workbooks sit at
positions 2 to 8 of a Taxation Statistics package and their filenames
contain “postcode” and “occupation”, so they shadowed the detailed
Individuals tables at positions 20 to 47. It now accepts a priority
vector of patterns plus an exclude regex. Affected
functions and the tables they were returning:
| Function | Was | Now |
|---|---|---|
ato_individuals() |
Snapshot 1 (historical tax rates) | Individuals 1 |
ato_individuals_postcode() |
Snapshot 7 (49 rows) | Individuals 6 (5,254 rows) |
ato_individuals_occupation() |
Snapshot 7 | Individuals 14 |
ato_individuals_sex() |
Individuals 2 (matched “…methodsex…”) | Individuals 3 |
ato_individuals_state() |
Snapshot 7 | Individuals 4 |
ato_medicare_levy() |
Individuals 1 (no Medicare columns) | Individuals 3 |
ato_find_col() matched column names exactly, so ATO
footnote markers defeated it: the postcode table’s state column is
state_territory1, not state_territory. Filters
therefore did nothing and returned unfiltered data with only a warning.
Matching now also accepts a trailing footnote digit
(broad_industry2) and the variant as a leading token
(occupation_unit_group1).
ato_individuals_postcode(state = "NSW") returns 1,250 rows
rather than all 5,254.
Column lookups now happen only when a filter is actually requested, and a requested filter that cannot be applied warns that the data is being returned unfiltered rather than reporting a missing column and continuing quietly.
ato_fbt(), ato_payg() and
ato_charities() searched for standalone packages that have
never existed on data.gov.au. All three are table families inside
Taxation Statistics and now resolve there.
ato_fuel_tax_credits(by = "industry") looked in the
Excise Data package, which has never carried the industry table. It now
reads Excise Table 4 of Taxation Statistics. by = "fuel"
and by = "period" read the historical FTC rate schedule
from Excise Data.
ato_vttc() looked for a resource named after the
year. The ATO has replaced the per-year workbooks with a single dated
notifications register covering all signatories and years, which is now
returned, with a message when a requested year cannot be
honoured.
These aborted or returned an unrelated table. They now abort with an accurate explanation and a pointer to the real source, and are candidates for removal in a later release.
ato_whm(): no Working Holiday Maker resource exists in
any ATO package on data.gov.au, current or archived.ato_division293(): Division 293 is not published as a
labelled series. 0.1.0 fell back to Individuals Table 3 and titled the
result “ATO Division 293”.ato_compliance(): the ATO annual report is a PDF on
ato.gov.au, not open data.The front-matter sheet test matched the whole sheet name, so it
caught “Notes” (28 workbooks) but not “Title & notes” (6) or
“Individuals Tax Title & Notes” (2). Every release up to 2015-16 was
therefore still parsing its title page instead of the data. Now matched
as whole words anywhere in the name, which leaves genuine data sheets
alone (the pre-2010 GST workbooks open on a sheet named for the income
year, e.g. “2000-01”).
ato_individuals_postcode(year = "2011-12") returns 5,067
rows instead of 14.
ato_super_funds() matched fund0[1-4]
only. Releases up to 2012-13 used a single unpadded digit
(taxstats2012fund1apraselecteditemsbyyear.xls), so those
two years errored. Both now return ~200 rows.
Net effect: all six core series now resolve across every release from 2011-12 to 2023-24, verified year by year.
ato_top_taxpayers() ignored its year
argument when reading the workbook. Each CTT release carries late
amendments for earlier income years alongside the headline year, so the
2023-24 request returned 4,198 rows spanning 2023-24, 2022-23 and
2021-22. It now filters on income_year and returns the
4,110 rows the ATO published for 2023-24, reporting how many amendment
rows were dropped.Language in DESCRIPTION was en-US while
the prose is British English throughout. Set to en-GB,
which clears 53 spurious spell-check hits (behaviour, catalogue,
harmonisation, licence, modelling, organisation and similar).
inst/WORDLIST refreshed against the remaining acronyms,
surnames and package names; spelling::spell_check_package()
is now clean.
ato_international() cited
oecd.org/tax/tax-policy/revenue-statistics.htm, which OECD
has since deleted (HTTP 410). Repointed at Revenue Statistics 2025. The
410 was invisible to automated URL checking because oecd.org returns 403
to every request from a non-browser client, valid path or not.
number_of_individuals and
taxable_income_average, neither of which exists in
Individuals Table 6, so it could never have run; it now uses the real
columns and derives the mean.test-resolution.R. Most of it is offline: query
encoding, resource-resolution priority and exclusion against a mocked
package, and column matching. One live test asserts that
year = "latest" resolves to a well-formed, current release
slug. It is deliberately not behind ATO_LIVE_TESTS, because
every existing live test pinned an explicit year and sat behind that
opt-in gate, which is why none of them noticed that the default argument
was broken.Initial CRAN submission. First public release. Provides R access to Australian Taxation Office public datasets via the data.gov.au Comprehensive Knowledge Archive Network (CKAN) API, with reproducibility, harmonisation, and interop tooling.
ato_catalog(): list all ATO datasets on data.gov.au
with their resources, licences, and modification dates.ato_download(): generic resource downloader with local
cache.ato_individuals(): Taxation Statistics Individual
snapshot (Table 1).ato_individuals_postcode(): individual tax return items
by postcode and state (Individuals Table 6). Accepts a vector of years
(e.g. year = 2018:2022) and returns a stacked panel with a
year column.ato_individuals_occupation(): individual tax return
items by occupation (ANZSCO), sex, and income range.ato_individuals_age(),
ato_individuals_sex(),
ato_individuals_state(): demographic cuts.ato_companies(): Company Taxation Statistics across all
nine Company Tables via table = ...: snapshot,
key_items_by_size, entity_type, industry (default), industry_by_size,
sub_industry, taxable_status, source, expenses.ato_super_funds(): APRA-regulated superannuation fund
and Self-Managed Superannuation Fund (SMSF) aggregates.ato_top_taxpayers(): Corporate Tax Transparency release
with sheet switch between income_tax and prrt
(Petroleum Resource Rent Tax filers).ato_gst(): Goods and Services Tax tables and Activity
Statement Ratios.ato_industry(): industry-level aggregates derived from
Individual and Company tables.ato_tax_gaps(): annual Tax Gap estimates across tax
heads (individuals, small business, large corporate, GST, excise, PRRT,
superannuation guarantee). Treasury cites this series in every
MYEFO.ato_rdti(): Research and Development Tax Incentive
claimants, expenditure, and offset data.ato_irpd(): International Related Party Dealings across
annual packages from 2019-20 (Table 1 totals, Table 2 by jurisdiction,
Table 3 chart-data index). Core BEPS and transfer-pricing dataset.ato_excise(): excise rate schedule, Fuel Tax Credit
rates, beer clearances, and spirits and other excisable beverages.ato_sme_benchmarks(): Small Business Benchmarks
(industry-specific cost-to-turnover and related ratios).ato_help(): Study and Training Support Loan statistics
covering HELP, AASL (Australian Apprenticeship Support Loans), and VSL
(VET Student Loans).ato_tax_expenditures(): Treasury Tax Expenditures and
Insights Statement (TEIS).ato_fuel_tax_credits(): FTC claims and rates.ato_division293(): Division 293 additional
contributions tax data.ato_prrt(): Petroleum Resource Rent Tax
aggregates.ato_compliance(): ATO compliance activity
statistics.ato_medicare_levy(): Medicare Levy Surcharge
aggregates.ato_whm(): Working Holiday Maker tax filings.ato_state_tax(): ABS 5506.0 state and territory
taxation.ato_international(): OECD Revenue Statistics.ato_rba(): RBA H1 Commonwealth Government
Receipts.ato_snapshot(): pin a session snapshot date, recorded
in every ato_tbl provenance header, manifest entry, and
citation.ato_sha256(): SHA-256 digest of a file or in-memory
object. Cached downloads carry a sidecar hash verified on every cache
hit; drift warns with both hash prefixes.ato_manifest(), ato_manifest_clear(),
ato_manifest_write(): session registry of every fetch (URL,
CKAN IDs, SHA-256, size, timestamp, snapshot pin, R and ato versions).
Output as data frame, YAML, JSON, or CSV for paper appendices.ato_deposit_zenodo(): stage a Zenodo deposit payload
for the session manifest. Dry run by default; call with
upload = TRUE and a ZENODO_TOKEN to mint a
DOI.ato_cite(): citation helper producing plain text,
BibTeX, or APA output from an ato_tbl or URL, with optional
SHA-256 digest, snapshot date, and doi = argument.ato_crosswalk(): bundled classification and reference
tables (ANZSIC 2006 to 2020, ANZSCO 2013 to 2021, postcode-state
anchors, ABS CPI annual, ABS ERP annual, Final Budget Outcome reference
totals).ato_harmonise(): rename columns to canonical names
across multi-year panels using ATO_COL_VARIANTS.ato_reconcile(): compare an aggregate against the
published Final Budget Outcome figure for the same year and measure;
warns on gaps above 5 per cent.ato_deflate(): nominal AUD to real AUD in a base year
using bundled ABS CPI.ato_per_capita(): divide by ABS ERP.ato_to_taxstats(): rename columns between ATO aggregate
schema and the taxstats 2 per cent microdata sample schema,
in either direction.ato_schema_map(): return the full column-name
mapping.ato_cache_info(), ato_clear_cache(): cache
management.np,
n.p., *, and others) are coerced to
NA by ato_fetch_csv() and
ato_fetch_xlsx() so numeric columns stay numeric.ato_tbl carries provenance attributes
(source URL, CC licence, retrieval time, title) exposed via
print() and ato_cite().grattan and taxstats: costing
a hypothetical reform.Data is published by the Australian Taxation Office on data.gov.au and ato.gov.au. Most Taxation Statistics datasets are licensed under Creative Commons Attribution 2.5 Australia; Corporate Tax Transparency and the Voluntary Tax Transparency Code are licensed under Creative Commons Attribution 3.0 Australia. All downloads are cached locally on first use.