The station inventory file of GHCNd is stored at https://www.ncei.noaa.gov/products/land-based-station/global-historical-climatology-network-daily.
The function stations() can read from this source or from a
local file, specified with filename. The inventory can also
be downloaded to a file using download_inventory().
inventory_file <- download_inventory("~/Downloads/ghcn-inventory.txt")
s <- stations(
  inventory_file,
  variables = "TMAX",
  first_year = 1990,
  last_year = 2000
)s <- stations(variables = "TMAX", first_year = 1990, last_year = 2000)
s
# A tibble: 16,763 × 6
   station     latitude longitude variable firstYear lastYear
   <chr>          <dbl>     <dbl> <chr>        <dbl>    <dbl>
 1 AE000041196     25.3     55.5  TMAX          1944     2024
 2 AEM00041194     25.3     55.4  TMAX          1983     2024
 3 AEM00041217     24.4     54.7  TMAX          1983     2024
 4 AFM00040938     34.2     62.2  TMAX          1973     2020
 5 AFM00040948     34.6     69.2  TMAX          1966     2021
 6 AFM00040990     31.5     65.8  TMAX          1973     2020
 7 AG000060390     36.7      3.25 TMAX          1940     2024
 8 AG000060590     30.6      2.87 TMAX          1940     2024
 9 AG000060611     28.0      9.63 TMAX          1958     2024
10 AG000060680     22.8      5.43 TMAX          1940     2004
# ℹ 16,753 more rows
# ℹ Use `print(n = ...)` to see more rowsBy specifying variables = "TMAX" only the stations that
recorded that variable are kept. Available variables implemented at the
moment are precipitation (“PRCP”), minimum temperature (“TMIN”), and
maximum temperature (“TMAX”). The arguments first_year and
last_year specify the minimum time period required for the
stations. Here, stations that are not sampled at least from 1990 until
at least 2000 are dropped.
Spatial filters can also be easily applied.
Spatial boundaries of countries can be downloaded from <https://www.geoboundaries.org/> using the `get_countr(couuntry_code = ...)` function, where `country_code` is the ISO3 code.get_countries() can take several ISO3 codes to return a
geometry of multiple countries.
s <- filter_stations(s, italy)
s
# A tibble: 41 × 6
   station     latitude longitude variable firstYear lastYear
   <chr>          <dbl>     <dbl> <chr>        <dbl>    <dbl>
 1 IT000016090     45.4     10.9  TMAX          1951     2024
 2 IT000016134     44.2     10.7  TMAX          1951     2024
 3 IT000016232     42       15    TMAX          1975     2024
 4 IT000016239     41.8     12.6  TMAX          1951     2024
 5 IT000016320     40.6     17.9  TMAX          1951     2024
 6 IT000016560     39.2      9.05 TMAX          1951     2024
 7 IT000160220     46.2     11.0  TMAX          1951     2024
 8 IT000162240     42.1     12.2  TMAX          1954     2024
 9 IT000162580     41.7     16.0  TMAX          1951     2024
10 ITE00100554     45.5      9.19 TMAX          1763     2008
# ℹ 31 more rows
# ℹ Use `print(n = ...)` to see more rowsDaily timeseries for a station can be downloaded using the
daily() function. In addition to the station ID,
daily() needs start and end dates of the timeseries. These
should be provided as strings with the format “YYYY-mm-dd”, e.g.,
“1990-01-01”.
daily_ts <- daily(
  station_id = "CA003076680",
  start_date = paste("2002", "11", "01", sep = "-"),
  end_date = paste("2024", "04", "22", sep = "-"),
  variables = "tmax"
)
daily_ts#> # A tibble: 7,547 × 4
#>    date       station      tmax tmax_flag
#>    <date>     <chr>       <dbl> <chr>    
#>  1 2003-01-01 CA003076680  -1.2 ""       
#>  2 2003-01-02 CA003076680  -1.4 ""       
#>  3 2003-01-03 CA003076680   5.2 ""       
#>  4 2003-01-04 CA003076680   3.2 ""       
#>  5 2003-01-05 CA003076680   7.1 ""       
#>  6 2003-01-06 CA003076680  13.6 ""       
#>  7 2003-01-07 CA003076680  16.1 ""       
#>  8 2003-01-08 CA003076680   6   ""       
#>  9 2003-01-09 CA003076680  -2.2 ""       
#> 10 2003-01-10 CA003076680 -11.1 ""       
#> # ℹ 7,537 more rowsMultiple stations can also be downloaded at once. Too many stations will cause the API to fail.
daily_ts <- daily(
  station_id = c("CA003076680", "USC00010655"),
  start_date = paste("2002", "11", "01", sep = "-"),
  end_date = paste("2024", "04", "22", sep = "-"),
  variables = "tmax"
)
plot(daily_ts, "tmax")Implmented variables are “tmin”, “tmax”, and “prcp”.
daily() returns a table with the value of the variable
chosen and associated flags.
Flagged records can be removed using remove_flagged().
In remove_flagged() the argument strict
(dafault = TRUE) specifies which flags to include. The
flags removed are:
#> $D
#> [1] "duplicate flag"
#> 
#> $I
#> [1] "consistency flag"
#> 
#> $K
#> [1] "streak flag"
#> 
#> $M
#> [1] "mega flag"
#> 
#> $N
#> [1] "naught flag"
#> 
#> $R
#> [1] "lagged range flag"
#> 
#> $X
#> [1] "bounds flag"
#> 
#> $O
#> [1] "outlier flag"
#> 
#> $G
#> [1] "gap flag"
#> 
#> $L
#> [1] "multiday flag"
#> 
#> $S
#> [1] "spatial consistency flag"
#> 
#> $Z
#> [1] "Datzilla flag"Setting strict = FALSE will only remove the flags:
#> $D
#> [1] "duplicate flag"
#> 
#> $I
#> [1] "consistency flag"
#> 
#> $K
#> [1] "streak flag"
#> 
#> $M
#> [1] "mega flag"
#> 
#> $N
#> [1] "naught flag"
#> 
#> $R
#> [1] "lagged range flag"
#> 
#> $X
#> [1] "bounds flag"This will also remove the “*_flag=” column.
daily_ts <- remove_flagged(daily_ts)
#> Removing 1 flagged record(s):
#>  - 1 spatial consistency flag(s)
plot(daily_ts, "tmax")Coverage of the timeseries can be calculated using
coverage().
station_coverage <- coverage(daily_ts)
station_coverage
#> # A tibble: 519 × 6
#>    station      year month monthly_coverage_tmax annual_coverage_tmax
#>    <chr>       <dbl> <dbl>                 <dbl>                <dbl>
#>  1 CA003076680  2003     1                 0.871                0.937
#>  2 CA003076680  2003     2                 0.929                0.937
#>  3 CA003076680  2003     3                 0.839                0.937
#>  4 CA003076680  2003     4                 0.867                0.937
#>  5 CA003076680  2003     5                 0.935                0.937
#>  6 CA003076680  2003     6                 1                    0.937
#>  7 CA003076680  2003     7                 1                    0.937
#>  8 CA003076680  2003     8                 1                    0.937
#>  9 CA003076680  2003     9                 1                    0.937
#> 10 CA003076680  2003    10                 0.903                0.937
#> # ℹ 509 more rows
#> # ℹ 1 more variable: period_coverage_tmax <dbl>period_coverage_* calculates the coverage across the
whole period, including missing years.
The output is a table with coverage by month and year
(monthly_coverage), by year (annual_coverage),
and for the whole time period (period_coverage).
annual_coverage is constant within the same year and
year is always a constant. This table is useful to inspect
stations that may have problematic timeseries, such as
unique(station_coverage[
  station_coverage$annual_coverage_tmax < .95,
  c("station", "year", "annual_coverage_tmax")
])
#> # A tibble: 10 × 3
#>    station      year annual_coverage_tmax
#>    <chr>       <dbl>                <dbl>
#>  1 CA003076680  2003                0.937
#>  2 CA003076680  2004                0.929
#>  3 CA003076680  2010                0.942
#>  4 CA003076680  2012                0.918
#>  5 CA003076680  2013                0.901
#>  6 CA003076680  2016                0.825
#>  7 CA003076680  2017                0.882
#>  8 CA003076680  2023                0.868
#>  9 CA003076680  2024                0.885
#> 10 USC00010655  2007                0.912The functions monthly(), quarterly(), and
annual() summarized the weather time series to monthly,
quarterly, and annual time series, respectively. Summaries are
calculated as follows:
NAs are removed during calculation.
monthly_ts <- monthly(daily_ts)
monthly_ts
#> # A tibble: 519 × 4
#>    station      year month  tmax
#>  * <chr>       <dbl> <dbl> <dbl>
#>  1 CA003076680  2003     1  16.1
#>  2 CA003076680  2003     2   4.4
#>  3 CA003076680  2003     3  12.5
#>  4 CA003076680  2003     4  18.9
#>  5 CA003076680  2003     5  27.6
#>  6 CA003076680  2003     6  27.6
#>  7 CA003076680  2003     7  31.4
#>  8 CA003076680  2003     8  32.1
#>  9 CA003076680  2003     9  29.6
#> 10 CA003076680  2003    10  26.2
#> # ℹ 509 more rows
plot(monthly_ts, "tmax")annual_ts <- annual(daily_ts)
annual_ts
#> # A tibble: 44 × 3
#>    station      year  tmax
#>  * <chr>       <dbl> <dbl>
#>  1 CA003076680  2003  32.1
#>  2 CA003076680  2004  31.4
#>  3 CA003076680  2005  28  
#>  4 CA003076680  2006  34.8
#>  5 CA003076680  2007  34.5
#>  6 CA003076680  2008  33.6
#>  7 CA003076680  2009  31.3
#>  8 CA003076680  2010  29.7
#>  9 CA003076680  2011  29.6
#> 10 CA003076680  2012  32.1
#> # ℹ 34 more rows
plot(annual_ts, "tmax")