Changelog
Source:NEWS.md
readnoaa 0.2.1
Resubmission of 0.2.0, which CRAN’s incoming checks rejected on 2026-09-08. Three problems, all now fixed.
write_cache()failed on Windows. The connection to the temporary file was closed byon.exit(), which registers against the enclosing function’s frame rather than thetryCatchblock, so the handle was still open whenfile.rename()ran. Unix renames an open file without complaint; Windows refuses, so every cache write silently returnedFALSEon that platform. The connection is now closed before the rename. This was invisible locally and only surfaced on CRAN’s Windows builder.The
DESCRIPTIONcited the bare NCEI Data Service endpoint, which answers HTTP 400 to a request with no query parameters and so reads as a broken link. It now points at the NCEI API user documentation. The endpoint the package actually calls is unchanged.The README linked WMO guidance on
library.wmo.int, a host that is currently unreachable and returned an HTTP/2 protocol error. Replaced with a plain citation to WMO-No. 1203, which cannot rot.
readnoaa 0.2.0
Examples now fail gracefully when the NCEI API is unreachable
Every \donttest{} example that reaches the NCEI API is wrapped in try(). 9 blocks were 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.
Bug fixes
noaa_normals()works for all periods.period = "annual"requestednormals-annual-1991-2020, which NCEI does not recognise; the annual normals are published asnormals-annualseasonal-1991-2020.period = "daily"sent no date window, which that dataset requires. Both previously failed with HTTP 400 on every call, leaving"monthly"as the only period that worked.period = "hourly"has been added.Hourly datasets no longer lose their timestamps.
global-hourlyandlocal-climatological-datapublish ISO 8601 timestamps, which the date parser did not recognise and silently converted toNA, discarding the time axis of every hourly request. These now return aPOSIXctcolumn in UTC.Station identifiers are no longer corrupted. Values were type-guessed on read, so ISD and GSOD identifiers with leading zeros lost them: Heathrow’s
"03772099999"became the number3772099999. All columns are now read as character and coerced explicitly.Requests for many stations no longer fail. The cache filename embedded the full station list, so a request for roughly fifteen or more stations exceeded the 255-character filename limit and aborted. Cache keys now use a readable prefix plus a digest, and stay within the limit for any request.
Empty responses are no longer cached. A request whose window ran past what NCEI had published was written to the cache and served from there indefinitely, so the missing days never appeared even after NOAA published them. Responses with no observations are now never cached, and an empty result returns a zero-row data frame instead of raising an error.
Missing elevations are
NArather than-999.9. The GHCN-Daily sentinel value was returned as though it were a real measurement for 4,619 stations.noaa_stations(text = )matches literally. The search string was passed straight togrepl()as a regular expression, so a name containing punctuation such as"ST. LOUIS ("raised an invalid-regex error, and metacharacters silently matched more than intended. Passregex = TRUEfor the old behaviour.API errors report what actually went wrong. A failed request reported only its status code, discarding the explanation NCEI returns in the response body, such as
boundingBox: A bounding box is required.list_datasets()no longer advertisesnoaa-global-surface-temperature, which the data service rejects as an unsupported dataset. Arequirescolumn records the datasets that need a date window or a bounding box.Column names containing hyphens now use underscores rather than dots, so a normals column matches the code that was requested:
MLY-TAVG-NORMALreturns asmly_tavg_normal.Retries now cover HTTP 500, 502, and 504 alongside 429 and 503.
New features
noaa_coverage()reports the first and last year of data for every element a station records, from the GHCN-Daily element inventory. This answers how current a station is before you request data from it, which matters because coverage varies from a few days for US stations to over a year for some international ones, and some listed stations stopped reporting years ago.noaa_stations()andnoaa_nearby()acceptelementandactive_sinceto return only stations that record a given variable, or that were still reporting in a given year.cache_info()lists cached responses with their size and age.All data functions accept
refreshto bypass the cache for a single call.
Cache behaviour
Cached responses now expire. A request whose window reaches into the last five weeks is treated as provisional and expires after one day, because NCEI publishes recent observations with a lag and revises them; older windows expire after 30 days. Previously nothing ever expired, so a result fetched during the publication lag was served indefinitely. Configurable through
readnoaa.cache_days_recentandreadnoaa.cache_days.Cache writes are atomic, so an interrupted download cannot leave a truncated file that is later served as valid data.
Other changes
Requests that do not name
datatypesnow drop columns containing no data at all. An unfiltereddaily-summariesrequest returned 152 columns of which around 130 were entirely empty. Passdrop_empty = FALSEto keep them.list_datatypes()reports what a station actually records, read from the element inventory, rather than the dataset’s full column schema. It previously reported 149 codes for a station recording about 20. It also acceptsstart_dateandend_dateto show only elements recorded during a window, and no longer probes a hard-coded week in 2024.noaa_stations()andnoaa_nearby()return the station metadata that was previously discarded when parsing:state,gsn_flag,hcn_crn_flag, andwmo_id.Multi-year daily requests union their column sets across chunks rather than assuming every year returns the same elements.
noaa_normals()documents that the NCEI normals datasets are published in US customary units and ignore theunitsparameter.README station identifiers corrected. Five of the nine listed were wrong:
USW00014739is Boston, not Chicago O’Hare (USW00094846);UKW00035054is West Malling, not Heathrow (UKM00003772);UKE00105915is Hampstead;FRE00104898does not exist (Paris-Montsouris isFRM00007156); and Sydney Observatory Hill stopped reporting in 2020.
readnoaa 0.1.2
- Fixed edge case in CSV numeric coercion where columns with all-NA original values could be incorrectly converted.
readnoaa 0.1.1
CRAN release: 2026-03-19
- Examples now cache to
tempdir()instead of the user’s home directory, fixing CRAN policy compliance for\donttestexamples. - Cache directory is now configurable via
options(readnoaa.cache_dir = ...).