Skip to content

Commit a8019bf

Browse files
committed
v1.2.0-RC
1 parent a30fd27 commit a8019bf

File tree

12 files changed

+248
-95
lines changed

12 files changed

+248
-95
lines changed

.Rapp.history

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
str(test)
21
units(test)
32
60*60*10
43
library(ncdf4)
@@ -419,3 +418,4 @@ rerddap::global_search('jplOscar')
419418
library(sos)
420419
getwd()
421420
devtools::check()
421+
devtools::build()

DESCRIPTION

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
Package: rerddap
2-
Title: General Purpose Client for 'ERDDAP' Servers
3-
Description: General purpose R client for 'ERDDAP' servers. Includes
2+
Title: General Purpose Client for 'ERDDAP' Servers
3+
Description: General purpose R client for 'ERDDAP' servers. Includes
44
functions to search for 'datasets', get summary information on
55
'datasets', and fetch 'datasets', in either 'csv' or 'netCDF' format.
6-
'ERDDAP' information:
6+
'ERDDAP' information:
77
<https://upwell.pfeg.noaa.gov/erddap/information.html>.
8-
Version: 1.1.0
9-
Date: 2024-1-12
8+
Version: 1.2.0
9+
Date: 2024-12-13
1010
License: MIT + file LICENSE
1111
Authors@R: c(
1212
person("Scott", "Chamberlain", role = "aut"),
@@ -31,6 +31,7 @@ Imports:
3131
jsonlite (>= 1.6),
3232
lubridate,
3333
methods,
34+
nanoparquet,
3435
ncdf4 (>= 1.16),
3536
tibble,
3637
utils,

NEWS.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
rerddap 1.2.0
2+
=============
3+
* tabledap() requests can now be downloaded as a parquet file, making for a much smaller download
4+
* units have been added to tabledap() output
5+
* griddap() bug fixed when a coordinate has a very large value, such as for some projected data.
6+
* browse() now returns the URL if base::interactive is FALSE, as the documentation states
7+
18
rerddap 1.1.0
29
=============
310
* 'tabledap()' responses now have the datatype given in the file .dds

R/browse.R

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
#' Browse a dataset webpage.
22
#'
3-
#' Note that it is an error to call this when `base::interactive()`
4-
#' returns `FALSE`
5-
#'
63
#' @export
74
#'
85
#' @param x datasetid or an object associated with a datasetid such
96
#' [info()], [griddap()] or [tabledap()]
10-
#' @param url A URL for an ERDDAP server. Default:
7+
#' @param url A URL for an ERDDAP server. Default:
118
#' https://upwell.pfeg.noaa.gov/erddap/ - See [eurl()] for
129
#' more information
1310
#' @param ... Further args passed on to `utils::browseURL`
@@ -33,39 +30,40 @@ browse <- function(x, url = eurl(), ...){
3330
UseMethod("browse", x)
3431
}
3532

33+
3634
#' @export
3735
browse.character <- function(x, url = eurl(), ...){
38-
stopifnot(interactive())
3936
if (missing(x)) stop("datasetid is required")
4037
uri <- sprintf(paste0(url, 'info/%s/index.html'), x)
41-
utils::browseURL(uri)
38+
39+
if (interactive()) {
40+
utils::browseURL(uri)
41+
} else {
42+
message("URL: ", uri)
43+
return(uri)
44+
}
4245
}
4346

4447
#' @export
4548
browse.info <- function(x, url = eurl(), ...){
46-
stopifnot(interactive())
4749
datasetid <- attr(x, "datasetid")
4850
browse(datasetid, ...)
4951
}
5052

5153
#' @export
5254
browse.tabledap <- function(x, url = eurl(), ...){
53-
stopifnot(interactive())
5455
datasetid <- attr(x, "datasetid")
5556
browse(datasetid, ...)
5657
}
5758

5859
#' @export
5960
browse.griddap_nc <- function(x, url = eurl(), ...){
60-
stopifnot(interactive())
6161
datasetid <- attr(x, "datasetid")
6262
browse(datasetid, ...)
6363
}
6464

65-
6665
#' @export
6766
browse.griddap_csv <- function(x, url = eurl(), ...){
68-
stopifnot(interactive())
6967
datasetid <- attr(x, "datasetid")
7068
browse(datasetid, ...)
7169
}

R/grid.R

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#' Get ERDDAP gridded data
1+
#' Get ERDDAP gridded data
22
#'
33
#' @export
44
#' @template griddap_params
@@ -275,7 +275,7 @@ parse_args <- function(.info, dim, s, dimargs, wname = FALSE){
275275
}
276276
tmp <- format(tmp, scientific = FALSE)
277277
if (length(s) > 1) {
278-
if (!length(s) == length(dimvars(.info))) stop("Your stride vector must equal length of dimension variables", call. = FALSE)
278+
if (!length(s) == length(dimvars(.info))) stop("Your stride vector must equal length of dimension variables", call. = FALSE)
279279
names(s) <- dimvars(.info)
280280
if (!wname) {
281281
sprintf('[(%s):%s:(%s)]', tmp[1], s[[dim]], tmp[2])
@@ -285,16 +285,16 @@ parse_args <- function(.info, dim, s, dimargs, wname = FALSE){
285285
} else {
286286
if (!wname) {
287287
if (length(tmp) == 1) {
288-
tmp
288+
tmp
289289
} else {
290290
sprintf('[(%s):%s:(%s)]', tmp[1], s, tmp[2])
291291
}
292292
} else {
293293
if (length(tmp) == 1) {
294-
tmp
294+
tmp
295295
} else {
296296
sprintf('%s[(%s):%s:(%s)]', dim, tmp[1], s, tmp[2])
297-
}
297+
}
298298
}
299299
}
300300
}

R/table.R

Lines changed: 83 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#' Get ERDDAP tabledap data.
1+
#' Get ERDDAP tabledap data.
22
#'
33
#' @export
44
#'
@@ -8,13 +8,13 @@
88
#' @param ... Any number of key-value pairs in quotes as query constraints.
99
#' See Details & examples
1010
#' @param fields Columns to return, as a character vector
11-
#' @param distinct If `TRUE` ERDDAP will sort all of the rows in the results
11+
#' @param distinct If `TRUE` ERDDAP will sort all of the rows in the results
1212
#' table (starting with the first requested variable, then using the second
1313
#' requested variable if the first variable has a tie, ...), then remove all
14-
#' non-unique rows of data. In many situations, ERDDAP can return distinct
15-
#' values quickly and efficiently. But in some cases, ERDDAP must look through
14+
#' non-unique rows of data. In many situations, ERDDAP can return distinct
15+
#' values quickly and efficiently. But in some cases, ERDDAP must look through
1616
#' all rows of the source dataset.
17-
#' @param orderby If used, ERDDAP will sort all of the rows in the results
17+
#' @param orderby If used, ERDDAP will sort all of the rows in the results
1818
#' table (starting with the first variable, then using the second variable
1919
#' if the first variable has a tie, ...). Normally, the rows of data in the
2020
#' response table are in the order they arrived from the data source. orderBy
@@ -23,7 +23,7 @@
2323
#' sorted by stationID, then time. The orderby variables MUST be included in
2424
#' the list of requested variables in the fields parameter.
2525
#' @param orderbymax Give a vector of one or more fields, that must be included
26-
#' in the fields parameter as well. Gives back data given constraints. ERDDAP
26+
#' in the fields parameter as well. Gives back data given constraints. ERDDAP
2727
#' will sort all of the rows in the results table (starting with the first
2828
#' variable, then using the second variable if the first variable has a
2929
#' tie, ...) and then just keeps the rows where the value of the last sort
@@ -33,10 +33,11 @@
3333
#' @param orderbyminmax Same as `orderbymax` parameter, except returns
3434
#' two rows for every combination of the n-1 variables: one row with the
3535
#' minimum value, and one row with the maximum value.
36+
#' @param fmt whether download should be as '.csv' (default) or '.parquet'
3637
#' @param units One of 'udunits' (units will be described via the UDUNITS
3738
#' standard (e.g.,degrees_C)) or 'ucum' (units will be described via the
3839
#' UCUM standard (e.g., Cel)).
39-
#' @param url A URL for an ERDDAP server.
40+
#' @param url A URL for an ERDDAP server.
4041
#' Default: https://upwell.pfeg.noaa.gov/erddap/ - See [eurl()] for
4142
#' more information
4243
#' @param store One of `disk` (default) or `memory`. You can pass
@@ -165,28 +166,49 @@
165166
#' ## memory
166167
#' tabledap('erdCinpKfmBT', store = memory())
167168
#'
168-
#' # use a different ERDDAP server
169+
#' # use a different ERDDAP server
169170
#' ## NOAA IOOS NERACOOS
170171
#' url <- "http://www.neracoos.org/erddap/"
171172
#' tabledap("E01_optics_hist", url = url)
172173
#' }
173174

174175
tabledap <- function(x, ..., fields=NULL, distinct=FALSE, orderby=NULL,
175-
orderbymax=NULL, orderbymin=NULL, orderbyminmax=NULL, units=NULL,
176+
orderbymax=NULL, orderbymin=NULL, orderbyminmax=NULL, units=NULL, fmt = 'csv',
176177
url = eurl(), store = disk(), callopts=list()) {
178+
177179

178180
if (inherits(x, "info")) {
179181
url <- x$base_url
180182
message("info() output passed to x; setting base url to: ", url)
181183
}
182184
x <- as.info(x, url)
185+
186+
# if fmt is parquet, check the ERDDAP version
187+
188+
if (fmt == 'parquet') {
189+
url_version <- version(url)
190+
url_version <- as.numeric(sub(".*=", "", url_version))
191+
if (url_version < 2.25) {
192+
print(paste0('Selected ERDDAP is version ', url_version))
193+
stop('ERDDAP version greater than 2.25 is required for parquet - program stops')
194+
}
195+
}
196+
183197
fields <- paste(fields, collapse = ",")
184198
lenURL <- nchar(url)
185199
if (substr(url, lenURL, lenURL) != '/') {
186200
url <- paste0(url, '/')
187201
}
188-
url <- sprintf(paste0(url, "tabledap/%s.csv?%s"), attr(x, "datasetid"),
189-
fields)
202+
if (fmt == 'csv') {
203+
url <- sprintf(paste0(url, "tabledap/%s.csv?%s"), attr(x, "datasetid"),
204+
fields)
205+
} else if (fmt == 'parquet') {
206+
url <- sprintf(paste0(url, "tabledap/%s.parquetWMeta?%s"), attr(x, "datasetid"),
207+
fields)
208+
} else {
209+
print(paste0('format given is ', fmt))
210+
stop('fmt must be either csv or parquet')
211+
}
190212
args <- list(...)
191213
distinct <- if (distinct) 'distinct()' else NULL
192214
units <- if (!is.null(units)) {
@@ -206,33 +228,60 @@ tabledap <- function(x, ..., fields=NULL, distinct=FALSE, orderby=NULL,
206228
if (!nchar(args[[1]]) == 0) {
207229
url <- paste0(url, '&', args)
208230
}
209-
resp <- erd_tab_GET(url, dset = attr(x, "datasetid"), store, callopts)
231+
resp <- erd_tab_GET(url, dset = attr(x, "datasetid"), store, fmt, callopts)
210232
loc <- if (store$store == "disk") resp else "memory"
211-
temp_table <- read_table(resp)
212-
# change response type
213-
dds_url <- sub('csv', 'dds', url)
214-
# strip off constraints
215-
amp_location <- regexpr("&", dds_url)
216-
if (amp_location[1] > 0) {
217-
dds_url <- substr(dds_url, 1, amp_location[1] - 1)
233+
temp_table <- read_table(resp, fmt)
234+
# change response type if csv
235+
if (fmt == 'csv'){
236+
dds_url <- sub('csv', 'dds', url)
237+
# strip off constraints
238+
amp_location <- regexpr("&", dds_url)
239+
if (amp_location[1] > 0) {
240+
dds_url <- substr(dds_url, 1, amp_location[1] - 1)
241+
}
242+
dds <- try(suppressWarnings(utils::read.table(dds_url)), silent = TRUE)
243+
# if (class(dds) == 'try-error') {
244+
if (methods::is(dds, 'try-error')) {
245+
print('failed to get variable datatype information')
246+
print('will leave units unchanged')
247+
} else{
248+
temp_table <- set_units(temp_table, dds)
249+
}
218250
}
219-
dds <- try(suppressWarnings(utils::read.table(dds_url)), silent = TRUE)
220-
# if (class(dds) == 'try-error') {
221-
if (methods::is(dds, 'try-error')) {
222-
print('failed to get variable datatype information')
223-
print('will leave units unchanged')
224-
} else{
225-
temp_table <- set_units(temp_table, dds)
251+
252+
# go through columns get units to add as an attribute
253+
# if parquet file also set missing value to NA
254+
temp_table_names <- colnames(temp_table)
255+
icount = 0
256+
for (myName in temp_table_names){
257+
icount <- icount + 1
258+
units_loc <- which(x$alldata[[myName]]$attribute_name == 'units')
259+
if (length(units_loc) > 0) {
260+
temp_units <- x$alldata[[myName]]$value[[units_loc]]
261+
if (icount == 1){
262+
temp_table_units <- temp_units
263+
} else {
264+
temp_table_units <- c(temp_table_units, temp_units)
265+
}
266+
} else {
267+
if (icount == 1){
268+
temp_table_units <- NA
269+
} else {
270+
temp_table_units <- c(temp_table_units, NA)
271+
}
272+
}
273+
fillLoc <- which(x$alldata[[myName]]$attribute_name == '_FillValue')
226274
}
227-
275+
228276

229277
structure(
230278
#read_table(resp),
231279
temp_table,
232280
class = c("tabledap", "data.frame"),
233281
datasetid = attr(x, "datasetid"),
234282
path = loc,
235-
url = url
283+
url = url,
284+
units = temp_table_units
236285
)
237286
}
238287

@@ -250,11 +299,15 @@ print.tabledap <- function(x, ...) {
250299
print(tibble::as_tibble(x))
251300
}
252301

253-
erd_tab_GET <- function(url, dset, store, callopts) {
302+
erd_tab_GET <- function(url, dset, store, fmt, callopts) {
254303
cli <- crul::HttpClient$new(url = url, opts = callopts)
255304
if (store$store == "disk") {
256305
# store on disk
257-
key <- gen_key(url, NULL, "csv")
306+
if (fmt == 'csv') {
307+
key <- gen_key(url, NULL, "csv")
308+
} else {
309+
key <- gen_key(url, NULL, "parquet")
310+
}
258311
if ( file.exists(file.path(store$path, key)) ) {
259312
file.path(store$path, key)
260313
} else {

R/zzz.r

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,17 +63,30 @@ read_all <- function(x, fmt, read) {
6363
)
6464
}
6565

66-
read_table <- function(x){
66+
read_table <- function(x, fmt){
6767
if (inherits(x, "HttpResponse")) {
6868
txt <- gsub('\n$', '', x$parse("UTF-8"))
6969
read.csv(text = txt, sep = ",", stringsAsFactors = FALSE,
7070
blank.lines.skip = FALSE)[-1, , drop = FALSE]
7171
} else {
72-
read.delim(x, sep = ",", stringsAsFactors = FALSE,
73-
blank.lines.skip = FALSE)[-1, , drop = FALSE]
72+
if (fmt =='csv') {
73+
read.delim(x, sep = ",", stringsAsFactors = FALSE,
74+
blank.lines.skip = FALSE)[-1, , drop = FALSE]
75+
} else {
76+
temp_data <- nanoparquet::read_parquet(x)[-1, , drop = FALSE]
77+
}
7478
}
7579
}
7680

81+
replace_value_with_na <- function(x, fillValue) {
82+
if (is.numeric(x)) {
83+
test_value <- as.numeric(fillValue)
84+
x[x == test_value] <- NA
85+
}
86+
return(x)
87+
}
88+
89+
7790
pu <- function(x) sub("/$|//$", "", x)
7891

7992
strect <- function (str, pattern) regmatches(str, regexpr(pattern, str))

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
rerddap
22
=====
33

4+
45
<!-- badges: start -->
56
[![cran checks](https://cranchecks.info/badges/worst/rerddap)](https://cranchecks.info/pkgs/rerddap)
67
[![R-CMD-check](https://github.com/ropensci/rerddap/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/ropensci/rerddap/actions/workflows/R-CMD-check.yaml)

0 commit comments

Comments
 (0)