readnoaa

Lifecycle: stable License: MIT

readnoaa provides clean, tidy access to climate and weather data from NOAA (the National Oceanic and Atmospheric Administration) directly from R. No API key required.

What is NOAA?

The National Oceanic and Atmospheric Administration is a US federal agency responsible for monitoring weather, oceans, and the atmosphere. Its National Centers for Environmental Information (NCEI) is the world’s largest archive of weather and climate data, hosting observations from over 100,000 stations across 180 countries, with some records stretching back to the 1700s.

NCEI maintains the Data Service API, which provides free, open access to this archive. Unlike many government data APIs, it requires no API key - you can start pulling data immediately. The API returns clean CSV with data current to approximately 2-3 days ago.

Types of data

NOAA’s archive covers a wide range of weather and climate variables. Daily observations include maximum and minimum temperature, precipitation, snowfall, snow depth, and wind speed. Monthly and annual summaries aggregate these into averages and totals. The data spans land-based weather stations, marine buoys, and airport observation sites worldwide.

Beyond current observations, NOAA publishes 30-year climate normals — statistical baselines calculated from the 1991-2020 period that represent “typical” weather for a given location. These are widely used in agriculture, energy, construction, and climate research to understand how current conditions compare to long-term averages. The archive also includes hourly observations, 15-minute precipitation data, and local climatological records for more specialised use cases.

Why readnoaa?

The flagship R package for NOAA data, rnoaa (~3,300 downloads/month at its peak), was archived from CRAN in February 2024 when NOAA deprecated its CDO v2 API. The planned rOpenSci replacement never materialised. The only remaining CRAN package (noaa, 3 functions, ~180 downloads/month) still targets the broken old API.

readnoaa fills this gap by targeting NOAA’s current NCEI Data Service v1 API. It provides dedicated functions for the most common datasets (daily observations, monthly/annual summaries, climate normals) plus a generic fetcher for the full archive. Station discovery functions help you find stations by location or name.

Installation

# Install from GitHub
devtools::install_github("charlescoverdale/readnoaa")

Quick start

Daily temperature for Central Park, NYC

library(readnoaa)

df <- noaa_daily("USW00094728", "2024-01-01", "2024-01-31",
                 datatypes = c("TMAX", "TMIN"))
head(df)
#>       station       date                          name tmax tmin
#>   USW00094728 2024-01-01 NEW YORK CITY CENTRAL PARK, NY  8.9  3.3
#>   USW00094728 2024-01-02 NEW YORK CITY CENTRAL PARK, NY  5.0 -1.1
#>   USW00094728 2024-01-03 NEW YORK CITY CENTRAL PARK, NY  2.8 -2.2
#>   ...

Find stations near London

stations <- noaa_nearby(51.5, -0.1, radius_km = 25)
head(stations)
#>        station                    name latitude longitude distance_km
#>   UKE00105915     LONDON WEATHER CENTRE   51.517    -0.117        1.4
#>   UKW00035054     HEATHROW             51.478    -0.449       24.1
#>   ...

Monthly precipitation summary

df <- noaa_monthly("USW00094728", "2024-01", "2024-12",
                   datatypes = c("PRCP"))
head(df)
#>       station       date                          name  prcp
#>   USW00094728 2024-01-01 NEW YORK CITY CENTRAL PARK, NY  87.6
#>   USW00094728 2024-02-01 NEW YORK CITY CENTRAL PARK, NY  55.4
#>   ...

Climate normals

normals <- noaa_normals("USW00094728", "monthly")
head(normals)
#>       station                          name  month  mly_tavg_normal  mly_prcp_normal
#>   USW00094728 NEW YORK CITY CENTRAL PARK, NY  01     1.2              86.4
#>   USW00094728 NEW YORK CITY CENTRAL PARK, NY  02     2.3              76.5
#>   ...

Multiple stations in one call

# Compare rainfall across three US cities
df <- noaa_monthly(c("USW00094728", "USW00023174", "USW00014739"),
                   "2024-01", "2024-12", datatypes = "PRCP")
head(df)
#>       station       date                               name  prcp
#>   USW00094728 2024-01-01 NEW YORK CITY CENTRAL PARK, NY US   87.6
#>   USW00023174 2024-01-01 LOS ANGELES INTL AP, CA US         52.3
#>   USW00014739 2024-01-01 CHICAGO OHARE INTL AP, IL US       44.2
#>   ...
df <- noaa_annual("USW00094728", "2000-01-01", "2024-01-01",
                  datatypes = "TAVG")
head(df)
#>       station       date                          name  tavg
#>   USW00094728 2000-01-01 NEW YORK CITY CENTRAL PARK, NY  13.1
#>   USW00094728 2001-01-01 NEW YORK CITY CENTRAL PARK, NY  13.4
#>   ...

Hourly data with the generic fetcher

# noaa_get() can access any NCEI dataset, including those
# without a dedicated function
df <- noaa_get("global-hourly", station = "USW00094728",
               start_date = "2024-07-01", end_date = "2024-07-01")
head(df)
#>       station       date                          name  ...
#>   USW00094728 2024-07-01 NEW YORK CITY CENTRAL PARK, NY ...
#>   ...

Finding stations

Every NOAA data request needs a station ID. There are two ways to find stations:

1. Search by location using noaa_nearby():

# Stations within 50 km of Sydney, Australia
noaa_nearby(-33.87, 151.21, radius_km = 50)
#>        station                    name latitude longitude distance_km
#>   ASN00066062 SYDNEY OBSERVATORY HILL   -33.86    151.21         1.1
#>   ASN00066006 SYDNEY AIRPORT AMO       -33.95    151.17         9.8
#>   ...

2. Search by name or bounding box using noaa_stations():

# Search by name
noaa_stations(text = "Heathrow")
#>        station              name latitude longitude elevation
#>   UKW00035054 HEATHROW            51.478    -0.449      25.3
#>   ...

# Search by bounding box (south, west, north, east)
noaa_stations(bbox = c(35, -120, 40, -115))
#>        station                    name latitude longitude elevation
#>   USC00040232   BAKERSFIELD MEADOWS FLD   35.433  -119.050     150.0
#>   ...

Common station IDs

Station Location
USW00094728 New York City (Central Park)
USW00023174 Los Angeles International Airport
USW00014739 Chicago O’Hare
UKE00105915 London Weather Centre
UKW00035054 London Heathrow
ASN00066062 Sydney Observatory Hill
JA000047662 Tokyo
GME00111445 Berlin-Tempelhof
FRE00104898 Paris-Montsouris

Common variables

Variable Code Unit (metric) Function
Maximum temperature TMAX °C noaa_daily()
Minimum temperature TMIN °C noaa_daily()
Precipitation PRCP mm noaa_daily(), noaa_monthly()
Snowfall SNOW mm noaa_daily()
Snow depth SNWD mm noaa_daily()
Average temperature TAVG °C noaa_monthly(), noaa_annual()
Wind speed AWND m/s noaa_daily()
Normal temperature MLY-TAVG-NORMAL °C noaa_normals()
Normal precipitation MLY-PRCP-NORMAL mm noaa_normals()

Use list_datatypes() to discover all available variables for a given dataset and station.

Data quality flags

NCEI applies automated quality control checks to all observations, flagging approximately 0.3% of values. You can include these flags by setting include_flags = TRUE:

df <- noaa_daily("USW00094728", "2024-01-01", "2024-01-31",
                 datatypes = c("TMAX", "TMIN"), include_flags = TRUE)

This adds attribute columns alongside each data column containing measurement and quality flag codes. Flags are useful for filtering suspect observations in research workflows.

To include station coordinates (latitude, longitude, elevation) with each observation, use include_location = TRUE.

Functions

Function Description
noaa_daily() Daily weather observations
noaa_monthly() Monthly summaries
noaa_annual() Annual summaries
noaa_normals() 30-year climate normals (1991-2020)
noaa_get() Generic fetcher for any NCEI dataset
noaa_stations() Search for stations by bbox or text
noaa_nearby() Find stations near a point
list_datasets() Curated table of common datasets
list_datatypes() Available data types for a dataset
clear_cache() Clear local cache

Data sources

Daily observations come from the Global Historical Climatology Network - Daily (GHCN-Daily), which integrates data from over 100,000 stations across 180 countries. Monthly and annual summaries are derived from the Global Summary of the Month/Year datasets. Climate normals follow the WMO guidelines for calculating 30-year averages.

Licence and limitations

NOAA data is produced by the US federal government and is in the public domain. There are no restrictions on its use, redistribution, or modification.

The NCEI Data Service API is free and requires no API key, but it does enforce rate limits. This package automatically throttles requests and retries on rate-limit errors. Daily data requests spanning more than one year are automatically split into yearly chunks to avoid API timeouts. Data is typically available up to 2-3 days behind real time, and station coverage varies — some stations have gaps or limited variable availability. This package is not affiliated with or endorsed by NOAA.