Skip to content

Commit fdf512f

Browse files
Merge pull request #145 from ropensci/dev
v0.7.2
2 parents f90bb10 + c537526 commit fdf512f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+3711
-2373
lines changed

.github/workflows/R-CMD-check.yaml

+12-11
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1-
# Workflow derived from https://github.com/r-lib/actions/tree/master/examples
1+
# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples
22
# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help
33
on:
44
push:
5+
branches: [main, master]
56
pull_request:
67
schedule:
7-
- cron: '30 0 * * 1'
8+
- cron: '30 0 1 * *'
89

9-
name: R-CMD-check
10+
name: R-CMD-check.yaml
11+
12+
permissions: read-all
1013

1114
jobs:
1215
R-CMD-check:
@@ -18,9 +21,9 @@ jobs:
1821
fail-fast: false
1922
matrix:
2023
config:
21-
- {os: macOS-latest, r: 'release'}
24+
- {os: macos-latest, r: 'release'}
2225
- {os: windows-latest, r: 'release'}
23-
#- {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'}
26+
- {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'}
2427
- {os: ubuntu-latest, r: 'release'}
2528
- {os: ubuntu-latest, r: 'oldrel-1'}
2629

@@ -30,12 +33,7 @@ jobs:
3033
R_KEEP_PKG_SOURCE: yes
3134

3235
steps:
33-
- uses: actions/checkout@v2
34-
35-
- name: MacOS dependencies
36-
if: runner.os == 'macOS'
37-
run: |
38-
brew install pkg-config gdal proj
36+
- uses: actions/checkout@v4
3937

4038
- uses: r-lib/actions/setup-pandoc@v2
4139

@@ -51,3 +49,6 @@ jobs:
5149
needs: check
5250

5351
- uses: r-lib/actions/check-r-package@v2
52+
with:
53+
upload-snapshots: true
54+
build_args: 'c("--no-manual","--compact-vignettes=gs+qpdf")'

DESCRIPTION

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Package: weathercan
22
Type: Package
33
Title: Download Weather Data from Environment and Climate Change Canada
4-
Version: 0.7.1
4+
Version: 0.7.2
55
Authors@R: c(
66
person("Steffi", "LaZerte", email = "[email protected]", role = c("aut","cre"), comment = c(ORCID = "0000-0002-7690-8360")),
77
person("Sam", "Albers", email = "[email protected]", role = c("ctb"), comment = c(ORCID = "0000-0002-9270-7884")),
@@ -18,7 +18,7 @@ Language: en-CA
1818
BugReports: https://github.com/ropensci/weathercan/issues/
1919
LazyData: TRUE
2020
URL: https://docs.ropensci.org/weathercan/, https://github.com/ropensci/weathercan/
21-
Depends: R (>= 3.3.0)
21+
Depends: R (>= 4.1.0)
2222
Imports:
2323
dplyr (>= 1.0.0),
2424
httr (>= 1.4.2),
@@ -35,7 +35,7 @@ Imports:
3535
tidyselect (>= 1.0.0),
3636
xml2 (>= 0.1.2),
3737
rappdirs (>= 0.3.3)
38-
RoxygenNote: 7.2.3
38+
RoxygenNote: 7.3.1
3939
Roxygen: list(markdown = TRUE)
4040
Suggests:
4141
devtools,

NAMESPACE

+1
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ export(weather_dl)
1010
export(weather_interp)
1111
importFrom(dplyr,"%>%")
1212
importFrom(rlang,.data)
13+
importFrom(rlang,.env)

NEWS.md

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
# weathercan (development version)
2+
3+
# weathercan 0.7.2
4+
- Fix normals to work with new ECCC data format
5+
- Prepare `normals_dl()` and family for new 1991-2020 normals
6+
17
# weathercan 0.7.1
28
- `stations()` now uses the most recent version of the data even if it hasn't changed
39
(prevent message regarding age of stations data frame).

R/normals.R

+62-45
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
#' data frame or the \code{\link{stations_search}} function to find Climate
1111
#' IDs.
1212
#' @param normals_years Character. The year range for which you want climate
13-
#' normals. Default "1981-2010".
13+
#' normals. Default "1981-2010". One of "1971-2000", "1981-2010", "1991-2020".
14+
#' Note: Some "1991-2020" are available online, but are not yet downloadable
15+
#' via weathercan.
1416
#' @param format Logical. If TRUE (default) formats measurements to numeric and
1517
#' date accordingly. Unlike `weather_dl()`, `normals_dl()` will always format
1618
#' column headings as normals data from ECCC cannot be directly made into a
@@ -29,10 +31,11 @@
2931
#' not the climate normals for this station met the WMO standards for
3032
#' temperature and precipitation (i.e. both have code >= A). Each measurement
3133
#' column has a corresponding `_code` column which reflects the data quality
32-
#' of that measurement (see the [1981-2010 ECCC calculations
33-
#' document](https://climate.weather.gc.ca/doc/Canadian_Climate_Normals_1981_2010_Calculation_Information.pdf)
34-
#' or the [1971-2000 ECCC calculations document](https://climate.weather.gc.ca/doc/Canadian_Climate_Normals_1971_2000_Calculation_Information.pdf)
35-
#' for more details)
34+
#' of that measurement (see the
35+
#' [1991-2020](https://collaboration.cmc.ec.gc.ca/cmc/climate/Normals/Canadian_Climate_Normals_1991_2020_Calculation_Information.pdf),
36+
#' [1981-2010](https://collaboration.cmc.ec.gc.ca/cmc/climate/Normals/Canadian_Climate_Normals_1981_2010_Calculation_Information.pdf), or
37+
#' [1971-2000](https://collaboration.cmc.ec.gc.ca/cmc/climate/Normals/Canadian_Climate_Normals_1971_2000_Calculation_Information.pdf)
38+
#' for more details) ECCC calculation documents.
3639
#'
3740
#' Climate normals are downloaded from the url stored in option
3841
#' `weathercan.urls.normals`. To change this location use:
@@ -49,12 +52,12 @@
4952
#' n <- normals_dl(climate_ids = "5010480")
5053
#' n
5154
#'
52-
#' # Pull out last frost data
55+
#' # Pull out last frost data *with* station information
5356
#' library(tidyr)
5457
#' f <- unnest(n, frost)
5558
#' f
5659
#'
57-
#' # Pull out normals
60+
#' # Pull out normals *with* station information
5861
#' nm <- unnest(n, normals)
5962
#' nm
6063
#'
@@ -67,14 +70,13 @@
6770
#'
6871
#' # Download multiple stations for 1981-2010,
6972
#' n <- normals_dl(climate_ids = c("301C3D4", "301FFNJ", "301N49A"))
70-
#' n
73+
#' unnest(n, frost)
74+
#'
7175
#'
72-
#' # Note, putting both into the same data set can be done but makes for
76+
#' # Note, putting both normals and frost data into the same data set can be done but makes for
7377
#' # a very unweildly dataset (there is lots of repetition)
74-
#' nm <- unnest(n, normals)
75-
#' f <- unnest(n, frost)
76-
#' both <- dplyr::full_join(nm, f)
77-
#' both
78+
#' nm <- unnest(n, normals) |>
79+
#' unnest(frost)
7880
#' @export
7981

8082
normals_dl <- function(climate_ids, normals_years = "1981-2010",
@@ -89,6 +91,11 @@ normals_dl <- function(climate_ids, normals_years = "1981-2010",
8991
}
9092
stn <- stations()
9193

94+
if(normals_years == "1991-2020") {
95+
stop("The new normals for 1991-2020 are not yet available via weathercan",
96+
call. = FALSE)
97+
}
98+
9299
check_ids(climate_ids, stn, type = "climate_id")
93100
check_normals(normals_years)
94101

@@ -111,7 +118,6 @@ normals_dl <- function(climate_ids, normals_years = "1981-2010",
111118
dplyr::select(-"normals")
112119
}
113120

114-
115121
# Download data
116122
n <- n %>%
117123
dplyr::mutate(
@@ -326,57 +332,66 @@ frost_extract <- function(f, climate_id) {
326332

327333
if(all(f == "")) return(dplyr::tibble())
328334

329-
frost_free <- stringr::str_which(f, f_names$variable[f_names$group == 1][1])
330-
frost_probs <- stringr::str_which(f, f_names$variable[f_names$group == 2][1])
335+
frost_free <- stringr::str_which(f, f_names$match[f_names$group == 1][1])[1]
336+
frost_probs <- stringr::str_which(f, f_names$match[f_names$group == 2][1])[1]
331337

332338
# Frost free days overall
333-
if(length(frost_free) > 0) {
339+
if(any(!is.na(frost_free)) && length(frost_free) > 0) {
334340
if(length(frost_probs) == 0) last <- length(f) else last <- frost_probs - 1
335341

336342
readr::local_edition(1)
337343
f1 <- readr::read_csv(I(f[frost_free:last]),
338344
col_names = c("variable", "value", "frost_code"),
339-
col_types = readr::cols(), progress = FALSE) %>%
345+
col_types = readr::cols(), progress = FALSE) |>
340346
tidyr::spread(key = "variable", value = "value")
341347

342-
n <- tibble_to_list(f_names[f_names$variable %in% names(f1),
343-
c("new_var", "variable")])
344-
f1 <- dplyr::rename(f1, !!n) %>%
348+
nms <- purrr::map(stats::setNames(f_names$match, f_names$new_var),
349+
\(x) stringr::str_subset(names(f1), x)) |>
350+
unlist()
351+
352+
f1 <- dplyr::rename(f1, !!nms) %>%
345353
dplyr::mutate_at(.vars = dplyr::vars(dplyr::contains("date")),
346-
~lubridate::yday(lubridate::as_date(paste0("1999", .)))) %>%
354+
~lubridate::yday(lubridate::as_date(paste0("1999", .)))) |>
347355
dplyr::mutate(length_frost_free =
348356
stringr::str_extract(.data$length_frost_free, "[0-9]*"),
349357
length_frost_free = as.numeric(.data$length_frost_free))
350358
} else f1 <- na_tibble(f_names$new_var[f_names$group == 1])
351359

352360
# Frost free probabilities
353-
if(length(frost_probs) > 0) {
361+
if(any(!is.na(frost_probs)) && length(frost_probs) > 0) {
362+
354363
readr::local_edition(1)
355364
f2 <- readr::read_csv(I(f[frost_probs:length(f)]),
356365
col_names = FALSE, col_types = readr::cols(),
357-
progress = FALSE) %>%
358-
as.data.frame()
359-
f2 <- data.frame(prob = rep(c("10%", "25%", "33%", "50%",
360-
"66%", "75%", "90%"), 3),
361-
value = c(t(f2[2, 2:8]), t(f2[4, 2:8]), t(f2[6, 2:8])),
362-
measure = c(rep(f2[1,1], 7), rep(f2[3,1], 7),
363-
rep(f2[5,1], 7))) %>%
364-
tidyr::spread("measure", "value")
365-
366-
n <- tibble_to_list(f_names[f_names$variable %in% names(f2),
367-
c("new_var", "variable")])
368-
369-
f2 <- dplyr::rename(f2, !!n)
366+
progress = FALSE) |>
367+
dplyr::select(dplyr::where(\(x) !all(is.na(x)))) |>
368+
dplyr::rename_with(
369+
.fn = \(x) "prob",
370+
.cols = dplyr::where(\(x) any(stringr::str_detect(x, "(P|p)robability")))) |>
371+
dplyr::rename_with(
372+
.fn = \(x) "value",
373+
.cols = dplyr::where(\(x) {
374+
any(stringr::str_detect(x, paste0("(", paste0(month.abb, collapse = ")|("), ")")))
375+
})) |>
376+
dplyr::mutate(measure = stringr::str_remove(.data$prob, "\\(\\d{2}%\\)"),
377+
prob = stringr::str_extract(.data$prob, "\\d{2}%")) |>
378+
tidyr::pivot_wider(names_from = "measure", values_from = "value")
379+
380+
nms <- purrr::map(stats::setNames(f_names$match, f_names$new_var),
381+
\(x) stringr::str_subset(names(f2), x)) |>
382+
unlist()
383+
384+
f2 <- dplyr::rename(f2, !!nms)
370385
} else f2 <- na_tibble(f_names$new_var[f_names$group == 2])
371386

372387
if(nrow(f1) == 0 & nrow(f2) == 0) {
373388
r <- cbind(f1, f2)
374389
} else {
375390
r <- dplyr::full_join(
376-
dplyr::mutate(f1, climate_id = climate_id),
377-
dplyr::mutate(f2, climate_id = climate_id),
378-
by = "climate_id", relationship = "many-to-many") %>%
379-
dplyr::select(-climate_id)
391+
dplyr::mutate(f1, climate_id = .env$climate_id),
392+
dplyr::mutate(f2, climate_id = .env$climate_id),
393+
by = "climate_id", relationship = "many-to-many") |>
394+
dplyr::select(-"climate_id")
380395
}
381396

382397
dplyr::as_tibble(r)
@@ -389,18 +404,20 @@ frost_find <- function(n, type = "extract") {
389404
# If no frost-free title, look for next measurement
390405

391406
if(length(frost) == 0) {
392-
for(i in f_names$variable) {
393-
frost <- find_line(n, i)
394-
if(length(frost) != 0) break
395-
}
407+
frost <- purrr::map(f_names$match, \(x) find_line(n, x)) |>
408+
unlist() |>
409+
min_na()
396410
}
397411

398412
if(length(frost) == 1) {
399413
if(type == "extract") r <- n[(frost):length(n)]
400414
if(type == "remove") r <- n[1:(frost-1)]
401-
} else {
415+
} else if(length(frost) == 0) {
402416
if(type == "extract") r <- ""
403417
if(type == "remove") r <- n
418+
} else{
419+
stop("Problem identifying frost data in normals\nPlease report this here: ",
420+
"https://github.com/ropensci/weathercan/issues", call. = FALSE)
404421
}
405422
r
406423
}

0 commit comments

Comments
 (0)