├── .Rapp.history ├── .Rbuildignore ├── .github ├── .gitignore ├── CONTRIBUTING.md ├── issue_template.md ├── pull_request_template.md └── workflows │ ├── R-CMD-check.yaml │ ├── R-check.yml │ └── test-coverage.yaml ├── .gitignore ├── CRAN-RELEASE ├── CRAN-SUBMISSION ├── DESCRIPTION ├── LICENSE ├── LICENSE.md ├── Makefile ├── NAMESPACE ├── NEWS.md ├── R ├── .DS_Store ├── browse.R ├── cache_delete.R ├── cache_details.R ├── cache_list.R ├── cache_paths.R ├── cache_setup.R ├── colors.R ├── convert_time.R ├── convert_units.R ├── default-url.R ├── fipscounty.R ├── global_search.R ├── grid.R ├── info.R ├── keywords.R ├── ncdf_helpers.R ├── on_load.R ├── rerddap-package.r ├── search.R ├── search_adv.R ├── servers.R ├── table.R ├── utils.R ├── version.R └── zzz.r ├── README.Rmd ├── README.md ├── _pkgdown.yml ├── codemeta.json ├── cran-comments.md ├── data ├── colors.rda ├── institutions.rda ├── ioos_categories.rda ├── keywords.rda ├── longnames.rda ├── standardnames.rda └── variablenames.rda ├── inst └── extdata │ └── MWsstd1day.nc ├── man-roxygen ├── griddap_egs.R └── griddap_params.R ├── man ├── browse.Rd ├── cache_delete.Rd ├── cache_details.Rd ├── cache_list.Rd ├── cache_setup.Rd ├── colors.Rd ├── convert_time.Rd ├── convert_units.Rd ├── disk.Rd ├── ed_search.Rd ├── ed_search_adv.Rd ├── eurl.Rd ├── fipscounty.Rd ├── global_search.Rd ├── griddap.Rd ├── info.Rd ├── institutions.Rd ├── ioos_categories.Rd ├── key_words.Rd ├── keywords.Rd ├── longnames.Rd ├── rerddap.Rd ├── servers.Rd ├── standardnames.Rd ├── tabledap.Rd ├── variablenames.Rd └── version.Rd ├── rerddap.Rproj ├── revdep ├── README.md ├── failures.md └── problems.md └── vignettes ├── CPSPlot-1.png ├── CPSPlot-2.png ├── MUR_sst.png ├── NAtlSSS.png ├── NDBC.png ├── NDBCTS.png ├── Using_rerddap.Rmd ├── VIIIRS_chla.png ├── VIIRS_chla.png ├── VIIRS_sst.png ├── VIIRS_sst_series.png ├── atn.png ├── calCOFIPlot-1.png ├── calCOFIPlot-2.png ├── coho_anomaly.png ├── glider.png ├── ifrPSA.png ├── maxslp.png ├── rerddap.Rmd ├── rerddap.Rmd.og ├── sardines.png └── soda70.png /.Rapp.history: -------------------------------------------------------------------------------- 1 | units(test) 2 | 60*60*10 3 | library(ncdf4) 4 | gribfile <- "http://nomads.ncdc.noaa.gov/thredds/dodsC/modeldata/cfsv2_forecast_ts_9mon/2011/201104/20110401/2011040100/tmax.01.2011040100.daily.grb2" 5 | nc <- nc.open(gribfile) 6 | nc <- nc_open(gribfile) 7 | gribfile <- "http://nomads.ncdc.noaa.gov/thredds/dodsC/modeldata/cfsv2_forecast_ts_9mon/2011/201104/20110401/2011040100/tmax.01.2011040100.daily.grb2.nc" 8 | nc <- nc_open(gribfile) 9 | gribfile <- "https://nomads.ncdc.noaa.gov/thredds/dodsC/modeldata/cfsv2_forecast_ts_9mon/2011/201104/20110401/2011040100/tmax.01.2011040100.daily.grb2.nc" 10 | nc <- nc_open(gribfile) 11 | gribfile <- "https://nomads.ncdc.noaa.gov/thredds/dodsC/modeldata/cfsv2_forecast_ts_9mon/2011/201104/20110401/2011040100/tmax.01.2011040100.daily.grb2" 12 | nc <- nc_open(gribfile) 13 | str(nc) 14 | nc_close(nc) 15 | library(orcutt) 16 | price<-c( 0.27, 0.28, 0.28, 0.28, 0.27, 0.26, 0.28 ,0.27 ,0.26 ,0.28, 0.28 ,0.27, 0.27, 0.29, 0.28,0.29, 0.28, 0.2 cons<-c(0.39, 0.37, 0.39, 0.42, 0.41, 0.34, 0.33, 0.29, 0.27, 0.26, 0.29 ,0.30, 0.33, 0.32, 0.38,0.38, 0.47, 0.44, income<-c(78, 79, 81, 80 ,76 ,78, 82, 79, 76, 79, 82, 85, 86, 83, 84, 82, 80, 78, 84, 86, 85, 87, 94, 92, 95, 96, 94 temp<-c(41,56,63,68,69,65,61,47,32,24,28,26,32,40,55,63,72,72,67,60,44,40,32,27,28,33,41,52,64,71) reg<-lm(cons~price+income+temp) reg2<-cochrane.orcutt(reg) reg2 17 | ?orcutt 18 | price<-c( 0.27, 0.28, 0.28, 0.28, 0.27, 0.26, 0.28 ,0.27 ,0.26 ,0.28, 0.28 ,0.27, 0.27, 0.29, 0.28,0.29, 0.28, 0.28, 0.28, 0.28, 0.29, 0.29, 0.28, 0.28, 0.28, 0.26, 0.26 ,0.26, 0.27 ,0.26)# 19 | cons<-c(0.39, 0.37, 0.39, 0.42, 0.41, 0.34, 0.33, 0.29, 0.27, 0.26, 0.29 ,0.30, 0.33, 0.32, 0.38,0.38, 0.47, 0.44, 0.39, 0.34, 0.32, 0.31, 0.28, 0.33, 0.31, 0.36, 0.38 ,0.42, 0.44 ,0.55)# 20 | income<-c(78, 79, 81, 80 ,76 ,78, 82, 79, 76, 79, 82, 85, 86, 83, 84, 82, 80, 78, 84, 86, 85, 87, 94, 92, 95, 96, 94, 96, 91, 90)# 21 | temp<-c(41,56,63,68,69,65,61,47,32,24,28,26,32,40,55,63,72,72,67,60,44,40,32,27,28,33,41,52,64,71)# 22 | reg<-lm(cons~price+income+temp)# 23 | reg2<-cochrane.orcutt(reg)# 24 | reg2 25 | library(orcutt) 26 | ?orcutt 27 | price<-c( 0.27, 0.28, 0.28, 0.28, 0.27, 0.26, 0.28 ,0.27 ,0.26 ,0.28, 0.28 ,0.27, 0.27, 0.29, 0.28,0.29, 0.28, 0.28, 0.28, 0.28, 0.29, 0.29, 0.28, 0.28, 0.28, 0.26, 0.26 ,0.26, 0.27 ,0.26)# 28 | cons<-c(0.39, 0.37, 0.39, 0.42, 0.41, 0.34, 0.33, 0.29, 0.27, 0.26, 0.29 ,0.30, 0.33, 0.32, 0.38,0.38, 0.47, 0.44, 0.39, 0.34, 0.32, 0.31, 0.28, 0.33, 0.31, 0.36, 0.38 ,0.42, 0.44 ,0.55)# 29 | income<-c(78, 79, 81, 80 ,76 ,78, 82, 79, 76, 79, 82, 85, 86, 83, 84, 82, 80, 78, 84, 86, 85, 87, 94, 92, 95, 96, 94, 96, 91, 90)# 30 | temp<-c(41,56,63,68,69,65,61,47,32,24,28,26,32,40,55,63,72,72,67,60,44,40,32,27,28,33,41,52,64,71)# 31 | reg<-lm(cons~price+income+temp)# 32 | reg2<-cochrane.orcutt(reg) 33 | reg 34 | reg2 35 | summary(reg) 36 | library(xtractomatic) 37 | citation(xtractomatic) 38 | citation("xtractomatic") 39 | ?xtractomatic 40 | library(IgorR) 41 | ?IgorR 42 | junk = read.pxp('/Users/rmendels/WorkFiles/65n_fourier.pxp', ReturnTimeSeries = TRUE) 43 | str(junk) 44 | str(junk$common_season12_10) 45 | plot(junk$common_season12_10) 46 | plot(junk$common_trend_1) 47 | sin(0) 48 | sin(1) 49 | ?saveRDS 50 | library(TSclust) 51 | ?TSclust 52 | data(interest.rates) 53 | trans.inter.rates <- log(interest.rates[2:215,]) - log(interest.rates[1:214,]) 54 | str(trans.inter.rates) 55 | ?diss 56 | myDist <- diss(trans.inter.rates,METHOD="DTWARP") 57 | library(ggplot2) 58 | library(plotly) 59 | set.seed(100)# 60 | d <- diamonds[sample(nrow(diamonds), 1000), ]# 61 | plot_ly(d, x = ~carat, y = ~price, color = ~carat,# 62 | size = ~carat, text = ~paste("Clarity: ", clarity)) 63 | p <- ggplot(data = d, aes(x = carat, y = price)) +# 64 | geom_point(aes(text = paste("Clarity:", clarity))) +# 65 | geom_smooth(aes(colour = cut, fill = cut)) + facet_wrap(~ cut) 66 | p 67 | ggplotly(p) 68 | library(ggiraph) 69 | ?ggiraph 70 | data("GlobalTemp") model_temp <- SSModel(GlobalTemp ~ SSMtrend(1, Q = NA, type = "common"), H = matrix(NA, 2, 2)) # Estimating the variance parameters inits <- chol(cov(GlobalTemp))[c(1, 4, 3)] inits[1:2] <- log(inits[1:2]) fit_temp <- fitSSM(model_temp, c(0.5*log(.1), inits), method = "BFGS") out_temp <- KFS(fit_temp$model) ts.plot(cbind(model_temp$y, coef(out_temp)), col = 1:3) legend("bottomright", legend = c(colnames(GlobalTemp), "Smoothed signal"), col = 1:3, lty = 1) 71 | library(KFAS) 72 | data("GlobalTemp") model_temp <- SSModel(GlobalTemp ~ SSMtrend(1, Q = NA, type = "common"), H = matrix(NA, 2, 2)) # Estimating the variance parameters inits <- chol(cov(GlobalTemp))[c(1, 4, 3)] inits[1:2] <- log(inits[1:2]) fit_temp <- fitSSM(model_temp, c(0.5*log(.1), inits), method = "BFGS") out_temp <- KFS(fit_temp$model) ts.plot(cbind(model_temp$y, coef(out_temp)), col = 1:3) legend("bottomright", legend = c(colnames(GlobalTemp), "Smoothed signal"), col = 1:3, lty = 1) 73 | library(rerddap) 74 | sardines <- tabledap(# 75 | 'FRDCPSTrawlLHHaulCatch',# 76 | fields = c('latitude', 'longitude', 'time', 'scientific_name', 'subsample_count'),# 77 | 'time>=2010-01-01', 'time<=2012-01-01', 'scientific_name="Sardinops sagax"'# 78 | ) 79 | p <- plotdap() 80 | add_tabledap(p, sardines, ~subsample_count) 81 | add_tabledap(p, sardines, ~log(subsample_count)) 82 | p <- plotdap(crs = "+proj=robin") 83 | add_tabledap(p, sardines, ~subsample_count) 84 | murSST <- griddap(# 85 | 'jplMURSST41', latitude = c(22, 51), longitude = c(-140, -105),# 86 | time = c('last', 'last'), fields = 'analysed_sst'# 87 | ) 88 | p <- plotdap(crs = "+proj=robin") 89 | add_griddap(p, murSST, ~analysed_sst) 90 | murSST <- griddap(# 91 | 'jplMURSST41', latitude = c(22, 51), longitude = c(-140, -105),# 92 | time = c('last', 'last'), fields = 'analysed_sst'# 93 | ) 94 | str(murSST) 95 | p <- plotdap() 96 | add_griddap(p, murSST, ~analysed_sst) 97 | help(.Rprofile) 98 | library(rerddap)# 99 | url <- "http://upwell.pfeg.noaa.gov/erddap/"# 100 | myinfo <- info( datasetid = "esrlNcepRe_LonPM180"# 101 | , url = url# 102 | ) 103 | myinfo 104 | x <- griddap( myinfo# 105 | , time = c( "2015-07-01T00:00:00Z", "2015-07-02T00:00:00Z" )# 106 | , latitude = c( 35, 37 )# 107 | , longitude = c( -117, -115 )# 108 | , fmt = "csv"# 109 | ) 110 | str(x) 111 | library(DT)# 112 | datatable(iris) 113 | library(DT) 114 | datatable(iris) 115 | View(iris) 116 | datatable(iris) 117 | f <- function() {# 118 | x <- 1# 119 | y <- 2# 120 | c(x, y)# 121 | }# 122 | f() 123 | rm(f) 124 | x <- 2# 125 | g <- function() {# 126 | y <- 1# 127 | c(x, y)# 128 | }# 129 | g() 130 | x <- 1# 131 | h <- function() {# 132 | y <- 2# 133 | i <- function() {# 134 | z <- 3# 135 | c(x, y, z)# 136 | }# 137 | i()# 138 | }# 139 | h() 140 | j <- function(x) {# 141 | y <- 2# 142 | function() {# 143 | c(x, y)# 144 | }# 145 | }# 146 | k <- j(1)# 147 | k() 148 | ?runif 149 | ?outer 150 | x <- 1:9; names(x) <- x 151 | x %o% x 152 | outer(month.abb, 1999:2003, FUN = "paste") 153 | str(month.abb) 154 | ?sprintf 155 | library(rerddap) 156 | pacakageVersion("rerddap") 157 | packageVersion("rerddap") 158 | plotdap() 159 | library(rerddap)# 160 | dataInfo <- rerddap::info('hawaii_d90f_20ee_c4cb')# 161 | xpos <- c(135.25, 240.25)# 162 | ypos <- c(20.25, 60.25)# 163 | zpos <- c(70.02, 70.02)# 164 | tpos <- c('2010-12-15', '2010-12-15')# 165 | soda70 <- griddap(dataInfo, longitude = xpos, latitude = ypos, time = tpos, depth = zpos, fields = 'temp' ) 166 | soda70$data$lon <- soda70$data$lon - 360 167 | junk <- soda70$data 168 | str(junk) 169 | is.factor(soda70$data$time) 170 | devtools::install_github("edzer/sfr") 171 | ?library 172 | library(lubridate) 173 | ?yday 174 | library(matplot) 175 | library(plotdap) 176 | sstInfo <- info('jplMURSST41') 177 | murSST <- griddap(sstInfo, latitude = c(22., 51.), longitude = c(-140., -105), time = c('last','last'), fields = 'analysed_sst') 178 | add_griddap(plotdap(), murSST, ~analysed_sst, maxpixels = 50000) 179 | library(ncdf4) 180 | myURL - 'http://kyrill.ias.sdsmt.edu:8080/thredds/dodsC/testAll/TSA_RCP85_CONUS_1920-2100.nc4' 181 | myURL <- 'http://kyrill.ias.sdsmt.edu:8080/thredds/dodsC/testAll/TSA_RCP85_CONUS_1920-2100.nc4' 182 | junk <- nc_open(myURL) 183 | str(junk) 184 | Sys.timezone() 185 | library(raster)# 186 | library(sf)# 187 | library(ggplot2)# 188 | # 189 | f <- system.file("external/test.grd", package="raster")# 190 | r <- raster(f)# 191 | s <- st_as_sf(rasterToPolygons(r))# 192 | ggplot() + geom_sf(data = s, aes(fill = test), colour = "transparent") 193 | library(sf) 194 | ?sf_transform 195 | ?st_transform 196 | library(rerddap) 197 | library(plotdap) 198 | library)ggplot2 199 | library(ggplot2) 200 | sardines <- tabledap(# 201 | 'FRDCPSTrawlLHHaulCatch',# 202 | fields = c('latitude', 'longitude', 'time', 'scientific_name', 'subsample_count'),# 203 | 'time>=2010-01-01', 'time<=2012-01-01', 'scientific_name="Sardinops sagax"'# 204 | ) 205 | add_tabledap(# 206 | plotdap(), # 207 | sardines, # 208 | ~subsample_count# 209 | ) 210 | buoy <- tabledap(# 211 | 'cwwcNDBCMet', # 212 | fields=c('latitude', 'longitude', 'time', 'wtmp'), # 213 | 'time=2017-08-01T19:00:00Z', # 214 | 'latitude>=36.5','latitude<=38.55', 'longitude>=-123.5','longitude<=-121.5',# 215 | 'wtmp>0'# 216 | ) 217 | buoy 218 | sardines 219 | add_tabledap(plotdap("base"), buoy, ~as.numeric(wtmp)) 220 | library(ggplot2) 221 | library(gapminder) 222 | library(gganimate) 223 | p <- ggplot(gapminder, aes(gdpPercap, lifeExp, size = pop, color = continent, frame = year)) +# 224 | geom_point() +# 225 | scale_x_log10() 226 | gganimate(p) 227 | library(gapminder)# 228 | library(ggplot2)# 229 | theme_set(theme_bw()) 230 | p <- ggplot(gapminder, aes(gdpPercap, lifeExp, size = pop, color = continent, frame = year)) +# 231 | geom_point() +# 232 | scale_x_log10() 233 | library(gganimate)# 234 | # 235 | gganimate(p) 236 | system("export PATH=/sw/bin:$PATH") 237 | gganimate(p) 238 | library(devtools) 239 | ?devtools 240 | gganimate(p) 241 | library(goodpractice) 242 | gp(path = "/Users/rmendels/WorkFiles/rerddap") 243 | ?plotBox 244 | covr::package_coverage() 245 | ?covr 246 | library(xtactomatic) 247 | library(xtractomatic) 248 | extract <- xtracto(tagData$lon[1:3], tagData$lat[1:3], tagData$date[1:3], "ETOPO360", 0. , 0.) 249 | tagData <- Marlintag38606 250 | extract <- xtracto(tagData$lon[1:3], tagData$lat[1:3], tagData$date[1:3], "ETOPO360", 0. , 0.) 251 | str(extract) 252 | extract <- xtracto(tagData$lon[1:3], tagData$lat[1:3], tagData$date[1:3], "ETOPO360", 0. , 0., verbose = TRUE) 253 | library(rerddap) 254 | urlbase <- 'https://upwell.pfeg.noaa.gov/erddap'# 255 | dataInfo <- rerddap::info('erdMBsstd8day')# 256 | parameter <- 'sst'# 257 | xcoord <- c(230, 231)# 258 | ycoord <- c(40, 41)# 259 | tcoord <- c('2006-01-15', '2006-01-20')# 260 | zcoord <- c(0., 0.)# 261 | xlen <- 0.5# 262 | ylen <- 0.5# 263 | extract <- rxtracto(dataInfo, parameter = parameter, xcoord = xcoord,# 264 | ycoord = ycoord, tcoord= tcoord, zcoord = zcoord,# 265 | xlen = xlen, ylen = ylen) 266 | library(rerddapXtracto) 267 | extract <- rxtracto(dataInfo, parameter = parameter, xcoord = xcoord,# 268 | ycoord = ycoord, tcoord= tcoord, zcoord = zcoord,# 269 | xlen = xlen, ylen = ylen) 270 | str(extract) 271 | devtools::install_github("helske/bssm") 272 | devtools::install_github("eliocamp/metR") 273 | library(ncdf4) 274 | ?ncvar_get 275 | 180/pi 276 | devtools::install_github("ropensci/git2r") 277 | devtools::install_github("seananderson/glmmfields") 278 | library(gridExtra) 279 | ?grid.arrange 280 | library(sf) 281 | wd <- st_as_sf(maps::map('world', plot = FALSE, fill = TRUE)) 282 | wd <- st_transform(wd, st_crs("+proj=robin")) 283 | st_graticule(wd) 284 | library(rerddap) 285 | install.packages('curl') 286 | library(rerddap) 287 | ?rerddap 288 | browseURL("https://www.r-project.org") 289 | devtools::install_github("james-thorson/VAST", INSTALL_opts="--no-staged-install") 290 | library(rgeos) 291 | ?rgeos 292 | ??rgeos 293 | spgeom() 294 | gArea() 295 | dummy <- function() rgeos::getScale() 296 | ?crs 297 | ?try_require 298 | load("/Users/rmendels/WorkFiles/Bakun_Kiefer/sst_model_phase.RData") 299 | ls() 300 | str(sst_model_phase_kernel_smooth) 301 | library(rnoaa) 302 | gefs_latitudes() 303 | gefs_longitudes() 304 | lat <- 46.28125# 305 | lon <- -118.2188 306 | forecast <- gefs("Total_precipitation_surface_6_Hour_Accumulation_ens",# 307 | lat, lon, ens = 0, time = 12) 308 | library(rnoaa) 309 | library(sp) 310 | data(meuse) 311 | data(meuse.grid) 312 | str(meuse.grid) 313 | str(meuse) 314 | library(sp) 315 | data(meuse) 316 | str(meuse) 317 | date(meuse.grid) 318 | data(meuse.grid) 319 | str(meuse.grid) 320 | zoop <- deriv(expression((-0.0263*B)+(0.0010*B^2)),"B",func=TRUE) 321 | zoop 322 | library(ncdf4) 323 | library(rerddap) 324 | info <- ('nesdisVHNSQchlaMonthly', url = 'https://coastwatch.pfeg.noaa.gov/erddap/') 325 | junk <- info('nesdisVHNSQchlaMonthly', url = 'https://coastwatch.pfeg.noaa.gov/erddap/') 326 | str(junk) 327 | plot(1:10) 328 | quartz()# 329 | plot(1:10) 330 | library(rerddap) 331 | result <- griddap('noaa_psl_7072_e40a_a07a', # 332 | time = c('1983-01-01', '1983-01-04'),# 333 | x = c(844038, 1103742),# 334 | y = c(6135507, 6297822),# 335 | fields ='quflux'# 336 | ) 337 | result <- griddap('noaa_psl_7072_e40a_a07a', # 338 | time = c('1983-01-01', '1983-01-04'),# 339 | x = c(844038, 1103742),# 340 | y = c(6135507, 6297822),# 341 | fields ='all'# 342 | ) 343 | out <- info('erdVHNchlamday') 344 | res <- griddap('erdVHNchlamday',# 345 | time = c('2015-04-01','2015-04-10'),# 346 | latitude = c(18, 21),# 347 | longitude = c(-120, -119)# 348 | ) 349 | result <- griddap(out, # 350 | time = c('1983-01-01', '1983-01-04'),# 351 | x = c(844038, 1103742),# 352 | y = c(6135507, 6297822),# 353 | fields ='all'# 354 | ) 355 | str(out) 356 | ibrary(buildmer)# 357 | library(lme4)# 358 | # 359 | nrow <- 100# 360 | # 361 | test <- data.frame(x01=runif(nrow),# 362 | y=runif(nrow)<.1, block=as.factor(floor((1:nrow)/50)))# 363 | head(test)# 364 | fit.model <- lme4::glmer(y~x01 + (1|block), data=test,# 365 | family=binomial(link="logit"))# 366 | fit.model # this works# 367 | # 368 | class(fit.model)# 369 | # 370 | summary(fit.model) 371 | library(buildmer)# 372 | library(lme4)# 373 | # 374 | nrow <- 100# 375 | # 376 | test <- data.frame(x01=runif(nrow),# 377 | y=runif(nrow)<.1, block=as.factor(floor((1:nrow)/50)))# 378 | head(test)# 379 | fit.model <- lme4::glmer(y~x01 + (1|block), data=test,# 380 | family=binomial(link="logit"))# 381 | fit.model # this works# 382 | # 383 | class(fit.model)# 384 | # 385 | summary(fit.model) 386 | install.packages("INLA",repos=c(getOption("repos"),INLA="https://inla.r-inla-download.org/R/stable"), dep=TRUE) 387 | library(ggplot2)# 388 | # 389 | linedata<- data.frame(# 390 | PointEstx = c( 1, 2 )# 391 | , PointEsty = c( 1, 1.5 )# 392 | ) 393 | str(linedata) 394 | ggplot(# 395 | linedata# 396 | , aes( x = PointEstx# 397 | , y = PointEsty# 398 | )# 399 | ) + geom_line() 400 | ggplot(linedata,aes(x=PointEstx, y=PointEsty) + geom_line()) 401 | ggplot(linedata,aes(x=PointEstx, y=PointEsty)) + geom_line() 402 | library(rerddap) 403 | cache_setup(temp_dir = TRUE) 404 | library(rerddap) 405 | cache_info() 406 | get_cache_path() 407 | library(rerddap)# 408 | cache_delete_all() 409 | dat <- tabledap('FED_JSATS_detects', 'study_id="RBDD_2018"', callopts = list(verbose = TRUE)) 410 | head(dat) 411 | myURL <- https://coastwatch.pfeg.noaa.gov/erddap/ 412 | myURL <- 'https://coastwatch.pfeg.noaa.gov/erddap/' 413 | oscr_info <- rerddap::info('jplOscar', url = myURL) 414 | oscr_info 415 | ?rerddap 416 | rerddp::global_search('jplOscar') 417 | rerddap::global_search('jplOscar') 418 | library(sos) 419 | getwd() 420 | devtools::check() 421 | devtools::build() 422 | -------------------------------------------------------------------------------- /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^.*\.Rproj$ 2 | ^\.Rproj\.user$ 3 | .travis.yml 4 | README.Rmd 5 | README.md 6 | _pkgdown.yml 7 | appveyor.yml 8 | Makefile 9 | cran-comments.md 10 | man-roxygen 11 | ^CODE_OF_CONDUCT\.md$ 12 | ^cran-comments\.md$ 13 | ^codemeta\.json$ 14 | ^revdep$ 15 | ^rerddap-.*\.tar\.gz$ 16 | ^rerddap-_.*\.tar\.gz$ 17 | ^\.github$ 18 | ^LICENSE\.md$ 19 | revdep/ 20 | ^CRAN-RELEASE$ 21 | ^CRAN-SUBMISSION$ 22 | -------------------------------------------------------------------------------- /.github/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # CONTRIBUTING # 2 | 3 | ### Fixing typos 4 | 5 | Small typos or grammatical errors in documentation may be edited directly using 6 | the GitHub web interface, so long as the changes are made in the _source_ file. 7 | 8 | * CORRECT: you edit a roxygen comment in a `.R` file below `R/`. 9 | * INCORRECT: you edit an `.Rd` file below `man/`. 10 | 11 | ### Prerequisites 12 | 13 | Before you make a substantial pull request, you should always file an issue and 14 | make sure someone from the team agrees that it’s a problem. If you’ve found a 15 | bug, create an associated issue and illustrate the bug with a minimal 16 | [reprex](https://www.tidyverse.org/help/#reprex). 17 | 18 | ### Pull request process 19 | 20 | * We recommend that you create a Git branch for each pull request (PR). 21 | * Look at the Travis and AppVeyor build status before and after making changes. The `README` should contain badges for any continuous integration services used by the package. 22 | * We use [roxygen2](https://cran.r-project.org/package=roxygen2). 23 | * We use [testthat](https://cran.r-project.org/package=testthat). Contributions with test cases included are easier to accept. 24 | * For user-facing changes, add a bullet to the top of `NEWS.md` below the 25 | current development version header describing the changes made followed by your 26 | GitHub username, and links to relevant issue(s)/PR(s). 27 | 28 | ### Code of Conduct 29 | 30 | Please note that the `rerddadp` project is released with a 31 | [Contributor Code of Conduct](https://ropensci.org/code-of-conduct/). By contributing to this project you agree to abide by its terms. 32 | 33 | ### See rOpenSci [contributing guide](https://ropensci.github.io/dev_guide/contributingguide.html) for further details. 34 | 35 | ### Discussion forum 36 | 37 | Check out our [discussion forum](https://discuss.ropensci.org) if you think your issue requires a longer form discussion. 38 | 39 | ### Thanks for contributing! 40 | 41 | This contributing guide is adapted from the tidyverse contributing guide available at https://raw.githubusercontent.com/r-lib/usethis/master/inst/templates/tidy-contributing.md 42 | -------------------------------------------------------------------------------- /.github/issue_template.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
Session Info 6 | 7 | ```r 8 | 9 | ``` 10 |
11 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ## Description 10 | 11 | 12 | ## Related Issue 13 | 16 | 17 | ## Example 18 | 20 | 21 | 23 | 24 | -------------------------------------------------------------------------------- /.github/workflows/R-CMD-check.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | branches: [main, master] 8 | 9 | name: R-CMD-check 10 | 11 | jobs: 12 | R-CMD-check: 13 | runs-on: ${{ matrix.config.os }} 14 | 15 | name: ${{ matrix.config.os }} (${{ matrix.config.r }}) 16 | 17 | strategy: 18 | fail-fast: false 19 | matrix: 20 | config: 21 | - {os: macos-latest, r: 'release'} 22 | - {os: windows-latest, r: 'release'} 23 | - {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'} 24 | - {os: ubuntu-latest, r: 'release'} 25 | - {os: ubuntu-latest, r: 'oldrel-1'} 26 | 27 | env: 28 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 29 | R_KEEP_PKG_SOURCE: yes 30 | VCR_VERBOSE_ERRORS: true 31 | 32 | steps: 33 | - uses: actions/checkout@v3 34 | 35 | - uses: r-lib/actions/setup-pandoc@v2 36 | 37 | - uses: r-lib/actions/setup-r@v2 38 | with: 39 | r-version: ${{ matrix.config.r }} 40 | http-user-agent: ${{ matrix.config.http-user-agent }} 41 | use-public-rspm: true 42 | 43 | - uses: r-lib/actions/setup-r-dependencies@v2 44 | with: 45 | extra-packages: any::rcmdcheck 46 | needs: check 47 | 48 | - uses: r-lib/actions/check-r-package@v2 49 | with: 50 | upload-snapshots: true 51 | -------------------------------------------------------------------------------- /.github/workflows/R-check.yml: -------------------------------------------------------------------------------- 1 | on: [push, pull_request] 2 | 3 | name: R-check 4 | 5 | jobs: 6 | R-check: 7 | runs-on: ${{ matrix.config.os }} 8 | 9 | name: ${{ matrix.config.os }} (${{ matrix.config.r }}) 10 | 11 | strategy: 12 | fail-fast: false 13 | matrix: 14 | config: 15 | - { os: windows-latest, r: 'release'} 16 | - { os: macOS-latest, r: 'release'} 17 | # - { os: macOS-latest, r: 'devel'} 18 | - { os: ubuntu-latest, r: 'release', rspm: "https://packagemanager.rstudio.com/cran/__linux__/bionic/latest"} 19 | 20 | env: 21 | R_REMOTES_NO_ERRORS_FROM_WARNINGS: true 22 | RSPM: ${{ matrix.config.rspm }} 23 | VCR_VERBOSE_ERRORS: true 24 | 25 | steps: 26 | - uses: actions/checkout@v2 27 | 28 | - uses: r-lib/actions/setup-r@v2 29 | with: 30 | r-version: ${{ matrix.config.r }} 31 | 32 | - uses: r-lib/actions/setup-pandoc@v1 33 | 34 | - name: Query dependencies 35 | run: | 36 | install.packages('remotes') 37 | saveRDS(remotes::dev_package_deps(dependencies = TRUE), ".github/depends.Rds", version = 2) 38 | writeLines(sprintf("R-%i.%i", getRversion()$major, getRversion()$minor), ".github/R-version") 39 | shell: Rscript {0} 40 | 41 | - name: Cache R packages 42 | if: runner.os != 'Windows' 43 | uses: actions/cache@v3 44 | with: 45 | path: ${{ env.R_LIBS_USER }} 46 | key: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-2-${{ hashFiles('.github/depends.Rds') }} 47 | restore-keys: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-2- 48 | 49 | - name: install macOS system dependencies 50 | if: runner.os == 'macOS' 51 | continue-on-error: true 52 | run: | 53 | brew install pkg-config gdal udunits proj netcdf 54 | 55 | - name: Install system dependencies 56 | if: runner.os == 'Linux' 57 | env: 58 | RHUB_PLATFORM: linux-x86_64-ubuntu-gcc 59 | run: | 60 | sudo apt update 61 | sudo apt install -y --no-install-recommends \ 62 | gdal-bin \ 63 | libgdal-dev \ 64 | libproj-dev \ 65 | netcdf-bin 66 | 67 | - name: Install dependencies 68 | run: | 69 | remotes::install_deps(dependencies = TRUE) 70 | remotes::install_cran(c("rcmdcheck", "taxize")) 71 | shell: Rscript {0} 72 | 73 | - name: Session info 74 | run: | 75 | options(width = 100) 76 | pkgs <- installed.packages()[, "Package"] 77 | sessioninfo::session_info(pkgs, include_base = TRUE) 78 | shell: Rscript {0} 79 | 80 | - name: Check 81 | env: 82 | _R_CHECK_CRAN_INCOMING_: false 83 | run: rcmdcheck::rcmdcheck(args = c("--no-manual", "--as-cran"), error_on = "warning", check_dir = "check") 84 | shell: Rscript {0} 85 | 86 | - name: Show testthat output 87 | if: always() 88 | run: find check -name 'testthat.Rout*' -exec cat '{}' \; || true 89 | shell: bash 90 | 91 | - name: Upload check results 92 | if: failure() 93 | uses: actions/upload-artifact@v4 94 | with: 95 | name: ${{ runner.os }}-r${{ matrix.config.r }}-results 96 | path: check 97 | 98 | - name: Test coverage 99 | if: matrix.config.os == 'ubuntu-22.04' && matrix.config.r == 'release' 100 | run: | 101 | Rscript -e 'remotes::install_cran("covr")' -e 'covr::codecov(token = "${{secrets.CODECOV_TOKEN}}")' 102 | -------------------------------------------------------------------------------- /.github/workflows/test-coverage.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | branches: [main, master] 8 | 9 | name: test-coverage 10 | 11 | jobs: 12 | test-coverage: 13 | runs-on: ubuntu-latest 14 | env: 15 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 16 | 17 | steps: 18 | - uses: actions/checkout@v3 19 | 20 | - uses: r-lib/actions/setup-r@v2 21 | with: 22 | use-public-rspm: true 23 | 24 | - uses: r-lib/actions/setup-r-dependencies@v2 25 | with: 26 | extra-packages: any::covr 27 | needs: coverage 28 | 29 | - name: Test coverage 30 | run: | 31 | covr::codecov( 32 | quiet = FALSE, 33 | clean = FALSE, 34 | install_path = file.path(Sys.getenv("RUNNER_TEMP"), "package") 35 | ) 36 | shell: Rscript {0} 37 | 38 | - name: Show testthat output 39 | if: always() 40 | run: | 41 | ## -------------------------------------------------------------------- 42 | find ${{ runner.temp }}/package -name 'testthat.Rout*' -exec cat '{}' \; || true 43 | shell: bash 44 | 45 | - name: Upload test results 46 | if: failure() 47 | uses: actions/upload-artifact@v4 48 | with: 49 | name: coverage-test-failures 50 | path: ${{ runner.temp }}/package 51 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .DS_Store 5 | revdep/checks.noindex 6 | revdep/data.sqlite 7 | revdep/library.noindex 8 | rerddap-*.tar.gz 9 | rerddap_*.tar.gz 10 | vignettes/cache 11 | -------------------------------------------------------------------------------- /CRAN-RELEASE: -------------------------------------------------------------------------------- 1 | This package was submitted to CRAN on 2021-11-19. 2 | Once it is accepted, delete this file and tag the release (commit abe2409). 3 | -------------------------------------------------------------------------------- /CRAN-SUBMISSION: -------------------------------------------------------------------------------- 1 | Version: 1.2.0 2 | Date: 2024-12-11 15:17:03 UTC 3 | SHA: 9662d98df70233be405dedcd27534c721b9136f5 4 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: rerddap 2 | Title: General Purpose Client for 'ERDDAP™' Servers 3 | Description: General purpose R client for 'ERDDAP™' servers. Includes 4 | functions to search for 'datasets', get summary information on 5 | 'datasets', and fetch 'datasets', in either 'csv' or 'netCDF' format. 6 | 'ERDDAP™' information: 7 | . 8 | Version: 1.2.1 9 | Date: 2025-03-19 10 | License: MIT + file LICENSE 11 | Authors@R: c( 12 | person("Scott", "Chamberlain", role = "aut"), 13 | person("Ben", "Tupper", role = "ctb"), 14 | person("Salvador Jesús Fernández", "Bejarano", role = "ctb"), 15 | person("Roy", "Mendelssohn", role = c("cre", "ctb"), 16 | email = "roy.mendelssohn@noaa.gov") 17 | ) 18 | URL: https://docs.ropensci.org/rerddap/, https://github.com/ropensci/rerddap 19 | BugReports: https://github.com/ropensci/rerddap/issues 20 | LazyData: true 21 | Depends: R (>= 4.00) 22 | Roxygen: list(markdown = TRUE) 23 | Encoding: UTF-8 24 | Language: en-US 25 | Imports: 26 | crul (>= 0.7.4), 27 | dplyr (>= 0.5.0), 28 | data.table (>= 1.12.0), 29 | digest, 30 | hoardr (>= 0.5.2), 31 | jsonlite (>= 1.6), 32 | lubridate, 33 | methods, 34 | nanoparquet, 35 | ncdf4 (>= 1.16), 36 | tibble, 37 | utils, 38 | xml2 (>= 1.2.0) 39 | Suggests: 40 | knitr, 41 | rmarkdown 42 | RoxygenNote: 7.3.2 43 | VignetteBuilder: knitr 44 | X-schema.org-applicationCategory: Climate 45 | X-schema.org-keywords: earth, science, climate, precipitation, temperature, storm, buoy, NOAA 46 | X-schema.org-isPartOf: https://ropensci.org 47 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | YEAR: 2021 2 | COPYRIGHT HOLDER: Scott Chamberlain 3 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | Copyright (c) 2021 Scott Chamberlain 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | PACKAGE := $(shell grep '^Package:' DESCRIPTION | sed -E 's/^Package:[[:space:]]+//') 2 | RSCRIPT = Rscript --no-init-file 3 | 4 | vign: 5 | cd vignettes;\ 6 | ${RSCRIPT} -e "Sys.setenv(NOT_CRAN='true'); knitr::knit('rerddap.Rmd.og', output = 'rerddap.Rmd')";\ 7 | cd .. 8 | 9 | #vign_using_rerddap: 10 | # cd vignettes;\ 11 | # ${RSCRIPT} -e "Sys.setenv(NOT_CRAN='true'); knitr::knit('Using_rerddap.Rmd.og', output = 'Using_rerddap.Rmd')";\ 12 | # cd .. 13 | 14 | test: 15 | ${RSCRIPT} -e 'library(methods); devtools::test()' 16 | 17 | doc: 18 | @mkdir -p man 19 | ${RSCRIPT} -e "library(methods); devtools::document()" 20 | 21 | eg: 22 | ${RSCRIPT} -e "devtools::run_examples(run = TRUE)" 23 | 24 | install: doc build 25 | R CMD INSTALL . && rm *.tar.gz 26 | 27 | build: 28 | R CMD build . 29 | 30 | check: build 31 | _R_CHECK_CRAN_INCOMING_=FALSE R CMD check --as-cran --no-manual `ls -1tr ${PACKAGE}*gz | tail -n1` 32 | @rm -f `ls -1tr ${PACKAGE}*gz | tail -n1` 33 | @rm -rf ${PACKAGE}.Rcheck 34 | 35 | check_windows: 36 | ${RSCRIPT} -e "devtools::check_win_devel(); devtools::check_win_release()" 37 | 38 | readme: 39 | ${RSCRIPT} -e "knitr::knit('README.Rmd')" 40 | 41 | # No real targets! 42 | .PHONY: all test doc install 43 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | S3method(as.info,character) 4 | S3method(as.info,info) 5 | S3method(browse,character) 6 | S3method(browse,default) 7 | S3method(browse,griddap_csv) 8 | S3method(browse,griddap_nc) 9 | S3method(browse,info) 10 | S3method(browse,tabledap) 11 | S3method(cache_delete,character) 12 | S3method(cache_delete,griddap_csv) 13 | S3method(cache_delete,griddap_nc) 14 | S3method(cache_delete,list) 15 | S3method(cache_delete,tabledap) 16 | S3method(cache_details,character) 17 | S3method(cache_details,default) 18 | S3method(cache_details,griddap_csv) 19 | S3method(cache_details,griddap_nc) 20 | S3method(cache_details,list) 21 | S3method(cache_details,tabledap) 22 | S3method(print,ed_search) 23 | S3method(print,ed_search_adv) 24 | S3method(print,griddap_csv) 25 | S3method(print,griddap_nc) 26 | S3method(print,info) 27 | S3method(print,rerddap_cache) 28 | S3method(print,rerddap_cache_info) 29 | S3method(print,tabledap) 30 | export(as.info) 31 | export(browse) 32 | export(cache_delete) 33 | export(cache_delete_all) 34 | export(cache_details) 35 | export(cache_info) 36 | export(cache_list) 37 | export(cache_setup) 38 | export(convert_time) 39 | export(convert_units) 40 | export(disk) 41 | export(ed_datasets) 42 | export(ed_search) 43 | export(ed_search_adv) 44 | export(eurl) 45 | export(fipscounty) 46 | export(global_search) 47 | export(griddap) 48 | export(info) 49 | export(key_words) 50 | export(memory) 51 | export(servers) 52 | export(tabledap) 53 | export(version) 54 | importFrom(crul,HttpClient) 55 | importFrom(data.table,rbindlist) 56 | importFrom(digest,digest) 57 | importFrom(dplyr,as_data_frame) 58 | importFrom(dplyr,bind_rows) 59 | importFrom(hoardr,hoard) 60 | importFrom(jsonlite,fromJSON) 61 | importFrom(ncdf4,nc_close) 62 | importFrom(ncdf4,nc_open) 63 | importFrom(ncdf4,ncvar_get) 64 | importFrom(utils,URLencode) 65 | importFrom(utils,head) 66 | importFrom(utils,read.csv) 67 | importFrom(utils,read.delim) 68 | importFrom(xml2,read_html) 69 | importFrom(xml2,xml_find_all) 70 | importFrom(xml2,xml_find_first) 71 | importFrom(xml2,xml_text) 72 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | rerddap 1.2.1 2 | ============= 3 | 4 | * Improved "safety" of some function calls to insure graceful endings if resource not available 5 | * Updated some of the examples in the vignette 6 | 7 | rerddap 1.2.0 8 | ============= 9 | * tabledap() requests can now be downloaded as a parquet file, making for a much smaller download 10 | * units have been added to tabledap() output as attributes 11 | * griddap() bug fixed when a coordinate has a very large value, such as for some projected data. 12 | * browse() now returns the URL if base::interactive is FALSE, as the documentation states 13 | 14 | rerddap 1.1.0 15 | ============= 16 | * 'tabledap()' responses now have the datatype given in the file .dds 17 | 18 | rerddap 1.0.4 19 | ============= 20 | * fixes problem with time bounds check and "last" 21 | 22 | rerddap 1.0.3 23 | ============= 24 | * Provides exta checks on time bounds. 25 | * Fixes some typos and a mistake showing 'global_search()' in vignette 26 | 27 | 28 | 29 | rerddap 1.0.2 30 | ============= 31 | Ensure '[' and ']' properly encoded in URL 32 | 33 | 34 | rerddap 1.0.1 35 | ============= 36 | Changed default cacheing behavior and 'cache_setup()' 37 | 38 | rerddap 1.0.0 39 | ============= 40 | 41 | * griddap dataframe now uses the same coordinate names returned in 'rerddap::info()' 42 | * all grids can now be "melted" into a dataframe, not just lat-lon grids 43 | * fixed some bugs accessing some datasets not on lat-lon grid 44 | * vignette now included in package. 45 | 46 | rerddap 0.8.0 47 | ============= 48 | 49 | * Added global search function 50 | * fixed bug when dataset has a decreasing coordinate that 51 | is not latitude or longitude 52 | 53 | 54 | rerddap 0.7.6 55 | ============= 56 | 57 | ### MINOR IMPROVEMENTS 58 | 59 | * fixed a bug in dealing with trailing slashes in URLs 60 | 61 | rerddap 0.7.4 62 | ============= 63 | 64 | ### MINOR IMPROVEMENTS 65 | 66 | * fix a broken test 67 | 68 | rerddap 0.7.0 69 | ============= 70 | 71 | ### MINOR IMPROVEMENTS 72 | 73 | * vignettes only on package documentation site now (#87) 74 | * `server()` (to fetch known ERDDAP server URLs) now uses the list maintained by `irishmarineinstitute/awesome-erddap` on GitHub (#86) 75 | * better error handling for `griddap()`: if no dimension arguments passed, we error saying so (and no http requests made); in addition, if a dataset is passed to `griddap()`, to which the output of `info()` was also passed, then we can check if the dataset has griddap data or not, and fail saying so if not (#91) 76 | * `griddap()` and `tabledap()`: if `info()` output passed to these two funcitons, we will now use the url within that info output, and use a message telling the user we are doing so; now you don't have to set the url if you pass info output (#92) 77 | 78 | 79 | rerddap 0.6.5 80 | ============= 81 | 82 | ### BUG FIXES 83 | 84 | * fix a `convert_units` test that was failing because remote service had changed the response 85 | 86 | 87 | rerddap 0.6.4 88 | ============= 89 | 90 | ### BUG FIXES 91 | 92 | * fix to internal fxn `err_handle()` for handling http errors - ERDDAP servers changed to some weird JSON-ish type format (#85) 93 | 94 | 95 | rerddap 0.6.0 96 | ============= 97 | 98 | ### MINOR IMPROVEMENTS 99 | 100 | * change all `tibble::as_data_frame`/`tibble::data_frame` to `tibble::as_tibble` (#79) 101 | * `info()` gains new element in its output list, `base_url`, the base url for the ERDDAP server under consideration (#80) 102 | * improved docs for `griddap()` with respect to what's returned from the function (#81) 103 | * fix some test fixtures to use preserve exact bytes so that cran checks on debian clang devel don't fail (#83) 104 | * add .github files: contributing, issue template, pull request template 105 | 106 | ### BUG FIXES 107 | 108 | * fix for lat/lon parsing within `griddap()` to account for cases when min and max are reversed from the order they should be in (#78) 109 | * fix to `griddap()` to parse additioanl dimensions returned; previously we were only returning time, lat, and lon, plus one more (#82) thanks @afredstonhermann 110 | 111 | 112 | rerddap 0.5.0 113 | ============= 114 | 115 | ### MINOR IMPROVEMENTS 116 | 117 | * added new `Caching` section to package level manual file (`?rerddap`) about caching (#52) 118 | * use markdown docs in package (#75) 119 | * replace `httr` with `crul` (#54) 120 | * cache most tests with HTTP requests using `vcr` (#76) 121 | * add test for `read` parameter in `griddap()` (#47) 122 | * use default url via `eurl()`; used as default in main functions; set default url with env vars, see `?eurl` (#41) 123 | * improve handling and reporting back to user of ERDDAP server errors (#70) (#73) 124 | * change to `griddap()`: when nc format gridded datasets have latitude and longitude we "melt" them into a data.frame for easy downstream consumption. When nc format gridded datasets do not have latitude and longitude components, we do not read in the data, throw a warning saying so. You can readin the nc file yourself with the file path (#74) 125 | * for for `griddap()` to support cases in wihch lat/lon runs north to south and south to north (#68) 126 | 127 | ### BUG FIXES 128 | 129 | * `memory()` usage in `griddap()` wasn't working. fixed now (#77) 130 | 131 | 132 | rerddap 0.4.2 133 | ============= 134 | 135 | ### NEW FEATURES 136 | 137 | * Now using `hoardr` to manage caching paths and such (#60). Also 138 | now asking users where they want to cache files, either in a 139 | `rappdirs` user cache dir or a temp directory. Now on tests and examples 140 | we use temp dirs. 141 | * Related to above, new functions `cache_info()` to get cache path and 142 | number of cached files, and `cache_setup()` to set cache path. 143 | * Related to above, `cache_details()`, `cache_list()`, and `cache_delete()` 144 | lose their `cache_path` parameter - now cache path is set package wide and 145 | we use the same cache path, so no need to set in the fxn call. 146 | 147 | ### MINOR IMPROVEMENTS 148 | 149 | * Fixes to a number of `griddap()` and `tabledap()` examples to use 150 | datasets that still exist (previous examples used datasets that are no 151 | gone) 152 | 153 | 154 | rerddap 0.4.0 155 | ============= 156 | 157 | ### NEW FEATURES 158 | 159 | * New vignette added that goes in to much more depth than 160 | the original vignette (#51) thx to @rmendels 161 | * `info()` function gains new attribute `url` with the 162 | base url for the ERDDAP server used (#42) 163 | * Replaced usage of internal compact data.frame code to 164 | use `tibble` package (#45) 165 | 166 | ### MINOR IMPROVEMENTS 167 | 168 | * Added another ERDDAP server to `servers()` function (#49) 169 | * Changed base URLs for default ERDDAP server from `http` 170 | to `https` (#50) 171 | * Added note to docs for `griddap()` and `tabledap()` for how 172 | to best deal with 500 server errors (#48) 173 | * Replaced all `dplyr::rbind_all` uses with `dplyr::bind_rows` (#46) 174 | 175 | 176 | rerddap 0.3.4 177 | ============= 178 | 179 | ### MINOR IMPROVEMENTS 180 | 181 | * Removed use of `ncdf` package, which has been taken off CRAN. 182 | Using `ncdf4` now for all NetCDF file manipulation. (#35) 183 | * Failing better now with custom error catching (#31) 184 | * Added many internal checks for parameter inputs, warning or 185 | stopping as necessary - ERDDAP servers silently drop with no 186 | informative messages (#32) 187 | 188 | ### BUG FIXES 189 | 190 | * Using now `file.info()$size` instead of `file.size()` to be 191 | backwards compatible with R versions < 3.2 192 | 193 | 194 | rerddap 0.3.0 195 | ============= 196 | 197 | ### NEW FEATURES 198 | 199 | * Cache functions accept the outputs of `griddap()` and `tabledap()` 200 | so that the user can easily see cache details or delete the file from 201 | the cache without having to manually get the file name. (#30) 202 | 203 | ### MINOR IMPROVEMENTS 204 | 205 | * All package dependencies now use `importFrom` so we only import 206 | functions we need instead of their global namespaces. 207 | 208 | ### BUG FIXES 209 | 210 | * Fixed bug in parsing data from netcdf files, affected the 211 | `griddap()` function (#28) 212 | 213 | 214 | rerddap 0.2.0 215 | ============= 216 | 217 | ### NEW FEATURES 218 | 219 | * Added a suite of functions to manage local cached files (#17) 220 | 221 | ### MINOR IMPROVEMENTS 222 | 223 | * Added new ERDDAP server to list of servers in the `servers()` function (#21) 224 | 225 | ### BUG FIXES 226 | 227 | * Fixed a few cases across a number of functions in which an empty list 228 | passed to `query` parmaeter in `httr::GET()` caused an error (#23) 229 | * Fixed retrieval of path to file written to disk by `httr::write_disk()` (#24) 230 | * `last` is a value accepted by ERDDAP servers, but internal functions 231 | weren't checking correctly, fixed now. (#25) 232 | * `as.info()` wasn't passing on the `url` parameter to the `info()` function. 233 | fixed now. (#26) 234 | 235 | 236 | rerddap 0.1.0 237 | ============= 238 | 239 | ### NEW FEATURES 240 | 241 | * released to CRAN -------------------------------------------------------------------------------- /R/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci/rerddap/429d1829eaa9371513431cbd3738c67792a46163/R/.DS_Store -------------------------------------------------------------------------------- /R/browse.R: -------------------------------------------------------------------------------- 1 | #' Browse a dataset webpage. 2 | #' 3 | #' @export 4 | #' 5 | #' @param x datasetid or an object associated with a datasetid such 6 | #' [info()], [griddap()] or [tabledap()] 7 | #' @param url A URL for an ERDDAP™ server. Default: 8 | #' https://upwell.pfeg.noaa.gov/erddap/ - See [eurl()] for 9 | #' more information 10 | #' @param ... Further args passed on to `utils::browseURL` 11 | #' (must be a named parameter) 12 | #' @return if in interactive mode, opens a URL in your default browser; 13 | #' if not, then prints the URL in the console 14 | #' @author Ben Tupper \email{btupper@@bigelow.org} 15 | #' @examples \dontrun{ 16 | #' if (interactive()) { 17 | #' # browse by dataset_id 18 | #' browse('erdATastnhday') 19 | #' 20 | #' # browse info class 21 | #' my_info <- info('erdATastnhday') 22 | #' browse(my_info) 23 | #' 24 | #' # browse tabledap class 25 | #' my_tabledap <- tabledap('erdCalCOFIlrvsiz', fields=c('latitude','longitude','larvae_size', 26 | #' 'itis_tsn'), 'time>=2011-10-25', 'time<=2011-10-31') 27 | #' browse(my_tabledap) 28 | #' }} 29 | browse <- function(x, url = eurl(), ...){ 30 | UseMethod("browse", x) 31 | } 32 | 33 | 34 | #' @export 35 | browse.character <- function(x, url = eurl(), ...){ 36 | if (missing(x)) stop("datasetid is required") 37 | uri <- sprintf(paste0(url, 'info/%s/index.html'), x) 38 | 39 | if (interactive()) { 40 | utils::browseURL(uri) 41 | } else { 42 | message("URL: ", uri) 43 | return(uri) 44 | } 45 | } 46 | 47 | #' @export 48 | browse.info <- function(x, url = eurl(), ...){ 49 | datasetid <- attr(x, "datasetid") 50 | browse(datasetid, ...) 51 | } 52 | 53 | #' @export 54 | browse.tabledap <- function(x, url = eurl(), ...){ 55 | datasetid <- attr(x, "datasetid") 56 | browse(datasetid, ...) 57 | } 58 | 59 | #' @export 60 | browse.griddap_nc <- function(x, url = eurl(), ...){ 61 | datasetid <- attr(x, "datasetid") 62 | browse(datasetid, ...) 63 | } 64 | 65 | #' @export 66 | browse.griddap_csv <- function(x, url = eurl(), ...){ 67 | datasetid <- attr(x, "datasetid") 68 | browse(datasetid, ...) 69 | } 70 | 71 | #' @export 72 | browse.default <- function(x, url = eurl(), ...){ 73 | att <- attributes(x) 74 | if (!is.null(att)) { 75 | if ('datasetid' %in% names(att)) browse(att, ...) 76 | } else { 77 | stop(sprintf("browse method not implemented for %s.", class(x)[1]), 78 | call. = FALSE) 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /R/cache_delete.R: -------------------------------------------------------------------------------- 1 | #' Delete cached files 2 | #' 3 | #' @export 4 | #' @param x File names 5 | #' @param force (logical) Should files be force deleted? Default: \code{FALSE} 6 | #' @family cache 7 | #' @examples \dontrun{ 8 | #' # delete files by name in cache 9 | #' # cache_delete('9911750294a039b8b517c8bf288978ea.csv') 10 | #' # cache_delete(c('9911750294a039b8b517c8bf288978ea.csv', 11 | #' # 'b26825b6737da13d6a52c28c8dfe690f.csv')) 12 | #' 13 | #' # You can delete from the output of griddap or tabledap fxns 14 | #' ## tabledap 15 | #' (table_res <- tabledap('erdCinpKfmBT')) 16 | #' cache_delete(table_res) 17 | #' 18 | #' ## griddap 19 | #' (out <- info('erdQMekm14day')) 20 | #' (grid_res <- griddap(out, 21 | #' time = c('2015-12-28','2016-01-01'), 22 | #' latitude = c(24, 23), 23 | #' longitude = c(88, 90) 24 | #' )) 25 | #' cache_delete(grid_res) 26 | #' } 27 | cache_delete <- function(x, force = FALSE) { 28 | UseMethod("cache_delete") 29 | } 30 | 31 | #' @export 32 | cache_delete.tabledap <- function(x, force = FALSE) { 33 | cdel(basename(attr(x, "path")), force) 34 | } 35 | 36 | #' @export 37 | cache_delete.griddap_nc <- function(x, force = FALSE) { 38 | cdel(basename(attr(x, "path")), force) 39 | } 40 | 41 | #' @export 42 | cache_delete.griddap_csv <- function(x, force = FALSE) { 43 | cdel(basename(attr(x, "path")), force) 44 | } 45 | 46 | #' @export 47 | cache_delete.list <- function(x, force = FALSE) { 48 | cdel(unlist(x), force) 49 | } 50 | 51 | #' @export 52 | cache_delete.character <- function(x, force = FALSE) { 53 | cdel(x, force) 54 | } 55 | 56 | # cache_delete helper 57 | cdel <- function(files, force = FALSE) { 58 | files <- file.path(rrcache$cache_path_get(), files) 59 | if (!all(file.exists(files))) { 60 | stop("These files don't exist or can't be found: \n", 61 | strwrap(files[!file.exists(files)], indent = 5), call. = FALSE) 62 | } 63 | unlink(files, force = force) 64 | } 65 | 66 | #' @export 67 | #' @rdname cache_delete 68 | cache_delete_all <- function(force = FALSE) { 69 | files <- list.files(rrcache$cache_path_get(), full.names = TRUE) 70 | unlink(files, force = force) 71 | } 72 | -------------------------------------------------------------------------------- /R/cache_details.R: -------------------------------------------------------------------------------- 1 | #' Get details of cached files 2 | #' 3 | #' @export 4 | #' @param x File names 5 | #' @family cache 6 | #' @details Can be used to list details for all files, both .nc and .csv 7 | #' types, or details for just individual files of class \code{tabledap}, 8 | #' \code{griddap_nc}, and \code{griddap_csv} 9 | #' @examples \dontrun{ 10 | #' # List details for all cached files 11 | #' cache_details() 12 | #' } 13 | cache_details <- function(x) { 14 | UseMethod("cache_details") 15 | } 16 | 17 | #' @export 18 | cache_details.default <- function(x) { 19 | cdetails(NULL) 20 | } 21 | 22 | #' @export 23 | cache_details.tabledap <- function(x) { 24 | cdetails(basename(attr(x, "path"))) 25 | } 26 | 27 | #' @export 28 | cache_details.griddap_nc <- function(x) { 29 | cdetails(basename(attr(x, "path"))) 30 | } 31 | 32 | #' @export 33 | cache_details.griddap_csv <- function(x) { 34 | cdetails(basename(attr(x, "path"))) 35 | } 36 | 37 | #' @export 38 | cache_details.list <- function(x) { 39 | cdetails(unlist(x)) 40 | } 41 | 42 | #' @export 43 | cache_details.character <- function(x) { 44 | cdetails(x) 45 | } 46 | 47 | # Helper fxn 48 | cdetails <- function(files = NULL) { 49 | if (is.null(files)) { 50 | files <- list.files(rrcache$cache_path_get(), full.names = TRUE) 51 | structure(lapply(files, file_info_), class = "rerddap_cache_info") 52 | } else { 53 | files <- file.path(rrcache$cache_path_get(), files) 54 | structure(lapply(files, file_info_), class = "rerddap_cache_info") 55 | } 56 | } 57 | 58 | file_info_ <- function(x) { 59 | tmp <- strsplit(x, '\\.')[[1]] 60 | ext <- tmp[length(tmp)] 61 | fs <- file.info(x)$size 62 | switch(ext, 63 | nc = { 64 | list(type = "netcdf", 65 | size = if (!is.na(fs)) getsize(fs) else NA, 66 | info = if (!is.na(fs)) ncdf_summary(x)$summary else NA 67 | ) 68 | }, 69 | csv = { 70 | list(type = "csv", 71 | size = if (!is.na(fs)) getsize(fs) else NA, 72 | info = if (!is.na(fs)) 73 | names(read.csv(x, nrows = 1, stringsAsFactors = FALSE)) else NA 74 | ) 75 | } 76 | ) 77 | } 78 | 79 | getsize <- function(x) { 80 | round(x/10 ^ 6, 3) 81 | } 82 | 83 | #' @export 84 | print.rerddap_cache_info <- function(x, ...) { 85 | cat("", sep = "\n") 86 | for (i in seq_along(x)) { 87 | cat(paste0("Type: ", x[[i]]$type), sep = "\n") 88 | cat(paste0("Size: ", x[[i]]$size, " mb"), sep = "\n") 89 | if (x[[i]]$type == "netcdf") { 90 | cat("info: ", sep = "\n") 91 | if (!any(is.na(x[[i]]$info))) { 92 | print(x[[i]]$info) 93 | } 94 | } else { 95 | cat("info: (csv columns)", sep = "\n") 96 | if (!any(is.na(x[[i]]$info))) { 97 | print(x[[i]]$info) 98 | } 99 | } 100 | cat("\n") 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /R/cache_list.R: -------------------------------------------------------------------------------- 1 | #' List cached files 2 | #' 3 | #' @export 4 | #' @family cache 5 | #' @examples \dontrun{ 6 | #' # list files in cache 7 | #' cache_list() 8 | #' 9 | #' # List info for files 10 | #' ## download some data first 11 | #' tabledap('erdCinpKfmBT') 12 | #' griddap('erdVHNchlamday', 13 | #' time = c('2015-04-01','2015-04-10'), 14 | #' latitude = c(18, 21), 15 | #' longitude = c(-120, -119) 16 | #' ) 17 | #' 18 | #' (x <- cache_list()) 19 | #' cache_details(x$nc[1]) 20 | #' cache_details(x$csv[1]) 21 | #' cache_details() 22 | #' 23 | #' # delete files by name in cache 24 | #' # cache_delete(x$nc[1]) 25 | #' # cache_delete(x$nc[2:3]) 26 | #' } 27 | cache_list <- function() { 28 | nc_files <- list.files(rrcache$cache_path_get(), pattern = ".nc") 29 | csv_files <- list.files(rrcache$cache_path_get(), pattern = ".csv") 30 | structure(list(nc = nc_files, csv = csv_files), class = "rerddap_cache") 31 | } 32 | 33 | #' @export 34 | print.rerddap_cache <- function(x, ...) { 35 | cat("", sep = "\n") 36 | cat(" NetCDF files: ", strwrap(x$nc, indent = 5), sep = "\n") 37 | cat(" CSV files: ", strwrap(x$csv, indent = 5), sep = "\n") 38 | } 39 | -------------------------------------------------------------------------------- /R/cache_paths.R: -------------------------------------------------------------------------------- 1 | get_cache_path <- function() { # nocov start 2 | path <- Sys.getenv("RERDDAP_CACHE_PATH", "") 3 | if (identical(path, "")) { 4 | path <- getOption("rerddap_cache_path") 5 | } 6 | return(path) 7 | } # nocov end 8 | -------------------------------------------------------------------------------- /R/cache_setup.R: -------------------------------------------------------------------------------- 1 | #' Setup cache path 2 | #' 3 | #' @export 4 | #' @param full_path (character) the full path to use for storing cached 5 | #' files. 6 | #' @param temp_dir (logical) if \code{TRUE} use a randomly assigned 7 | #' \code{tempdir} (and \code{full_path} is ignored), if \code{FALSE}, you 8 | #' can use \code{full_path}. 9 | #' @family cache 10 | #' @return the full cache path, a directory (character) 11 | #' @details On opening, by default a temporary directory is created for caching 12 | #' files. To have files cached elsewhere, give the full path of where to 13 | #' cache files. Adding \code{temp_dir = TRUE} will again use a temporary 14 | #' dirctory for cacheing. 15 | #' @examples \dontrun{ 16 | #' # default path 17 | #' cache_setup() 18 | #' 19 | #' # you can define your own path 20 | #' cache_setup(path = "foobar") 21 | #' 22 | #' # set a tempdir - better for programming with to avoid prompt 23 | #' cache_setup(temp_dir = TRUE) 24 | #' 25 | #' # cache info 26 | #' cache_info() 27 | #' } 28 | cache_setup <- function(full_path = NULL, temp_dir = FALSE) { 29 | if (!is.null(full_path)) rrcache$cache_path_set(full_path = full_path) 30 | if (temp_dir) rrcache$cache_path_set("rerddap", type = "tempdir") 31 | rrcache$cache_path_get() 32 | } 33 | 34 | #' @export 35 | #' @rdname cache_setup 36 | cache_info <- function() { 37 | list( 38 | path = rrcache$cache_path_get(), 39 | no_files = length(rrcache$list()) 40 | ) 41 | } 42 | -------------------------------------------------------------------------------- /R/colors.R: -------------------------------------------------------------------------------- 1 | #' cmocean colors 2 | #' The cmocean color palette by Kristen Thyng as implemented in the R package "oce" 3 | #' 4 | #' str(colors) 5 | #' List of 13 6 | #' $ viridis 7 | #' $ cdom 8 | #' $ chlorophyll 9 | #' $ density 10 | #' $ freesurface 11 | #' $ oxygen 12 | #' $ par 13 | #' $ phase 14 | #' $ salinity 15 | #' $ temperature 16 | #' $ turbidity 17 | #' $ velocity 18 | #' $ vorticity 19 | "colors" 20 | -------------------------------------------------------------------------------- /R/convert_time.R: -------------------------------------------------------------------------------- 1 | #' Convert a UDUNITS compatible time to ISO time 2 | #' 3 | #' @export 4 | #' @param n numeric; A unix time number. 5 | #' @param isoTime character; A string time representation. 6 | #' @param units character; Units to return. Default: 7 | #' "seconds since 1970-01-01T00:00:00Z" 8 | #' @param url Base URL of the ERDDAP™ server. See [eurl()] for 9 | #' more information 10 | #' @param method (character) One of local or web. Local simply uses 11 | #' [as.POSIXct()], while web method uses the ERDDAP™ time conversion service 12 | #' `/erddap/convert/time.txt` 13 | #' @param ... Curl options passed on to [crul::verb-GET] 14 | #' @details When `method = "web"` time zone is GMT/UTC 15 | #' @examples \dontrun{ 16 | #' # local conversions 17 | #' convert_time(n = 473472000) 18 | #' convert_time(isoTime = "1985-01-02T00:00:00Z") 19 | #' 20 | #' # using an ERDDAP™ web service 21 | #' convert_time(n = 473472000, method = "web") 22 | #' convert_time(isoTime = "1985-01-02T00:00:00Z", method = "web") 23 | #' } 24 | 25 | convert_time <- function(n = NULL, isoTime = NULL, 26 | units = "seconds since 1970-01-01T00:00:00Z", url = eurl(), 27 | method = "local", ...) { 28 | 29 | if (!is.null(n)) stopifnot(is.numeric(n)) 30 | if (!is.null(isoTime)) stopifnot(is.character(isoTime)) 31 | check1notboth(n, isoTime) 32 | if (method == "local") { 33 | format(as.POSIXct(rc(list(n, isoTime))[[1]], 34 | origin = "1970-01-01T00:00:00Z", tz = "UTC"), 35 | format = "%Y-%m-%dT%H:%M:%SZ", tz = "UTC") 36 | } else { 37 | args <- rc(list(n = n, isoTime = isoTime, units = units)) 38 | cli <- crul::HttpClient$new(url = file.path(pu(url), 'convert/time.txt'), 39 | opts = list(...)) 40 | # res <- cli$get(query = args) 41 | response <- tryCatch( 42 | { 43 | res <- cli$get(query = args) # Attempt to fetch 44 | }, 45 | error = function(e) { 46 | message("Curl request failed to convert time: ", e$message) 47 | quit(save = "no", status = 1) # Gracefully exit R session 48 | } 49 | ) 50 | res$raise_for_status() 51 | res$parse("UTF-8") 52 | } 53 | } 54 | 55 | depsub <- function(x) { 56 | deparse(substitute(x, env = parent.env())) 57 | } 58 | 59 | check1notboth <- function(x, y) { 60 | if (is.null(x) && is.null(y)) { 61 | stop(sprintf("One of %s or %s must be non-NULL", 62 | deparse(substitute(x)), deparse(substitute(y))), call. = FALSE) 63 | } 64 | if (!is.null(x) && !is.null(y)) { 65 | stop(sprintf("Supply only one of %s or %s", 66 | deparse(substitute(x)), deparse(substitute(y))), call. = FALSE) 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /R/convert_units.R: -------------------------------------------------------------------------------- 1 | #' Convert a CF Standard Name to/from a GCMD Science Keyword 2 | #' 3 | #' @export 4 | #' @param udunits character; A UDUNITS character string 5 | #' https://www.unidata.ucar.edu/software/udunits/ 6 | #' @param ucum character; A UCUM character string 7 | #' https://ucum.org/ucum.html 8 | #' @param url Base URL of the ERDDAP server. See [eurl()] for 9 | #' more information 10 | #' @param ... Curl options passed on to [crul::verb-GET] 11 | #' @examples \dontrun{ 12 | #' convert_units(udunits = "degree_C meter-1") 13 | #' convert_units(ucum = "Cel.m-1") 14 | #' } 15 | 16 | convert_units <- function(udunits = NULL, ucum = NULL, url = eurl(), ...) { 17 | check1notboth(udunits, ucum) 18 | args <- rc(list(UDUNITS = udunits, UCUM = ucum)) 19 | cli <- crul::HttpClient$new(url = file.path(pu(url), 'convert/units.txt'), 20 | opts = list(...)) 21 | # res <- cli$get(query = args) 22 | response <- tryCatch( 23 | { 24 | res <- cli$get(query = args) # Attempt to fetch 25 | }, 26 | error = function(e) { 27 | message("Curl request failed to convert units: ", e$message) 28 | quit(save = "no", status = 1) # Gracefully exit R session 29 | } 30 | ) 31 | res$raise_for_status() 32 | res$parse("UTF-8") 33 | } 34 | -------------------------------------------------------------------------------- /R/default-url.R: -------------------------------------------------------------------------------- 1 | #' Default ERDDAP server URL 2 | #' 3 | #' @details default url is https://upwell.pfeg.noaa.gov/erddap/ 4 | #' 5 | #' You can set a default using an environment variable so you 6 | #' don't have to pass anything to the URL parameter in your 7 | #' function calls. 8 | #' 9 | #' In your .Renviron file or similar set a URL for the environment 10 | #' variable `RERDDAP_DEFAULT_URL`, like 11 | #' `RERDDAP_DEFAULT_URL=https://upwell.pfeg.noaa.gov/erddap/` 12 | #' 13 | #' It's important that you include a trailing slash in your URL 14 | #' 15 | #' @export 16 | #' @examples 17 | #' eurl() 18 | #' Sys.setenv(RERDDAP_DEFAULT_URL = "https://google.com") 19 | #' Sys.getenv("RERDDAP_DEFAULT_URL") 20 | #' eurl() 21 | #' Sys.unsetenv("RERDDAP_DEFAULT_URL") 22 | #' eurl() 23 | eurl <- function() { 24 | def_url <- "https://upwell.pfeg.noaa.gov/erddap/" 25 | url <- Sys.getenv("RERDDAP_DEFAULT_URL", "") 26 | if (identical(url, "")) return(def_url) 27 | url <- check_url(url) 28 | return(url) 29 | } 30 | 31 | check_url <- function(x) { 32 | # check if has scheme or not 33 | if (!grepl("https?://", x)) stop("Not a proper url") 34 | # add trailing slash if not present 35 | if (!grepl("\\/$", x)) paste0(x, "/") else x 36 | } 37 | -------------------------------------------------------------------------------- /R/fipscounty.R: -------------------------------------------------------------------------------- 1 | #' Convert a FIPS County Code to/from a County Name 2 | #' 3 | #' @export 4 | #' @param county character; A county name. 5 | #' @param code numeric; A FIPS code. 6 | #' @param url A URL for an ERDDAP™ server. Default: 7 | #' https://upwell.pfeg.noaa.gov/erddap/ - See [eurl()] for 8 | #' more information 9 | #' @param ... Curl options passed on to [crul::verb-GET] 10 | #' @examples \dontrun{ 11 | #' fipscounty(code = "06053") 12 | #' fipscounty(county = "CA, Monterey") 13 | #' fipscounty(county = "OR, Multnomah") 14 | #' } 15 | 16 | fipscounty <- function(county = NULL, code = NULL, url = eurl(), ...){ 17 | either_or_fips(county, code) 18 | args <- rc(list(county = county, code = code)) 19 | cli <- crul::HttpClient$new(url = file.path(pu(url), 'convert/fipscounty.txt'), 20 | opts = list(...)) 21 | # res <- cli$get(query = args) 22 | response <- tryCatch( 23 | { 24 | res <- cli$get(query = args) # Attempt to fetch 25 | }, 26 | error = function(e) { 27 | message("Curl request failed to get FIPS country code: ", e$message) 28 | quit(save = "no", status = 1) # Gracefully exit R session 29 | } 30 | ) 31 | res$raise_for_status() 32 | res$parse("UTF-8") 33 | } 34 | 35 | either_or_fips <- function(county, code) { 36 | if (!xor(!is.null(county), !is.null(code))) { 37 | stop("Provide either county or code, not both", call. = FALSE) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /R/global_search.R: -------------------------------------------------------------------------------- 1 | #' @title global_search 2 | #' @description Search for ERDDAP tabledap or griddap datasets from a list 3 | #' of ERDDAP servers based on search terms. 4 | #' @param query (character) Search terms 5 | #' @param server_list (list of character) List of ERDDAP servers to search 6 | #' @param which_service (character) One of tabledep or griddap. 7 | #' @return If successful a dataframe wih columns: 8 | #' \itemize{ 9 | #' \item title - the dataset title 10 | #' \item dataset_id - the datasetid on that ERDDAP server 11 | #' \item url - base url of dataset ERDDAP server 12 | #' } 13 | #' if urls are valid, no match is found, will return no match found 14 | #' else returns error message 15 | #' @details Uses the 'reddap' function ed_search() to search over 16 | #' the list of servers 17 | #' @examples 18 | #' # get list of servers know by 19 | #' # https://irishmarineinstitute.github.io/awesome-erddap 20 | #' # e_servers <- servers()$url 21 | #' # select a couple to search 22 | #' # e_servers <- e_servers[c(1, 40)] 23 | #' # to meet CRAN time limits will only search 1 place 24 | #' e_servers <- "https://coastwatch.pfeg.noaa.gov/erddap/" 25 | #' test_query <- 'NOAA/NCDC Blended Monthly' 26 | #' query_results <- global_search(test_query, e_servers, "griddap") 27 | #' @seealso 28 | #' \code{\link[crul]{HttpClient}} 29 | #' @rdname global_search 30 | #' @export 31 | global_search <- function(query, server_list, which_service) { 32 | # check that input is of correct type 33 | check_arg(query, "character") 34 | check_arg(server_list, "character") 35 | check_arg(which_service, "character") 36 | which_service <- match.arg(which_service, c("tabledap","griddap"), FALSE) 37 | search_url <- list() 38 | for (iserv in seq(1, length(server_list))) { 39 | # set which server 40 | my_serv <- server_list[iserv] 41 | good_url <- TRUE 42 | # will do two tests on the server 43 | # First is if erddap is not in URL 44 | test_url <- grepl('erddap', my_serv, fixed = TRUE) 45 | if (!test_url) { # erddap not in url 46 | print(paste('server URL ', my_serv), ' does not contain "erddap"') 47 | print('will be removed from server list') 48 | good_url <- FALSE 49 | } 50 | # test if URL reachable 51 | if (good_url) { 52 | test_url <- crul::HttpClient$new(my_serv) 53 | test_url_head <- try(test_url$head(), silent = TRUE) 54 | if (suppressWarnings(class(test_url_head)[1] == 'try-error')) { 55 | print(paste(' server URL', my_serv, ' not responding')) 56 | good_url <- FALSE 57 | } 58 | } 59 | # good URL, responding, make query 60 | if (good_url){ 61 | temp_list <- try(ed_search(query = query, url = my_serv, 62 | which = which_service), 63 | silent = TRUE) 64 | class_error <- suppressWarnings(class(temp_list)[1] == 'try-error') 65 | if(!class_error) { 66 | temp_list <- temp_list$info 67 | temp_names <- names(temp_list) 68 | temp_list$url <- rep(my_serv, nrow(temp_list)) 69 | names(temp_list) <- c(temp_names, 'url') 70 | search_url <- rbind(search_url, temp_list) 71 | } 72 | } 73 | } 74 | if(length(search_url) == 0) { 75 | print('no search results found') 76 | return('no search results found') 77 | } else { 78 | return(search_url) 79 | } 80 | } 81 | 82 | -------------------------------------------------------------------------------- /R/grid.R: -------------------------------------------------------------------------------- 1 | #' Get ERDDAP™ gridded data 2 | #' 3 | #' @export 4 | #' @template griddap_params 5 | #' @template griddap_egs 6 | griddap <- function(datasetx, ..., fields = 'all', stride = 1, fmt = "nc", 7 | url = eurl(), store = disk(), read = TRUE, callopts = list()) { 8 | x <- datasetx 9 | calls <- names(sapply(match.call(), deparse))[-1] 10 | calls_vec <- "ncdf" %in% calls 11 | if (any(calls_vec)) { 12 | stop( 13 | "The parameter ncdf has been removed. We use ncdf4 package now internally", 14 | call. = FALSE) 15 | } 16 | 17 | dimargs <- list(...) 18 | if (length(dimargs) == 0) stop("no dimension arguments passed, see ?griddap") 19 | if (inherits(x, "info")) { 20 | url <- x$base_url 21 | message("info() output passed to x; setting base url to: ", url) 22 | } else { 23 | x <- as.info(x, url) 24 | } 25 | if (attr(x, "type") != "griddap") 26 | stop("datasetid '", attr(x, "datasetid"), "' not of type griddap") 27 | check_dims(dimargs, x) 28 | if (!is.null(dimargs$time)) { 29 | check_time_range(dimargs, x) 30 | } 31 | check_lat_text(dimargs) 32 | check_lon_text(dimargs) 33 | dimargs <- fix_dims(dimargs, .info = x) 34 | check_lon_data_range(dimargs, x) 35 | check_lat_data_range(dimargs, x) 36 | d <- attr(x, "datasetid") 37 | var <- field_handler(fields, x$variables$variable_name) 38 | dims <- dimvars(x) 39 | store <- toggle_store(fmt, store) 40 | if (all(var == "none")) { 41 | args <- paste0(sapply(dims, function(y) { 42 | parse_args(x, y, stride, dimargs, wname = TRUE) 43 | }), collapse = ",") 44 | } else { 45 | pargs <- sapply(dims, function(y) parse_args(x, y, stride, dimargs)) 46 | args <- paste0(lapply(var, function(y) { 47 | paste0(y, paste0(pargs, collapse = "")) 48 | }), collapse = ",") 49 | } 50 | fmt <- match.arg(fmt, c("nc", "csv")) 51 | lenURL <- nchar(url) 52 | if (substr(url, lenURL, lenURL) != '/') { 53 | url <- paste0(url, '/') 54 | } 55 | resp <- erd_up_GET(url = sprintf("%sgriddap/%s.%s", url, d, fmt), dset = d, 56 | args = args, store = store, fmt = fmt, callopts) 57 | loc <- if (store$store == "disk") resp else "memory" 58 | outclasses <- switch(fmt, 59 | nc = c("griddap_nc", "nc", "list"), 60 | csv = c("griddap_csv", "csv", "data.frame")) 61 | read <- toggle_read(read, store) 62 | structure( 63 | read_all(resp, fmt, read), 64 | class = outclasses, 65 | datasetid = d, 66 | path = loc, 67 | url = url_build(sprintf("%sgriddap/%s.%s", url, d, fmt), args) 68 | ) 69 | } 70 | 71 | toggle_read <- function(x, store) { 72 | if (store$store == "memory") { 73 | return(TRUE) 74 | } else { 75 | return(x) 76 | } 77 | } 78 | 79 | toggle_store <- function(fmt, store) { 80 | if (fmt == "nc") { 81 | if (store$store == "memory") { 82 | disk() 83 | } else { 84 | store 85 | } 86 | } else { 87 | store 88 | } 89 | } 90 | 91 | #' @export 92 | print.griddap_csv <- function(x, ...) { 93 | finfo <- file_info(attr(x, "path")) 94 | cat(sprintf(" %s", attr(x, "datasetid")), sep = "\n") 95 | path <- attr(x, "path") 96 | path2 <- if (file.exists(path)) path else "" 97 | cat(sprintf(" Path: [%s]", path2), sep = "\n") 98 | if (attr(x, "path") != "memory") { 99 | cat(sprintf(" Last updated: [%s]", finfo$mtime), sep = "\n") 100 | cat(sprintf(" File size: [%s mb]", finfo$size), sep = "\n") 101 | } 102 | cat(sprintf(" Dimensions: [%s X %s]\n", NROW(x), NCOL(x)), sep = "\n") 103 | print(tibble::as_tibble(x)) 104 | } 105 | 106 | #' @export 107 | print.griddap_nc <- function(x, ...) { 108 | finfo <- file_info(attr(x, "path")) 109 | cat(sprintf(" %s", attr(x, "datasetid")), sep = "\n") 110 | path <- attr(x, "path") 111 | path2 <- if (file.exists(path)) path else "" 112 | cat(sprintf(" Path: [%s]", path2), sep = "\n") 113 | if (attr(x, "path") != "memory") { 114 | cat(sprintf(" Last updated: [%s]", finfo$mtime), sep = "\n") 115 | cat(sprintf(" File size: [%s mb]", finfo$size), sep = "\n") 116 | } 117 | cat(sprintf(" Dimensions (dims/vars): [%s X %s]", x$summary$ndims, x$summary$nvars), sep = "\n") 118 | cat(sprintf(" Dim names: %s", paste0(names(x$summary$dim), collapse = ", ")), sep = "\n") 119 | cat(sprintf(" Variable names: %s", paste0(unname(sapply(x$summary$var, "[[", "longname")), collapse = ", ")), sep = "\n") 120 | cat(sprintf(" data.frame (rows/columns): [%s X %s]", dim(x$data)[1], dim(x$data)[2]), sep = "\n\n") 121 | print(tibble::as_tibble(x$data)) 122 | } 123 | 124 | field_handler <- function(x, y){ 125 | x <- match.arg(x, c(y, "none", "all"), TRUE) 126 | if (length(x) == 1 && x == "all") { 127 | y 128 | } else if (all(x %in% y) || x == "none") { 129 | x 130 | } 131 | } 132 | 133 | check_dims <- function(dimargs, .info) { 134 | if (any(lengths(dimargs )!= 2)) { 135 | print("All coordinate bounds must be of length 2, even if same value") 136 | print("Present values are:") 137 | print(dimargs) 138 | stop("rerddap halted", call. = FALSE) 139 | } 140 | if (!all(names(dimargs) %in% dimvars(.info))) { 141 | stop(sprintf("Some input dimensions (%s) don't match those in dataset (%s)", 142 | paste0(names(dimargs), collapse = ", "), 143 | paste0(dimvars(.info), collapse = ", ")), call. = FALSE) 144 | } 145 | } 146 | 147 | check_lon_text <- function(dimargs) { 148 | if (!is.null(dimargs$longitude)) { 149 | if (any(sapply(dimargs$longitude, class) == "character")) { 150 | txt <- dimargs$longitude[sapply(dimargs$longitude, class) == "character"] 151 | if (!all(grepl("last", txt))) stop("Only text values allowed are 'last' & variants on that", call. = FALSE) 152 | } 153 | } 154 | } 155 | 156 | check_lat_text <- function(dimargs) { 157 | if (!is.null(dimargs$latitude)) { 158 | if (any(sapply(dimargs$latitude, class) == "character")) { 159 | txt <- dimargs$latitude[sapply(dimargs$latitude, class) == "character"] 160 | if (!all(grepl("last", txt))) stop("Only text values allowed are 'last' & variants on that", call. = FALSE) 161 | } 162 | } 163 | } 164 | 165 | is_lon_text <- function(dimargs) { 166 | if (!is.null(dimargs$longitude)) { 167 | any(sapply(dimargs$longitude, class) == "character") 168 | } else { 169 | FALSE 170 | } 171 | } 172 | 173 | is_lat_text <- function(dimargs) { 174 | if (!is.null(dimargs$latitude)) { 175 | any(sapply(dimargs$latitude, class) == "character") 176 | } else { 177 | FALSE 178 | } 179 | } 180 | 181 | check_time_range <- function(dimargs, x) { 182 | # if(!class(dimargs$time) == 'character'){ 183 | if(!is.character(dimargs$time)){ 184 | print('time must be given as character strings') 185 | print('you are passing ', paste0(class(dimargs$time))) 186 | stop('rerddap halted', call. = FALSE) 187 | } 188 | global <- x$alldata$NC_GLOBAL 189 | tt <- global[ global$attribute_name %in%c('time_coverage_end','time_coverage_start'), "value", ] 190 | tt <- rev(tt) 191 | if (!('last' %in% dimargs$time)){ 192 | if((dimargs$time[1] < tt[1]) | (dimargs$time[2] > tt[2])) { 193 | print('time bounds are out of range') 194 | print('You gave: ') 195 | print(dimargs$time) 196 | print("Dataset times are: ") 197 | print(tt) 198 | stop('rerddap halted', call. = FALSE) 199 | } 200 | } 201 | } 202 | 203 | 204 | check_lon_data_range <- function(dimargs, .info) { 205 | if (!is.null(dimargs$longitude)) { 206 | val <- .info$alldata$longitude[ .info$alldata$longitude$attribute_name == "actual_range", "value"] 207 | val2 <- as.numeric(strtrim(strsplit(val, ",")[[1]])) 208 | if (!is_lon_text(dimargs)) { 209 | if (max(dimargs$longitude) > max(val2) || min(dimargs$longitude) < min(val2)) { 210 | stop(sprintf("One or both longitude values (%s) outside data range (%s)", 211 | paste0(dimargs$longitude, collapse = ", "), 212 | paste0(val2, collapse = ", ")), call. = FALSE) 213 | } 214 | } 215 | } 216 | } 217 | 218 | check_lat_data_range <- function(dimargs, .info) { 219 | if (!is.null(dimargs$latitude)) { 220 | val <- .info$alldata$latitude[ .info$alldata$latitude$attribute_name == "actual_range", "value"] 221 | val2 <- as.numeric(strtrim(strsplit(val, ",")[[1]])) 222 | if (!is_lat_text(dimargs)) { 223 | if (max(dimargs$latitude) > max(val2) || min(dimargs$latitude) < min(val2)) { 224 | stop(sprintf("One or both latitude values (%s) outside data range (%s)", 225 | paste0(dimargs$latitude, collapse = ", "), 226 | paste0(val2, collapse = ", ")), call. = FALSE) 227 | } 228 | } 229 | } 230 | } 231 | 232 | fix_dims <- function(dimargs, .info) { 233 | for (i in seq_along(dimargs)) { 234 | tmp <- dimargs[[i]] 235 | nm <- names(dimargs[i]) 236 | tmp <- grep("last+", tmp, value = TRUE, invert = TRUE) 237 | if (nm == "time") { 238 | tmp <- as.Date(tmp) 239 | } 240 | 241 | val <- .info$alldata[[nm]][ .info$alldata[[nm]]$attribute_name == "actual_range", "value"] 242 | val2 <- as.numeric(strtrim(strsplit(val, ",")[[1]])) 243 | if (length(tmp) != 0) { 244 | if (which.min(val2) != which.min(tmp)) { 245 | dimargs[[i]] <- rev(dimargs[[i]]) 246 | } 247 | } 248 | 249 | ## new 250 | # if (nm %in% c('latitude', 'longitude')) { 251 | if (nm != 'time') { 252 | z <- unlist(strsplit(.info$alldata[[nm]]$value[1], ",")) 253 | spacing <- as.numeric(unlist(strsplit(z[3], "=")[[1]])[2]) 254 | if ((!is.na(spacing)) & (spacing < 0)) { 255 | if (!(dimargs[[i]][1] > dimargs[[i]][2])) { 256 | dimargs[[i]] <- rev(dimargs[[i]]) 257 | } 258 | } 259 | } 260 | } 261 | dimargs 262 | } 263 | 264 | parse_args <- function(.info, dim, s, dimargs, wname = FALSE){ 265 | tmp <- if (dim %in% names(dimargs)) { 266 | dimargs[[dim]] 267 | } else { 268 | if (dim == "time") { 269 | times <- c(getvar(.info, "time_coverage_start"), getvar(.info, "time_coverage_end")) 270 | sprintf('[(%s):%s:(%s)]', times[1], s, times[2]) 271 | } else { 272 | actrange <- foo(.info$alldata[[dim]], "actual_range") 273 | gsub("\\s+", "", strsplit(actrange, ",")[[1]]) 274 | } 275 | } 276 | tmp <- format(tmp, scientific = FALSE) 277 | if (length(s) > 1) { 278 | if (!length(s) == length(dimvars(.info))) stop("Your stride vector must equal length of dimension variables", call. = FALSE) 279 | names(s) <- dimvars(.info) 280 | if (!wname) { 281 | sprintf('[(%s):%s:(%s)]', tmp[1], s[[dim]], tmp[2]) 282 | } else { 283 | sprintf('%s[(%s):%s:(%s)]', dim, tmp[1], s[[dim]], tmp[2]) 284 | } 285 | } else { 286 | if (!wname) { 287 | if (length(tmp) == 1) { 288 | tmp 289 | } else { 290 | sprintf('[(%s):%s:(%s)]', tmp[1], s, tmp[2]) 291 | } 292 | } else { 293 | if (length(tmp) == 1) { 294 | tmp 295 | } else { 296 | sprintf('%s[(%s):%s:(%s)]', dim, tmp[1], s, tmp[2]) 297 | } 298 | } 299 | } 300 | } 301 | 302 | getvar <- function(x, y){ 303 | x$alldata$NC_GLOBAL[ x$alldata$NC_GLOBAL$attribute_name == y, "value"] 304 | } 305 | 306 | getvars <- function(x){ 307 | vars <- names(x$alldata) 308 | vars[ !vars %in% c("NC_GLOBAL", "time", x$variables$variable_name) ] 309 | } 310 | 311 | getallvars <- function(x){ 312 | vars <- names(x$alldata) 313 | vars[ !vars %in% "NC_GLOBAL" ] 314 | } 315 | 316 | dimvars <- function(x){ 317 | vars <- names(x$alldata) 318 | vars[ !vars %in% c("NC_GLOBAL", x$variables$variable_name) ] 319 | } 320 | 321 | erd_up_GET <- function(url, dset, args, store, fmt, callopts) { 322 | if (length(args) > 0) url <- sprintf("%s?%s", url, args) 323 | url1 <- url 324 | url1 <- gsub('\\[', '%5B', url1) 325 | url1 <- gsub('\\]', '%5D', url1) 326 | cli <- crul::HttpClient$new(url = url1, opts = callopts) 327 | if (store$store == "disk") { 328 | # store on disk 329 | key <- gen_key(url, args, fmt) 330 | if ( file.exists(file.path(store$path, key)) ) { 331 | file.path(store$path, key) 332 | } else { 333 | dir.create(store$path, showWarnings = FALSE, recursive = TRUE) 334 | if (!store$overwrite) { 335 | stop('overwrite was `FALSE`, see ?disk') 336 | } 337 | # res <- cli$get(disk = file.path(store$path, key)) 338 | response <- tryCatch( 339 | { 340 | res <- cli$get(disk = file.path(store$path, key)) # Attempt to fetch 341 | }, 342 | error = function(e) { 343 | message("Curl request failed to get file: ", e$message) 344 | quit(save = "no", status = 1) # Gracefully exit R session 345 | } 346 | ) 347 | # delete file if error, and stop message 348 | err_handle(res, store, key) 349 | # return file path 350 | res$content 351 | } 352 | } else { 353 | # read into memory, bypass disk storage 354 | # res <- cli$get() 355 | response <- tryCatch( 356 | { 357 | res <- cli$get() # Attempt to fetch 358 | }, 359 | error = function(e) { 360 | message("Curl request failed to get grid data: ", e$message) 361 | quit(save = "no", status = 1) # Gracefully exit R session 362 | } 363 | ) 364 | # if error stop message 365 | err_handle(res, store, key) 366 | # return response object 367 | res 368 | } 369 | } 370 | 371 | writepath <- function(path, d, fmt) file.path(path, paste0(d, ".", fmt)) 372 | 373 | gen_key <- function(url, args, fmt) { 374 | ky <- paste0(url, "?", args) 375 | paste0(digest::digest(ky), ".", fmt) 376 | } 377 | 378 | # libfile <- function() file.path(path.expand("~/.rerddap"), ".library") 379 | 380 | # hash_file <- function(x) { 381 | # if (!file.exists(x)) { 382 | # cat("\n", file = x) 383 | # } 384 | # } 385 | 386 | # write_key <- function(path, key) { 387 | # hash_file(path) 388 | # cat("- ", key, file = path, append = TRUE) 389 | # } 390 | 391 | file_info <- function(x) { 392 | tmp <- file.info(x) 393 | row.names(tmp) <- NULL 394 | tmp2 <- tmp[,c('mtime', 'size')] 395 | tmp2$size <- round(tmp2$size/1000000L, 2) 396 | tmp2 397 | } 398 | 399 | strextract <- function(str, pattern) regmatches(str, regexpr(pattern, str)) 400 | 401 | strtrim <- function(str) gsub("^\\s+|\\s+$", "", str) 402 | -------------------------------------------------------------------------------- /R/info.R: -------------------------------------------------------------------------------- 1 | #' Get information on an ERDDAP dataset. 2 | #' 3 | #' @export 4 | #' 5 | #' @param datasetid Dataset id 6 | #' @param url A URL for an ERDDAP server. Default: 7 | #' https://upwell.pfeg.noaa.gov/erddap/ - See [eurl()] for 8 | #' more information 9 | #' @param ... Further args passed on to [crul::verb-GET] (must be a 10 | #' named parameter) 11 | #' @param x A datasetid or the output of `info` 12 | #' @return Prints a summary of the data on return, but you can index to 13 | #' various information. 14 | #' 15 | #' The data is a list of length two with: 16 | #' 17 | #' - variables - Data.frame of variables and their types 18 | #' - alldata - List of data variables and their full attributes 19 | #' 20 | #' Where `alldata` element has many data.frame's, one for each variable, 21 | #' with metadata for that variable. E.g., for griddap dataset 22 | #' `noaa_pfeg_696e_ec99_6fa6`, `alldata` has: 23 | #' 24 | #' - NC_GLOBAL 25 | #' - time 26 | #' - latitude 27 | #' - longitude 28 | #' - sss 29 | #' 30 | #' @references https://upwell.pfeg.noaa.gov/erddap/index.html 31 | #' @examples \dontrun{ 32 | #' # grid dap datasets 33 | #' info('erdATastnhday') 34 | #' 35 | #' (out <- ed_search(query='temperature')) 36 | #' info(out$info$dataset_id[5]) 37 | #' info(out$info$dataset_id[15]) 38 | #' info(out$info$dataset_id[25]) 39 | #' info(out$info$dataset_id[150]) 40 | #' info(out$info$dataset_id[400]) 41 | #' info(out$info$dataset_id[678]) 42 | #' 43 | #' out <- info(datasetid='erdMBchla1day') 44 | #' ## See brief overview of the variables and range of possible values, if given 45 | #' out$variables 46 | #' ## all information on longitude 47 | #' out$alldata$longitude 48 | #' ## all information on chlorophyll 49 | #' out$alldata$chlorophyll 50 | #' 51 | #' # table dap datasets 52 | #' (out <- ed_search(query='temperature', which = "table")) 53 | #' info(out$info$dataset_id[1]) 54 | #' info(out$info$dataset_id[2]) 55 | #' info(out$info$dataset_id[3]) 56 | #' info(out$info$dataset_id[4]) 57 | #' 58 | #' info('erdCinpKfmBT') 59 | #' out <- info('erdCinpKfmBT') 60 | #' ## See brief overview of the variables and range of possible values, if given 61 | #' out$variables 62 | #' ## all information on longitude 63 | #' out$alldata$longitude 64 | #' ## all information on Haliotis_corrugata_Mean_Density 65 | #' out$alldata$Haliotis_corrugata_Mean_Density 66 | #' 67 | #' # use a different ERDDAP server 68 | #' ## Marine Institute (Ireland) 69 | #' info("IMI_CONN_2D", url = "http://erddap.marine.ie/erddap/") 70 | #' } 71 | 72 | info <- function(datasetid, url = eurl(), ...){ 73 | url <- sub("/$", "", url) 74 | json <- erdddap_GET(sprintf(file.path(url, 'info/%s/index.json'), datasetid), 75 | NULL, ...) 76 | colnames <- vapply(tolower(json$table$columnNames), 77 | function(z) gsub("\\s", "_", z), "", USE.NAMES = FALSE) 78 | dfs <- lapply(json$table$rows, function(x){ 79 | tmp <- data.frame(x, stringsAsFactors = FALSE) 80 | names(tmp) <- colnames 81 | tmp 82 | }) 83 | lists <- lapply(json$table$rows, stats::setNames, nm=colnames) 84 | names(lists) <- vapply(lists, function(b) b$variable_name, "", 85 | USE.NAMES = FALSE) 86 | outout <- list() 87 | for (i in seq_along(lists)) { 88 | outout[[names(lists[i])]] <- 89 | unname(lists[ names(lists) %in% names(lists)[i] ]) 90 | } 91 | 92 | df <- data.frame(rbindlist(dfs)) 93 | vars <- df[ df$row_type == 'variable', names(df) %in% 94 | c('variable_name','data_type')] 95 | actual <- vapply(split(df, df$variable_name), function(z){ 96 | tmp <- z[ z$attribute_name %in% 'actual_range' , "value"] 97 | if(length(tmp)==0) "" else tmp 98 | }, "") 99 | actualdf <- data.frame(variable_name=names(actual), 100 | actual_range=unname(actual)) 101 | vars <- merge(vars, actualdf, by="variable_name") 102 | oo <- lapply(outout, function(x) data.frame(rbindlist(x))) 103 | structure(list(variables=vars, alldata=oo, base_url=url), 104 | class="info", 105 | datasetid=datasetid, 106 | type=table_or_grid(datasetid, url)) 107 | } 108 | 109 | #' @export 110 | print.info <- function(x, ...) { 111 | global <- x$alldata$NC_GLOBAL 112 | tt <- global[ global$attribute_name %in% 113 | c('time_coverage_end','time_coverage_start'), "value", ] 114 | dims <- x$alldata[dimvars(x)] 115 | vars <- x$alldata[x$variables$variable_name] 116 | cat(sprintf(" %s", attr(x, "datasetid")), "\n") 117 | cat(paste0(" Base URL: ", x$base_url), "\n") 118 | cat(paste0(" Dataset Type: ", attr(x, "type")), "\n") 119 | if(attr(x, "type") == "griddap") cat(" Dimensions (range): ", "\n") 120 | for(i in seq_along(dims)){ 121 | if(names(dims[i]) == "time"){ 122 | cat(sprintf(" time: (%s, %s)", tt[2], tt[1]), "\n") 123 | } else { 124 | cat(sprintf(" %s: (%s)", names(dims[i]), foo(dims[[i]], 125 | "actual_range")), "\n") 126 | } 127 | } 128 | cat(" Variables: ", "\n") 129 | for(i in seq_along(vars)){ 130 | cat(sprintf(" %s:", names(vars[i])), "\n") 131 | ar <- foo(vars[[i]], "actual_range") 132 | if(!length(ar) == 0) cat(" Range:", 133 | foo(vars[[i]], "actual_range"), "\n") 134 | un <- foo(vars[[i]], "units") 135 | if(!length(un) == 0) cat(" Units:", foo(vars[[i]], "units"), "\n") 136 | } 137 | } 138 | 139 | foo <- function(x, y){ 140 | x[ x$attribute_name == y, "value"] 141 | } 142 | 143 | #' @export 144 | #' @rdname info 145 | as.info <- function(x, url) { 146 | UseMethod("as.info") 147 | } 148 | 149 | #' @export 150 | as.info.info <- function(x, url) { 151 | x 152 | } 153 | 154 | #' @export 155 | as.info.character <- function(x, url) { 156 | info(x, url) 157 | } 158 | 159 | table_or_grid <- function(datasetid, url) { 160 | url <- sub("/$", "", url) 161 | table_url <- file.path(url, 'tabledap/index.json') 162 | tab <- toghelper(table_url) 163 | if (datasetid %in% tab) "tabledap" else "griddap" 164 | } 165 | 166 | toghelper <- function(url) { 167 | out <- erdddap_GET(url, list(page = 1, itemsPerPage = 10000L)) 168 | nms <- out$table$columnNames 169 | lists <- lapply(out$table$rows, stats::setNames, nm = nms) 170 | vapply(lists, "[[", "", "Dataset ID") 171 | } 172 | -------------------------------------------------------------------------------- /R/keywords.R: -------------------------------------------------------------------------------- 1 | #' Convert a CF Standard Name to/from a GCMD Science Keyword 2 | #' 3 | #' @export 4 | #' @param cf character; A cf standard name 5 | #' http://cfconventions.org/Data/cf-standard-names/27/build/cf-standard-name-table.html 6 | #' @param gcmd character; A GCMD science keyword 7 | #' http://gcmd.gsfc.nasa.gov/learn/keyword_list.html 8 | #' @param url A URL for an ERDDAP™ server. Default: 9 | #' https://upwell.pfeg.noaa.gov/erddap/. See [eurl()] for 10 | #' more information 11 | #' @param ... Curl options passed on to [crul::verb-GET] 12 | #' @examples \dontrun{ 13 | #' key_words(cf = "air_pressure") 14 | #' cat(key_words(cf = "air_pressure")) 15 | #' 16 | #' # a different ERDDAP™ server 17 | #' # key_words(cf = "air_pressure", url = servers()$url[6]) 18 | #' } 19 | 20 | key_words <- function(cf = NULL, gcmd = NULL, url = eurl(), ...){ 21 | either_or_keywords(cf, gcmd) 22 | args <- rc(list(cf = cf, gcmd = gcmd)) 23 | cli <- crul::HttpClient$new(url = file.path(pu(url), 'convert/keywords.txt'), 24 | opts = list(...)) 25 | # res <- cli$get(query = args) 26 | response <- tryCatch( 27 | { 28 | res <- cli$get(query = args) # Attempt to fetch 29 | }, 30 | error = function(e) { 31 | message("Curl request failed on finding keyword: ", e$message) 32 | quit(save = "no", status = 1) # Gracefully exit R session 33 | } 34 | ) 35 | 36 | res$raise_for_status() 37 | res$parse("UTF-8") 38 | } 39 | 40 | either_or_keywords <- function(cf, gcmd) { 41 | if (!xor(!is.null(cf), !is.null(gcmd))) { 42 | stop("Provide either cf or gcmd, not both", call. = FALSE) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /R/ncdf_helpers.R: -------------------------------------------------------------------------------- 1 | # get metadata and data ----------------------- 2 | ncdf4_get <- function(file){ 3 | nc <- ncdf4::nc_open(file) 4 | on.exit(ncdf4::nc_close(nc)) 5 | tmp <- unclass(nc) 6 | 7 | dims <- names(nc$dim) 8 | 9 | lat_name = ifelse('lat' %in% dims, 'lat', 'latitude') 10 | lon_name = ifelse('lon' %in% dims, 'lon', 'longitude') 11 | out <- list() 12 | for (i in seq_along(dims)) { 13 | out[[dims[i]]] <- ncdf4::ncvar_get(nc, nc$dim[[dims[i]]]) 14 | } 15 | if ('time' %in% names(out)){ 16 | out$time <- sapply(out$time, convert_time) 17 | 18 | } 19 | vars <- names(nc$var) 20 | outvars <- list() 21 | for (i in seq_along(vars)) { 22 | outvars[[ vars[i] ]] <- as.vector(ncdf4::ncvar_get(nc, vars[i])) 23 | } 24 | df <- do.call("cbind.data.frame", outvars) 25 | rows <- length(outvars[[1]]) 26 | 27 | out <- out[length(out):1] 28 | meta <- expand.grid(out, stringsAsFactors = FALSE) 29 | # make data.frame 30 | alldf <- if (NROW(meta) > 0) cbind(meta, df) else df 31 | 32 | # output 33 | list(summary = tmp, data = alldf) 34 | } 35 | 36 | # get just metadata ----------------------- 37 | ncdf_summary <- function(file) { 38 | nc <- ncdf4::nc_open(file, readunlim = FALSE) 39 | tmp <- unclass(nc) 40 | on.exit(ncdf4::nc_close(nc)) 41 | list(summary = tmp, data = data.frame(NULL)) 42 | } 43 | -------------------------------------------------------------------------------- /R/on_load.R: -------------------------------------------------------------------------------- 1 | rrcache <- NULL # nocov start 2 | .onLoad <- function(libname, pkgname) { 3 | x <- hoardr::hoard() 4 | x$cache_path_set(path = 'rerddap', type = 'tempdir') 5 | rrcache <<- x 6 | } # nocov end 7 | -------------------------------------------------------------------------------- /R/rerddap-package.r: -------------------------------------------------------------------------------- 1 | #' @title rerddap 2 | #' @description General purpose R client for ERDDAP servers 3 | #' @section ERDDAP info: 4 | #' NOAA's ERDDAP service holds many datasets of interest. It's built on top of 5 | #' OPenDAP. You can search for datasets via 6 | #' [ed_search()], list datasets via [ed_datasets()], 7 | #' get information on a single dataset via [info()], then get 8 | #' data you want for either tabledap type via [tabledap()], or 9 | #' for griddap type via [griddap()] 10 | #' 11 | #' @section tabledap/griddap: 12 | #' tabledap and griddap have different interfaces to query for data, so 13 | #' [tabledap()] and [griddap()] are separated out as 14 | #' separate functions even though some of the internals are the same. In 15 | #' particular, with tabledap you can query on/subset all variables, whereas 16 | #' with gridddap, you can only query on/subset the dimension varibles (e.g., 17 | #' latitude, longitude, altitude). 18 | #' 19 | #' @section Data size: 20 | #' With griddap data via [griddap()] you can get a lot of 21 | #' data quickly. Try small searches of a dataset to start to get a sense for 22 | #' the data, then you can increase the amount of data you get. See 23 | #' [griddap()] for more details. 24 | #' 25 | #' @section Caching: 26 | #' \pkg{rerddap} by default caches the requests you make, so that if you happen to 27 | #' make the same request again, the data is restored from the cache, rather than 28 | #' having to go out and retrieve it remotely. For most applications, this is good, 29 | #' as it can speed things up when doing a lot of request in a script, and works 30 | #' because in most cases an ERDDAP request is "idempotent". This means that the 31 | #' the request will always return the same thing no matter what requests came 32 | #' before - it doesn't depend on state. However this is not true if the 33 | #' script uses either "last" in [griddap()] or "now" in [tabledap()] as these 34 | #' will return different values as time elapses and data are added to the 35 | #' datasets. While it is desirable to have ERDDAP purely idempotent, the 36 | #' "last" and "now" constructs are very helpful for people using ERDDAP 37 | #' in dashboards, webpages, regular input to models and the like, and the 38 | #' benefits far outweigh the problems. However, if you are using either "last" 39 | #' or "now" in an \pkg{rerddap} based script, you want to be very careful to 40 | #' clear the \pkg{rerddap} cache, otherwise the request will be viewed as the 41 | #' same, and the data from the last request, rather than the latest data, 42 | #' will be returned. 43 | #' 44 | #' @importFrom utils head read.csv read.delim URLencode 45 | #' @importFrom crul HttpClient 46 | #' @importFrom jsonlite fromJSON 47 | #' @importFrom data.table rbindlist 48 | #' @importFrom ncdf4 nc_open nc_close ncvar_get 49 | #' @importFrom xml2 xml_text xml_find_all read_html xml_find_first 50 | #' @importFrom dplyr as_data_frame bind_rows 51 | #' @importFrom digest digest 52 | #' @importFrom hoardr hoard 53 | #' @docType package 54 | #' @name rerddap 55 | #' @keywords internal 56 | "_PACKAGE" 57 | ## usethis namespace: start 58 | ## usethis namespace: end 59 | 60 | #' institutions 61 | #' 62 | #' @docType data 63 | #' @keywords datasets 64 | #' @format A character vector 65 | #' @name institutions 66 | NULL 67 | 68 | #' ioos_categories 69 | #' 70 | #' @docType data 71 | #' @keywords datasets 72 | #' @format A character vector 73 | #' @name ioos_categories 74 | NULL 75 | 76 | #' keywords 77 | #' 78 | #' @docType data 79 | #' @keywords datasets 80 | #' @format A character vector 81 | #' @name keywords 82 | NULL 83 | 84 | #' longnames 85 | #' 86 | #' @docType data 87 | #' @keywords datasets 88 | #' @format A character vector 89 | #' @name longnames 90 | NULL 91 | 92 | #' standardnames 93 | #' 94 | #' @docType data 95 | #' @keywords datasets 96 | #' @format A character vector 97 | #' @name standardnames 98 | NULL 99 | 100 | #' variablenames 101 | #' 102 | #' @docType data 103 | #' @keywords datasets 104 | #' @format A character vector 105 | #' @name variablenames 106 | NULL 107 | -------------------------------------------------------------------------------- /R/search.R: -------------------------------------------------------------------------------- 1 | #' Search for ERDDAP tabledep or griddap datasets 2 | #' 3 | #' @export 4 | #' 5 | #' @param query (character) Search terms 6 | #' @param page (integer) Page number 7 | #' @param page_size (integer) Results per page 8 | #' @param which (character) One of tabledep or griddap. 9 | #' @param url A URL for an ERDDAP server. Default: 10 | #' https://upwell.pfeg.noaa.gov/erddap/ - See [eurl()] for 11 | #' more information 12 | #' @param ... Curl options passed on to [crul::verb-GET] (must be 13 | #' named parameters) 14 | #' @references https://upwell.pfeg.noaa.gov/erddap/index.html 15 | #' @examples \dontrun{ 16 | #' (out <- ed_search(query='temperature')) 17 | #' out$alldata[[1]] 18 | #' (out <- ed_search(query='size')) 19 | #' out$info 20 | #' 21 | #' # List datasets 22 | #' ed_datasets('table') 23 | #' ed_datasets('grid') 24 | #' 25 | #' # use a different ERDDAP server 26 | #' ## Marine Institute (Ireland) 27 | #' ed_search("temperature", url = "http://erddap.marine.ie/erddap/") 28 | #' } 29 | 30 | ed_search <- function(query, page=NULL, page_size=NULL, which='griddap', 31 | url = eurl(), ...){ 32 | 33 | check_arg(query, "character") 34 | check_arg(page, "numeric") 35 | check_arg(page_size, "numeric") 36 | which <- match.arg(which, c("tabledap","griddap"), FALSE) 37 | args <- rc(list(searchFor = query, page = page, itemsPerPage = page_size)) 38 | json <- erdddap_GET(paste0(url, 'search/index.json'), args, ...) 39 | colnames <- vapply( 40 | tolower(json$table$columnNames), function(z) gsub("\\s", "_", z), 41 | "", USE.NAMES = FALSE) 42 | dfs <- lapply(json$table$rows, function(x){ 43 | names(x) <- colnames 44 | x <- x[c('title','dataset_id')] 45 | data.frame(x, stringsAsFactors = FALSE) 46 | }) 47 | df <- data.frame(rbindlist(dfs)) 48 | lists <- lapply(json$table$rows, stats::setNames, nm = colnames) 49 | df$gd <- vapply( 50 | lists, function(x) { 51 | if (x$griddap == "") "tabledap" else "griddap" 52 | }, character(1)) 53 | df <- df[ df$gd == which, -3 ] 54 | row.names(df) <- NULL 55 | res <- list(info = df, alldata = lists) 56 | structure(res, class = "ed_search") 57 | } 58 | 59 | #' @export 60 | print.ed_search <- function(x, ...){ 61 | print(tibble::as_tibble(x$info)) 62 | } 63 | 64 | #' @export 65 | #' @rdname ed_search 66 | ed_datasets <- function(which = 'tabledap', url = eurl()){ 67 | which <- match.arg(which, c("tabledap","griddap"), FALSE) 68 | url <- sprintf('%s%s/index.json', url, which) 69 | out <- erdddap_GET(url, list(page = 1, itemsPerPage = 10000L)) 70 | nms <- out$table$columnNames 71 | lists <- lapply(out$table$rows, stats::setNames, nm = nms) 72 | tibble::as_tibble(rbindlist(lapply(lists, data.frame, 73 | stringsAsFactors = FALSE))) 74 | } 75 | -------------------------------------------------------------------------------- /R/search_adv.R: -------------------------------------------------------------------------------- 1 | #' Advanced search for ERDDAP tabledep or griddap datasets 2 | #' 3 | #' @export 4 | #' 5 | #' @param query (character) Search terms 6 | #' @param page (integer) Page number. Default: 1 7 | #' @param page_size (integer) Results per page: Default: 1000 8 | #' @param protocol (character) One of any (default), tabledep or griddap 9 | #' @param cdm_data_type (character) One of grid, other, point, profile, 10 | #' timeseries, timeseriesprofile, trajectory, trajectoryprofile 11 | #' @param institution (character) An institution. See the dataset 12 | #' `institutions` 13 | #' @param ioos_category (character) An ioos category See the dataset 14 | #' `ioos_categories` 15 | #' @param keywords (character) A keywords. See the dataset `keywords` 16 | #' @param long_name (character) A long name. See the dataset `longnames` 17 | #' @param standard_name (character) A standar dname. See the dataset 18 | #' `standardnames` 19 | #' @param variableName (character) A variable name. See the dataset 20 | #' `variablenames` 21 | #' @param minLat,maxLat (numeric) Minimum and maximum latitude, between -90 22 | #' and 90 23 | #' @param minLon,maxLon (numeric) Minimum and maximum longitude. Some datasets 24 | #' have longitude values within -180 to 180, others use 0 to 360. If you 25 | #' specify min and max Longitude within -180 to 180 (or 0 to 360), ERDDAP will 26 | #' only find datasets that match the values you specify. Consider doing one 27 | #' search: longitude -180 to 360, or two searches: longitude -180 to 180, 28 | #' and 0 to 360. 29 | #' @param minTime,maxTime (numeric/character) Minimum and maximum time. Time 30 | #' string with the format "yyyy-MM-ddTHH:mm:ssZ, (e.g., 2009-01-21T23:00:00Z). 31 | #' If you specify something, you must include at least yyyy-MM-dd; you can 32 | #' omit Z, :ss, :mm, :HH, and T. Always use UTC (GMT/Zulu) time. Or specify 33 | #' the number of seconds since 1970-01-01T00:00:00Z. 34 | #' @param url A URL for an ERDDAP server. Default: 35 | #' https://upwell.pfeg.noaa.gov/erddap/ - See [eurl()] for 36 | #' more information 37 | #' @param ... Curl options passed on to [crul::verb-GET] (must be 38 | #' named parameters) 39 | #' @references https://upwell.pfeg.noaa.gov/erddap/index.html 40 | #' @examples \dontrun{ 41 | #' ed_search_adv(query = 'temperature') 42 | #' ed_search_adv(query = 'temperature', protocol = "griddap") 43 | #' ed_search_adv(query = 'temperature', protocol = "tabledap") 44 | #' ed_search_adv(maxLat = 63, minLon = -107, maxLon = -87, minLat = 50, 45 | #' protocol = "griddap") 46 | #' ed_search_adv(maxLat = 63, minLon = -107, maxLon = -87, minLat = 50, 47 | #' protocol = "tabledap") 48 | #' ed_search_adv(minTime = "2010-01-01T00:00:00Z", 49 | #' maxTime="2010-02-01T00:00:00Z") 50 | #' (out <- ed_search_adv(maxLat = 63, minLon = -107, maxLon = -87, minLat = 50, 51 | #' minTime = "2010-01-01T00:00:00Z", 52 | #' maxTime="2010-02-01T00:00:00Z")) 53 | #' out$alldata[[1]] 54 | #' ed_search_adv(variableName = 'upwelling') 55 | #' ed_search_adv(query = 'upwelling', protocol = "tabledap") 56 | #' 57 | #' # use a different URL 58 | #' ed_search_adv(query = 'temperature', url = servers()$url[6]) 59 | #' } 60 | 61 | ed_search_adv <- function(query = NULL, page = 1, page_size = 1000, 62 | protocol = NULL, cdm_data_type = NULL, institution = NULL, 63 | ioos_category = NULL, keywords = NULL, long_name = NULL, standard_name = NULL, 64 | variableName = NULL, maxLat = NULL, minLon = NULL, maxLon = NULL, 65 | minLat = NULL, minTime = NULL, maxTime = NULL, url = eurl(), ...) { 66 | 67 | check_args(query, page, page_size, protocol, cdm_data_type, institution, 68 | ioos_category, keywords, long_name, standard_name, variableName, 69 | maxLat, minLon, maxLon, minLat, minTime, maxTime) 70 | args <- rc(list( 71 | searchFor = query, page = page, itemsPerPage = page_size, 72 | protocol = protocol, cdm_data_type = cdm_data_type, 73 | institution = institution, ioos_category = ioos_category, 74 | keywords = keywords, long_name = long_name, 75 | standard_name = standard_name, 76 | variableName = variableName, maxLat = maxLat, minLon = minLon, 77 | maxLon = maxLon, minLat = minLat, minTime = minTime, maxTime = maxTime)) 78 | json <- erdddap_GET(paste0(url, 'search/advanced.json'), args, ...) 79 | colnames <- vapply( 80 | tolower(json$table$columnNames), function(z) gsub("\\s", "_", z), "", 81 | USE.NAMES = FALSE 82 | ) 83 | dfs <- lapply(json$table$rows, function(x){ 84 | names(x) <- colnames 85 | x <- x[c('title', 'dataset_id')] 86 | dplyr::as_tibble(x) 87 | }) 88 | df <- dplyr::bind_rows(dfs) 89 | lists <- lapply(json$table$rows, stats::setNames, nm = colnames) 90 | res <- list(info = df, alldata = lists) 91 | structure(res, class = "ed_search_adv") 92 | } 93 | 94 | #' @export 95 | print.ed_search_adv <- function(x, ...){ 96 | cat(sprintf("%s results, showing first 20", nrow(x$info)), "\n") 97 | print(head(x$info, n = 20)) 98 | } 99 | 100 | check_args <- function(query, page, page_size, protocol, cdm_data_type, 101 | institution, ioos_category, keywords, long_name, standard_name, 102 | variableName, maxLat, minLon, maxLon, minLat, minTime, maxTime) { 103 | 104 | check_arg(query, "character") 105 | check_arg(page, "numeric") 106 | check_arg(page_size, "numeric") 107 | check_arg(protocol, "character") 108 | check_arg(cdm_data_type, "character") 109 | check_arg(institution, "character") 110 | check_arg(ioos_category, "character") 111 | check_arg(keywords, "character") 112 | check_arg(long_name, "character") 113 | check_arg(standard_name, "character") 114 | check_arg(variableName, "character") 115 | check_arg(maxLat, "numeric") 116 | check_arg(minLon, "numeric") 117 | check_arg(maxLon, "numeric") 118 | check_arg(minLat, "numeric") 119 | check_arg(minTime, c("numeric", "character")) 120 | check_arg(maxTime, c("numeric", "character")) 121 | } 122 | 123 | check_arg <- function(x, class) { 124 | var <- deparse(substitute(x)) 125 | if (!is.null(x)) { 126 | if (!class(x) %in% class) { 127 | if (length(class) > 1) class <- paste0(class, collapse = ", ") 128 | stop(var, " not of class ", class, call. = FALSE) 129 | } 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /R/servers.R: -------------------------------------------------------------------------------- 1 | #' ERDDAP™ server URLS and other info 2 | #' 3 | #' @export 4 | #' @param ... curl options passed on to [crul::verb-GET] 5 | #' @return data.frame with 3 columns: 6 | #' 7 | #' - name (character): ERDDAP™ name 8 | #' - url (character): ERDDAP™ url 9 | #' - public (logical): whether it's public or not 10 | #' 11 | #' @examples \dontrun{ 12 | #' servers() 13 | #' } 14 | servers <- function(...) { 15 | surl <- "https://irishmarineinstitute.github.io/awesome-erddap/erddaps.json" 16 | # tt <- crul::HttpClient$new(url = surl, opts = list(...))$get() 17 | response <- tryCatch( 18 | { 19 | tt <- crul::HttpClient$new(url = surl, opts = list(...))$get() # Attempt to fetch 20 | }, 21 | error = function(e) { 22 | message("Curl request failed to get server list: ", e$message) 23 | quit(save = "no", status = 1) # Gracefully exit R session 24 | } 25 | ) 26 | tt$raise_for_status() 27 | tibble::as_tibble(jsonlite::fromJSON(tt$parse("UTF-8"))) 28 | } 29 | -------------------------------------------------------------------------------- /R/utils.R: -------------------------------------------------------------------------------- 1 | #' Options for saving ERDDAP datasets. 2 | #' 3 | #' @export 4 | #' @param path Path to store files in. A directory, not a file. 5 | #' Default: the root cache path, see \code{\link{cache_setup}} 6 | #' @param overwrite (logical) Overwrite an existing file of the same name? 7 | #' Default: \code{TRUE} 8 | disk <- function(path = NULL, overwrite = TRUE) { 9 | if (is.null(path)) { 10 | # path is NULL - use cache path already setup 11 | path <- rrcache$cache_path_get() 12 | } 13 | list(store = "disk", path = path, overwrite = overwrite) 14 | } 15 | 16 | #' @export 17 | #' @rdname disk 18 | memory <- function() list(store = "memory") 19 | -------------------------------------------------------------------------------- /R/version.R: -------------------------------------------------------------------------------- 1 | #' Get ERDDAP™ version 2 | #' 3 | #' @export 4 | #' @param url A URL for an ERDDAP™ server. Default: 5 | #' https://upwell.pfeg.noaa.gov/erddap/ - See [eurl()] for 6 | #' more information 7 | #' @param ... Curl options passed on to [crul::verb-GET] 8 | #' @examples \dontrun{ 9 | #' version() 10 | #' ss <- servers() 11 | #' version(ss$url[2]) 12 | #' version(ss$url[3]) 13 | #' } 14 | version <- function(url = eurl(), ...){ 15 | cli <- crul::HttpClient$new(url = file.path(pu(url), 'version'), 16 | opts = list(...)) 17 | # res <- cli$get() 18 | response <- tryCatch( 19 | { 20 | res <- cli$get() # Attempt to fetch 21 | }, 22 | error = function(e) { 23 | message("Curl request failed to get version: ", e$message) 24 | quit(save = "no", status = 1) # Gracefully exit R session 25 | } 26 | ) 27 | res$raise_for_status() 28 | sub("\n", "", res$parse("UTF-8")) 29 | } 30 | -------------------------------------------------------------------------------- /R/zzz.r: -------------------------------------------------------------------------------- 1 | # Function to get UTM zone from a single longitude and latitude pair 2 | # originally from David LeBauer I think 3 | # @param lon Longitude, in decimal degree style 4 | # @param lat Latitude, in decimal degree style 5 | long2utm <- function(lon, lat) { 6 | if (56 <= lat & lat < 64) { 7 | if (0 <= lon & lon < 3) { 31 } else 8 | if (3 <= lon & lon < 12) { 32 } else { NULL } 9 | } else { 10 | if (72 <= lat) { 11 | if (0 <= lon & lon < 9) { 31 } else 12 | if (9 <= lon & lon < 21) { 33 } else 13 | if (21 <= lon & lon < 33) { 35 } else 14 | if (33 <= lon & lon < 42) { 37 } else { NULL } 15 | } 16 | (floor((lon + 180)/6) %% 60) + 1 17 | } 18 | } 19 | 20 | rc <- function(l) Filter(Negate(is.null), l) 21 | 22 | read_csv <- function(x){ 23 | tmp <- read.csv(x, header = FALSE, sep = ",", stringsAsFactors = FALSE, 24 | skip = 3) 25 | nmz <- names(read.csv(x, header = TRUE, sep = ",", stringsAsFactors = FALSE, 26 | skip = 1, nrows = 1)) 27 | names(tmp) <- tolower(nmz) 28 | tmp 29 | } 30 | 31 | read_data <- function(x, nrows = -1){ 32 | if (inherits(x, "HttpResponse")) { 33 | x <- x$parse("UTF-8") 34 | tmp <- read.csv(text = x, header = FALSE, sep = ",", 35 | stringsAsFactors = FALSE, skip = 2, nrows = nrows) 36 | nmz <- names(read.csv(text = x, header = TRUE, sep = ",", 37 | stringsAsFactors = FALSE, nrows = 1)) 38 | } else { 39 | tmp <- read.csv(x, header = FALSE, sep = ",", stringsAsFactors = FALSE, 40 | skip = 2, nrows = nrows) 41 | nmz <- names(read.csv(x, header = TRUE, sep = ",", 42 | stringsAsFactors = FALSE, nrows = 1)) 43 | } 44 | stats::setNames(tmp, tolower(nmz)) 45 | } 46 | 47 | read_all <- function(x, fmt, read) { 48 | switch(fmt, 49 | csv = { 50 | if (read) { 51 | read_data(x) 52 | } else { 53 | read_data(x, 10) 54 | } 55 | }, 56 | nc = { 57 | if (read) { 58 | ncdf4_get(x) 59 | } else { 60 | ncdf_summary(x) 61 | } 62 | } 63 | ) 64 | } 65 | 66 | read_table <- function(x, fmt){ 67 | if (inherits(x, "HttpResponse")) { 68 | txt <- gsub('\n$', '', x$parse("UTF-8")) 69 | read.csv(text = txt, sep = ",", stringsAsFactors = FALSE, 70 | blank.lines.skip = FALSE)[-1, , drop = FALSE] 71 | } else { 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 | } 78 | } 79 | } 80 | 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 | 90 | pu <- function(x) sub("/$|//$", "", x) 91 | 92 | strect <- function (str, pattern) regmatches(str, regexpr(pattern, str)) 93 | 94 | err_handle <- function(x, store, key) { 95 | if (x$status_code > 201) { 96 | tt <- if (store$store == "disk") x$content else x$parse("UTF-8") 97 | html <- tryCatch(read_html(tt), error = function(e) e) 98 | if (inherits(html, "error")) { 99 | mssg <- tt 100 | } else { 101 | mssg <- xml_text(xml_find_all(html, '//body//p[text()[contains(., "Error") or contains(., "error")]]')) %||% "" 102 | mssg <- sub("Message\\s", "", mssg) 103 | if (!nzchar(mssg)) { 104 | mssg <- strect(xml_text(xml_find_first(html, '//body')), "Query error.+") 105 | } 106 | } 107 | if (store$store != "memory") unlink(file.path(store$path, key)) 108 | stop(paste0(mssg, collapse = "\n\n"), call. = FALSE) 109 | } 110 | } 111 | 112 | err_handle2 <- function(x) { 113 | if (x$status_code > 201) { 114 | tt <- x$parse("UTF-8") 115 | mssg <- xml_text(xml_find_all(read_html(tt), "//h1")) 116 | stop(paste0(mssg, collapse = "\n\n"), call. = FALSE) 117 | } 118 | } 119 | 120 | erdddap_GET <- function(url, args = NULL, ...) { 121 | cli <- crul::HttpClient$new(url = url, opts = list(...)) 122 | # tt <- cli$get(query = args) 123 | response <- tryCatch( 124 | { 125 | tt <- cli$get(query = args) # Attempt to fetch 126 | }, 127 | error = function(e) { 128 | message("Curl request failed: ", e$message) 129 | quit(save = "no", status = 1) # Gracefully exit R session 130 | } 131 | ) 132 | 133 | err_handle2(tt) 134 | stopifnot(tt$response_headers$`content-type` == 'application/json;charset=UTF-8') 135 | out <- tt$parse("UTF-8") 136 | jsonlite::fromJSON(out, FALSE) 137 | } 138 | 139 | url_build <- function(url, args = NULL) { 140 | if (is.null(args)) return(url) 141 | paste0(url, "?", args) 142 | } 143 | 144 | `%||%` <- function (x, y) { 145 | if (is.null(x) || length(x) == 0) y else x 146 | } 147 | -------------------------------------------------------------------------------- /README.Rmd: -------------------------------------------------------------------------------- 1 | rerddap 2 | ===== 3 | 4 | ```{r echo=FALSE} 5 | knitr::opts_chunk$set( 6 | comment = "#>", 7 | collapse = TRUE, 8 | warning = FALSE, 9 | message = FALSE 10 | ) 11 | ``` 12 | 13 | [![cran checks](https://badges.cranchecks.info/worst/rerddap.svg)](https://cran.r-project.org/web/checks/check_results_rerddap.html) 14 | [![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) 15 | [![codecov.io](https://codecov.io/github/ropensci/rerddap/coverage.svg?branch=master)](https://codecov.io/github/ropensci/rerddap?branch=master) 16 | [![rstudio mirror downloads](https://cranlogs.r-pkg.org/badges/rerddap)](https://github.com/r-hub/cranlogs.app) 17 | [![cran version](https://www.r-pkg.org/badges/version/rerddap)](https://cran.r-project.org/package=rerddap) 18 | 19 | 20 | `rerddap` is a general purpose R client for working with ERDDAP servers. 21 | 22 | Package Docs: 23 | 24 | ## Installation 25 | 26 | From CRAN 27 | 28 | ```{r eval=FALSE} 29 | install.packages("rerddap") 30 | ``` 31 | 32 | Or development version from GitHub 33 | 34 | ```{r eval=FALSE} 35 | remotes::install_github("ropensci/rerddap") 36 | ``` 37 | 38 | ```{r} 39 | library("rerddap") 40 | ``` 41 | 42 | Some users may experience an installation error, stating to install 1 or more 43 | packages, e.g., you may need `DBI`, in which case do, for example, 44 | `install.packages("DBI")` before installing `rerddap`. 45 | 46 | ## Background 47 | 48 | ERDDAP is a server built on top of OPenDAP, which serves some NOAA data. You can get gridded data (griddap ()), which lets you query from gridded datasets, or table data (tabledap ()) which lets you query from tabular datasets. In terms of how we interface with them, there are similarities, but some differences too. We try to make a similar interface to both data types in `rerddap`. 49 | 50 | ## NetCDF 51 | 52 | `rerddap` supports NetCDF format, and is the default when using the `griddap()` function. NetCDF is a binary file format, and will have a much smaller footprint on your disk than csv. The binary file format means it's harder to inspect, but the `ncdf4` package makes it easy to pull data out and write data back into a NetCDF file. Note the the file extension for NetCDF files is `.nc`. Whether you choose NetCDF or csv for small files won't make much of a difference, but will with large files. 53 | 54 | ## Caching 55 | 56 | Data files downloaded are cached in a single directory on your machine determined by the `hoardr` package. When you use `griddap()` or `tabledap()` functions, we construct a MD5 hash from the base URL, and any query parameters - this way each query is separately cached. Once we have the hash, we look in the cache directory for a matching hash. If there's a match we use that file on disk - if no match, we make a http request for the data to the ERDDAP server you specify. 57 | 58 | ## ERDDAP servers 59 | 60 | You can get a data.frame of ERDDAP servers using the function `servers()`. Most I think serve some kind of NOAA data, but there are a few that aren't NOAA data. If you know of more ERDDAP servers, send a pull request, or let us know. 61 | 62 | ## Meta 63 | 64 | * Please [report any issues or bugs](https://github.com/ropensci/rerddap/issues). 65 | * License: MIT 66 | * Get citation information for `rerddap` in R doing `citation(package = 'rerddap')` 67 | * Please note that this package is released with a [Contributor Code of Conduct](https://ropensci.org/code-of-conduct/). By contributing to this project, you agree to abide by its terms. 68 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | rerddap 2 | ===== 3 | 4 | 5 | 6 | [![cran checks](https://badges.cranchecks.info/worst/rerddap.svg)](https://cran.r-project.org/web/checks/check_results_rerddap.html) 7 | [![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) 8 | [![codecov.io](https://codecov.io/github/ropensci/rerddap/coverage.svg?branch=master)](https://codecov.io/github/ropensci/rerddap?branch=master) 9 | [![rstudio mirror downloads](https://cranlogs.r-pkg.org/badges/rerddap)](https://github.com/r-hub/cranlogs.app) 10 | [![cran version](https://www.r-pkg.org/badges/version/rerddap)](https://cran.r-project.org/package=rerddap) 11 | 12 | 13 | `rerddap` is a general purpose R client for working with ERDDAP servers. 14 | 15 | Package Docs: 16 | 17 | ## Installation 18 | 19 | From CRAN 20 | 21 | 22 | ```r 23 | install.packages("rerddap") 24 | ``` 25 | 26 | Or development version from GitHub 27 | 28 | 29 | ```r 30 | remotes::install_github("ropensci/rerddap") 31 | ``` 32 | 33 | 34 | ```r 35 | library("rerddap") 36 | ``` 37 | 38 | Some users may experience an installation error, stating to install 1 or more 39 | packages, e.g., you may need `DBI`, in which case do, for example, 40 | `install.packages("DBI")` before installing `rerddap`. 41 | 42 | ## Background 43 | 44 | ERDDAP is a server built on top of OPenDAP, which serves some NOAA data. You can get gridded data (griddap ()), which lets you query from gridded datasets, or table data (tabledap ()) which lets you query from tabular datasets. In terms of how we interface with them, there are similarities, but some differences too. We try to make a similar interface to both data types in `rerddap`. 45 | 46 | ## NetCDF 47 | 48 | `rerddap` supports NetCDF format, and is the default when using the `griddap()` function. NetCDF is a binary file format, and will have a much smaller footprint on your disk than csv. The binary file format means it's harder to inspect, but the `ncdf4` package makes it easy to pull data out and write data back into a NetCDF file. Note the the file extension for NetCDF files is `.nc`. Whether you choose NetCDF or csv for small files won't make much of a difference, but will with large files. 49 | 50 | ## Caching 51 | 52 | Data files downloaded are cached in a single directory on your machine determined by the `hoardr` package. When you use `griddap()` or `tabledap()` functions, we construct a MD5 hash from the base URL, and any query parameters - this way each query is separately cached. Once we have the hash, we look in the cache directory for a matching hash. If there's a match we use that file on disk - if no match, we make a http request for the data to the ERDDAP server you specify. 53 | 54 | ## ERDDAP servers 55 | 56 | You can get a data.frame of ERDDAP servers using the function `servers()`. Most I think serve some kind of NOAA data, but there are a few that aren't NOAA data. If you know of more ERDDAP servers, send a pull request, or let us know. 57 | 58 | ## Meta 59 | 60 | * Please [report any issues or bugs](https://github.com/ropensci/rerddap/issues). 61 | * License: MIT 62 | * Get citation information for `rerddap` in R doing `citation(package = 'rerddap')` 63 | * Please note that this package is released with a [Contributor Code of Conduct](https://ropensci.org/code-of-conduct/). By contributing to this project, you agree to abide by its terms. 64 | -------------------------------------------------------------------------------- /_pkgdown.yml: -------------------------------------------------------------------------------- 1 | reference: 2 | - title: rerddap Package Description 3 | contents: 4 | - rerddap-package 5 | 6 | - title: Search 7 | desc: > 8 | Functions to search for ERDDAP servers as well as to search 9 | ERDDAP for datasets whose metadata match the given search. 10 | contents: 11 | - ed_search 12 | - ed_search_adv 13 | - global_search 14 | - servers 15 | 16 | - title: Obtain basic dataset metadata 17 | 18 | desc: > 19 | Obtain the basic dataset metadata to help in subsetting and downloading. 20 | contents: 21 | - info 22 | - browse 23 | 24 | 25 | - title: Subset and Download Data 26 | 27 | desc: > 28 | Functions to subset and download ERDDAP grids and tables. 29 | contents: 30 | - griddap 31 | - tabledap 32 | 33 | - title: Optional Settings for Data Download 34 | 35 | desc: > 36 | Optional settings for functions that subset and download ERDDAP grids and tables. 37 | contents: 38 | - disk 39 | - eurl 40 | - memory 41 | 42 | - title: Cache Handling 43 | 44 | desc: > 45 | Functions for dealing with 'rerddap' cache. 46 | contents: 47 | - cache_delete 48 | - cache_delete_all 49 | - cache_details 50 | - cache_info 51 | - cache_list 52 | - cache_setup 53 | 54 | - title: Various ERDDAP Based Utilities 55 | 56 | desc: > 57 | Various ERDDAP based utilities for converting parameters. 58 | contents: 59 | - convert_time 60 | - convert_units 61 | - fipscounty 62 | - key_words 63 | - version 64 | 65 | - title: Datasets 66 | 67 | desc: > 68 | Datasets used in the the functions nd vignette. 69 | contents: 70 | - colors 71 | - institutions 72 | - ioos_categories 73 | - keywords 74 | - longnames 75 | - standardnames 76 | - variablenames 77 | 78 | -------------------------------------------------------------------------------- /codemeta.json: -------------------------------------------------------------------------------- 1 | { 2 | "@context": "https://doi.org/10.5063/schema/codemeta-2.0", 3 | "@type": "SoftwareSourceCode", 4 | "identifier": "rerddap", 5 | "description": "General purpose R client for 'ERDDAP™' servers. Includes functions to search for 'datasets', get summary information on 'datasets', and fetch 'datasets', in either 'csv' or 'netCDF' format. 'ERDDAP™' information: .", 6 | "name": "rerddap: General Purpose Client for 'ERDDAP™' Servers", 7 | "relatedLink": "https://docs.ropensci.org/rerddap/", 8 | "codeRepository": "https://github.com/ropensci/rerddap", 9 | "issueTracker": "https://github.com/ropensci/rerddap/issues", 10 | "license": "https://spdx.org/licenses/MIT", 11 | "version": "1.2.0", 12 | "programmingLanguage": { 13 | "@type": "ComputerLanguage", 14 | "name": "R", 15 | "url": "https://r-project.org" 16 | }, 17 | "runtimePlatform": "R version 4.4.2 (2024-10-31)", 18 | "provider": { 19 | "@id": "https://cran.r-project.org", 20 | "@type": "Organization", 21 | "name": "Comprehensive R Archive Network (CRAN)", 22 | "url": "https://cran.r-project.org" 23 | }, 24 | "author": [ 25 | { 26 | "@type": "Person", 27 | "givenName": "Scott", 28 | "familyName": "Chamberlain" 29 | } 30 | ], 31 | "contributor": [ 32 | { 33 | "@type": "Person", 34 | "givenName": "Ben", 35 | "familyName": "Tupper" 36 | }, 37 | { 38 | "@type": "Person", 39 | "givenName": "Salvador Jesús Fernández", 40 | "familyName": "Bejarano" 41 | }, 42 | { 43 | "@type": "Person", 44 | "givenName": "Roy", 45 | "familyName": "Mendelssohn", 46 | "email": "roy.mendelssohn@noaa.gov" 47 | } 48 | ], 49 | "maintainer": [ 50 | { 51 | "@type": "Person", 52 | "givenName": "Roy", 53 | "familyName": "Mendelssohn", 54 | "email": "roy.mendelssohn@noaa.gov" 55 | } 56 | ], 57 | "softwareSuggestions": [ 58 | { 59 | "@type": "SoftwareApplication", 60 | "identifier": "knitr", 61 | "name": "knitr", 62 | "provider": { 63 | "@id": "https://cran.r-project.org", 64 | "@type": "Organization", 65 | "name": "Comprehensive R Archive Network (CRAN)", 66 | "url": "https://cran.r-project.org" 67 | }, 68 | "sameAs": "https://CRAN.R-project.org/package=knitr" 69 | }, 70 | { 71 | "@type": "SoftwareApplication", 72 | "identifier": "rmarkdown", 73 | "name": "rmarkdown", 74 | "provider": { 75 | "@id": "https://cran.r-project.org", 76 | "@type": "Organization", 77 | "name": "Comprehensive R Archive Network (CRAN)", 78 | "url": "https://cran.r-project.org" 79 | }, 80 | "sameAs": "https://CRAN.R-project.org/package=rmarkdown" 81 | } 82 | ], 83 | "softwareRequirements": { 84 | "1": { 85 | "@type": "SoftwareApplication", 86 | "identifier": "R", 87 | "name": "R", 88 | "version": ">= 4.00" 89 | }, 90 | "2": { 91 | "@type": "SoftwareApplication", 92 | "identifier": "crul", 93 | "name": "crul", 94 | "version": ">= 0.7.4", 95 | "provider": { 96 | "@id": "https://cran.r-project.org", 97 | "@type": "Organization", 98 | "name": "Comprehensive R Archive Network (CRAN)", 99 | "url": "https://cran.r-project.org" 100 | }, 101 | "sameAs": "https://CRAN.R-project.org/package=crul" 102 | }, 103 | "3": { 104 | "@type": "SoftwareApplication", 105 | "identifier": "dplyr", 106 | "name": "dplyr", 107 | "version": ">= 0.5.0", 108 | "provider": { 109 | "@id": "https://cran.r-project.org", 110 | "@type": "Organization", 111 | "name": "Comprehensive R Archive Network (CRAN)", 112 | "url": "https://cran.r-project.org" 113 | }, 114 | "sameAs": "https://CRAN.R-project.org/package=dplyr" 115 | }, 116 | "4": { 117 | "@type": "SoftwareApplication", 118 | "identifier": "data.table", 119 | "name": "data.table", 120 | "version": ">= 1.12.0", 121 | "provider": { 122 | "@id": "https://cran.r-project.org", 123 | "@type": "Organization", 124 | "name": "Comprehensive R Archive Network (CRAN)", 125 | "url": "https://cran.r-project.org" 126 | }, 127 | "sameAs": "https://CRAN.R-project.org/package=data.table" 128 | }, 129 | "5": { 130 | "@type": "SoftwareApplication", 131 | "identifier": "digest", 132 | "name": "digest", 133 | "provider": { 134 | "@id": "https://cran.r-project.org", 135 | "@type": "Organization", 136 | "name": "Comprehensive R Archive Network (CRAN)", 137 | "url": "https://cran.r-project.org" 138 | }, 139 | "sameAs": "https://CRAN.R-project.org/package=digest" 140 | }, 141 | "6": { 142 | "@type": "SoftwareApplication", 143 | "identifier": "hoardr", 144 | "name": "hoardr", 145 | "version": ">= 0.5.2", 146 | "provider": { 147 | "@id": "https://cran.r-project.org", 148 | "@type": "Organization", 149 | "name": "Comprehensive R Archive Network (CRAN)", 150 | "url": "https://cran.r-project.org" 151 | }, 152 | "sameAs": "https://CRAN.R-project.org/package=hoardr" 153 | }, 154 | "7": { 155 | "@type": "SoftwareApplication", 156 | "identifier": "jsonlite", 157 | "name": "jsonlite", 158 | "version": ">= 1.6", 159 | "provider": { 160 | "@id": "https://cran.r-project.org", 161 | "@type": "Organization", 162 | "name": "Comprehensive R Archive Network (CRAN)", 163 | "url": "https://cran.r-project.org" 164 | }, 165 | "sameAs": "https://CRAN.R-project.org/package=jsonlite" 166 | }, 167 | "8": { 168 | "@type": "SoftwareApplication", 169 | "identifier": "lubridate", 170 | "name": "lubridate", 171 | "provider": { 172 | "@id": "https://cran.r-project.org", 173 | "@type": "Organization", 174 | "name": "Comprehensive R Archive Network (CRAN)", 175 | "url": "https://cran.r-project.org" 176 | }, 177 | "sameAs": "https://CRAN.R-project.org/package=lubridate" 178 | }, 179 | "9": { 180 | "@type": "SoftwareApplication", 181 | "identifier": "methods", 182 | "name": "methods" 183 | }, 184 | "10": { 185 | "@type": "SoftwareApplication", 186 | "identifier": "nanoparquet", 187 | "name": "nanoparquet", 188 | "provider": { 189 | "@id": "https://cran.r-project.org", 190 | "@type": "Organization", 191 | "name": "Comprehensive R Archive Network (CRAN)", 192 | "url": "https://cran.r-project.org" 193 | }, 194 | "sameAs": "https://CRAN.R-project.org/package=nanoparquet" 195 | }, 196 | "11": { 197 | "@type": "SoftwareApplication", 198 | "identifier": "ncdf4", 199 | "name": "ncdf4", 200 | "version": ">= 1.16", 201 | "provider": { 202 | "@id": "https://cran.r-project.org", 203 | "@type": "Organization", 204 | "name": "Comprehensive R Archive Network (CRAN)", 205 | "url": "https://cran.r-project.org" 206 | }, 207 | "sameAs": "https://CRAN.R-project.org/package=ncdf4" 208 | }, 209 | "12": { 210 | "@type": "SoftwareApplication", 211 | "identifier": "tibble", 212 | "name": "tibble", 213 | "provider": { 214 | "@id": "https://cran.r-project.org", 215 | "@type": "Organization", 216 | "name": "Comprehensive R Archive Network (CRAN)", 217 | "url": "https://cran.r-project.org" 218 | }, 219 | "sameAs": "https://CRAN.R-project.org/package=tibble" 220 | }, 221 | "13": { 222 | "@type": "SoftwareApplication", 223 | "identifier": "utils", 224 | "name": "utils" 225 | }, 226 | "14": { 227 | "@type": "SoftwareApplication", 228 | "identifier": "xml2", 229 | "name": "xml2", 230 | "version": ">= 1.2.0", 231 | "provider": { 232 | "@id": "https://cran.r-project.org", 233 | "@type": "Organization", 234 | "name": "Comprehensive R Archive Network (CRAN)", 235 | "url": "https://cran.r-project.org" 236 | }, 237 | "sameAs": "https://CRAN.R-project.org/package=xml2" 238 | }, 239 | "SystemRequirements": null 240 | }, 241 | "applicationCategory": "Climate", 242 | "isPartOf": "https://ropensci.org", 243 | "keywords": ["earth", "science", "climate", "precipitation", "temperature", "storm", "buoy", "NOAA", "rstats", "erddap", "noaa-data", "api-client", "r", "r-package"], 244 | "fileSize": "3018.425KB", 245 | "releaseNotes": "https://github.com/ropensci/rerddap/blob/master/NEWS.md", 246 | "readme": "https://github.com/ropensci/rerddap/blob/master/README.md", 247 | "contIntegration": ["https://github.com/ropensci/rerddap/actions/workflows/R-CMD-check.yaml", "https://codecov.io/github/ropensci/rerddap?branch=master"] 248 | } 249 | -------------------------------------------------------------------------------- /cran-comments.md: -------------------------------------------------------------------------------- 1 | ## Test environments 2 | 3 | * local macOS install, R 4.4.3 4 | * github actions - mac, windows, ubuntu 5 | * r-universe mac, windows, linux 6 | * macOS Builder (devtools::check_mac_release()) 7 | * win-builder (devel and release - devtools::check_win_*()) 8 | 9 | ## R CMD check results 10 | 11 | OK from all checks 12 | 13 | ## Reverse dependencies 14 | 15 | * I am maintainer of plotdap and rerddapXtracto - they check out 16 | 17 | --- 18 | 19 | 20 | Thanks! 21 | Roy Mendelssohn 22 | -------------------------------------------------------------------------------- /data/colors.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci/rerddap/429d1829eaa9371513431cbd3738c67792a46163/data/colors.rda -------------------------------------------------------------------------------- /data/institutions.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci/rerddap/429d1829eaa9371513431cbd3738c67792a46163/data/institutions.rda -------------------------------------------------------------------------------- /data/ioos_categories.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci/rerddap/429d1829eaa9371513431cbd3738c67792a46163/data/ioos_categories.rda -------------------------------------------------------------------------------- /data/keywords.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci/rerddap/429d1829eaa9371513431cbd3738c67792a46163/data/keywords.rda -------------------------------------------------------------------------------- /data/longnames.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci/rerddap/429d1829eaa9371513431cbd3738c67792a46163/data/longnames.rda -------------------------------------------------------------------------------- /data/standardnames.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci/rerddap/429d1829eaa9371513431cbd3738c67792a46163/data/standardnames.rda -------------------------------------------------------------------------------- /data/variablenames.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci/rerddap/429d1829eaa9371513431cbd3738c67792a46163/data/variablenames.rda -------------------------------------------------------------------------------- /inst/extdata/MWsstd1day.nc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci/rerddap/429d1829eaa9371513431cbd3738c67792a46163/inst/extdata/MWsstd1day.nc -------------------------------------------------------------------------------- /man-roxygen/griddap_egs.R: -------------------------------------------------------------------------------- 1 | #' @examples \dontrun{ 2 | #' # single variable dataset 3 | #' ## You can pass in the outpu of a call to info 4 | #' (out <- info('erdVHNchlamday')) 5 | #' ## Or, pass in a dataset id 6 | #' (res <- griddap('erdVHNchlamday', 7 | #' time = c('2015-04-01','2015-04-10'), 8 | #' latitude = c(18, 21), 9 | #' longitude = c(-120, -119) 10 | #' )) 11 | #' 12 | #' # multi-variable dataset 13 | #' (out <- info('erdQMekm14day')) 14 | #' (res <- griddap(out, 15 | #' time = c('2015-12-28','2016-01-01'), 16 | #' latitude = c(24, 23), 17 | #' longitude = c(88, 90) 18 | #' )) 19 | #' (res <- griddap(out, time = c('2015-12-28','2016-01-01'), 20 | #' latitude = c(24, 23), longitude = c(88, 90), fields = 'mod_current')) 21 | #' (res <- griddap(out, time = c('2015-12-28','2016-01-01'), 22 | #' latitude = c(24, 23), longitude = c(88, 90), fields = 'mod_current', 23 | #' stride = c(1,2,1,2))) 24 | #' (res <- griddap(out, time = c('2015-12-28','2016-01-01'), 25 | #' latitude = c(24, 23), longitude = c(88, 90), 26 | #' fields = c('mod_current','u_current'))) 27 | #' 28 | #' 29 | #' # Write to memory (within R), or to disk 30 | #' (out <- info('erdQSwindmday')) 31 | #' ## disk, by default (to prevent bogging down system w/ large datasets) 32 | #' ## you can also pass in path and overwrite options to disk() 33 | #' (res <- griddap(out, 34 | #' time = c('2006-07-11','2006-07-20'), 35 | #' longitude = c(166, 170), 36 | #' store = disk() 37 | #' )) 38 | #' ## the 2nd call is much faster as it's mostly just the time of reading in 39 | #' ## the table from disk 40 | #' system.time( griddap(out, 41 | #' time = c('2006-07-11','2006-07-15'), 42 | #' longitude = c(10, 15), 43 | #' store = disk() 44 | #' ) ) 45 | #' system.time( griddap(out, 46 | #' time = c('2006-07-11','2006-07-15'), 47 | #' longitude = c(10, 15), 48 | #' store = disk() 49 | #' ) ) 50 | #' 51 | #' ## memory - you have to choose fmt="csv" if you use memory 52 | #' (res <- griddap("erdMBchla1day", 53 | #' time = c('2015-01-01','2015-01-03'), 54 | #' latitude = c(14, 15), 55 | #' longitude = c(125, 126), 56 | #' fmt = "csv", store = memory() 57 | #' )) 58 | #' 59 | #' ## Use ncdf4 package to parse data 60 | #' info("erdMBchla1day") 61 | #' (res <- griddap("erdMBchla1day", 62 | #' time = c('2015-01-01','2015-01-03'), 63 | #' latitude = c(14, 15), 64 | #' longitude = c(125, 126) 65 | #' )) 66 | #' 67 | #' # Get data in csv format 68 | #' ## by default, we get netcdf format data 69 | #' (res <- griddap('erdMBchla1day', 70 | #' time = c('2015-01-01','2015-01-03'), 71 | #' latitude = c(14, 15), 72 | #' longitude = c(125, 126), 73 | #' fmt = "csv" 74 | #' )) 75 | #' 76 | #' # Use a different ERDDAP server url 77 | #' ## NOAA IOOS PacIOOS 78 | #' url = "https://cwcgom.aoml.noaa.gov/erddap/" 79 | #' out <- info("miamiacidification", url = url) 80 | #' (res <- griddap(out, 81 | #' time = c('2019-11-01','2019-11-03'), 82 | #' latitude = c(15, 16), 83 | #' longitude = c(-90, -88) 84 | #' )) 85 | #' ## pass directly into griddap() - if you pass a datasetid string directly 86 | #' ## you must pass in the url or you'll be querying the default ERDDAP url, 87 | #' ## which isn't the one you want if you're not using the default ERDDAP url 88 | #' griddap("miamiacidification", url = url, 89 | #' time = c('2019-11-01','2019-11-03'), 90 | #' latitude = c(15, 16), 91 | #' longitude = c(-90, -88) 92 | #' ) 93 | #' 94 | #' # Using 'last' 95 | #' ## with time 96 | #' griddap('erdVHNchlamday', 97 | #' time = c('last-5','last'), 98 | #' latitude = c(18, 21), 99 | #' longitude = c(-120, -119) 100 | #' ) 101 | #' ## with latitude 102 | #' griddap('erdVHNchlamday', 103 | #' time = c('2015-04-01','2015-04-10'), 104 | #' latitude = c('last', 'last'), 105 | #' longitude = c(-120, -119) 106 | #' ) 107 | #' ## with longitude 108 | #' griddap('erdVHNchlamday', 109 | #' time = c('2015-04-01','2015-04-10'), 110 | #' latitude = c(18, 21), 111 | #' longitude = c('last', 'last') 112 | #' ) 113 | #' 114 | #' # datasets without lat/lon grid and with fmt=nc 115 | #' # FIXME: this dataset is gone 116 | #' # (x <- info('glos_tds_5912_ca66_3f41')) 117 | #' # res <- griddap(x, 118 | #' # time = c('2018-04-01','2018-04-10'), 119 | #' # ny = c(1, 2), 120 | #' # nx = c(3, 5) 121 | #' # ) 122 | #' ## data.frame is empty 123 | #' # res$data 124 | #' ## read in from the nc file path 125 | #' # ncdf4::nc_open(res$summary$filename) 126 | #' } 127 | -------------------------------------------------------------------------------- /man-roxygen/griddap_params.R: -------------------------------------------------------------------------------- 1 | #' @param datasetx Anything coercable to an object of class info. So the output of a 2 | #' call to \code{\link{info}}, or a datasetid, which will internally be passed 3 | #' through \code{\link{info}} 4 | #' @param ... Dimension arguments. See examples. Can be any 1 or more of the 5 | #' dimensions for the particular dataset - and the dimensions vary by dataset. 6 | #' For each dimension, pass in a vector of length two, with min and max value 7 | #' desired. at least 1 required. 8 | #' @param fields (character) Fields to return, in a character vector. 9 | #' @param stride (integer) How many values to get. 1 = get every value, 2 = get 10 | #' every other value, etc. Default: 1 (i.e., get every value) 11 | #' @param fmt (character) One of csv or nc (for netcdf). Default: nc 12 | #' @param url A URL for an ERDDAP server. Default: 13 | #' https://upwell.pfeg.noaa.gov/erddap/ - See [eurl()] for 14 | #' more information 15 | #' @param store One of \code{\link{disk}} (default) or \code{\link{memory}}. You 16 | #' can pass options to \code{\link{disk}}. Beware: if you choose \code{fmt="nc"}, 17 | #' we force \code{store=disk()} because nc files have to be written to disk. 18 | #' @param read (logical) Read data into memory or not. Does not apply when 19 | #' \code{store} parameter is set to memory (which reads data into memory). 20 | #' For large csv, or especially netcdf files, you may want to set this to 21 | #' \code{FALSE}, which simply returns a summary of the dataset - and you can 22 | #' read in data piecemeal later. Default: \code{TRUE} 23 | #' @param callopts Curl options passed on to \code{\link[crul]{verb-GET}} 24 | #' 25 | #' @return An object of class \code{griddap_csv} if csv chosen or 26 | #' \code{griddap_nc} if nc file format chosen. 27 | #' 28 | #' \itemize{ 29 | #' \item \code{griddap_csv}: a data.frame created from the downloaded csv 30 | #' data 31 | #' \item \code{griddap_nc}: a list, with slots "summary" and "data". "summary" 32 | #' is the unclassed output from \code{ncdf4::nc_open}, from which you can 33 | #' do any netcdf operations you like. "data" is a data.frame created 34 | #' from the netcdf data. the data.frame may be empty if there were problems 35 | #' parsing the netcdf data 36 | #' } 37 | #' 38 | #' Both have the attributes: datasetid (the dataset id), path (the path on file 39 | #' for the csv or nc file), url (the url requested to the ERDDAP server) 40 | #' 41 | #' If \code{read=FALSE}, the data.frame for \code{griddap_csv} 42 | #' and the data.frame in the "data" slot is empty for \code{griddap_nc} 43 | #' 44 | #' @details Details: 45 | #' 46 | #' If you run into an error like "HTTP Status 500 - There was a (temporary?) 47 | #' problem. Wait a minute, then try again.". it's likely they are hitting 48 | #' up against a size limit, and they should reduce the amount of data they 49 | #' are requesting either via space, time, or variables. Pass in 50 | #' \code{config = verbose()} to the request, and paste the URL into your 51 | #' browser to see if the output is garbled to examine if there's a problem 52 | #' with servers or this package 53 | #' 54 | #' @section Dimensions and Variables: 55 | #' ERDDAP grid dap data has this concept of dimenions vs. variables. Dimensions 56 | #' are things like time, latitude, longitude, altitude, and depth. Whereas 57 | #' variables are the measured variables, e.g., temperature, salinity, air. 58 | #' 59 | #' You can't separately adjust values for dimensions for different variables. 60 | #' So, here's how it's gonna work: 61 | #' 62 | #' Pass in lower and upper limits you want for each dimension as a vector 63 | #' (e.g., \code{c(1,2)}), or leave to defaults (i.e., don't pass anything to 64 | #' a dimension). Then pick which variables you want returned via the 65 | #' \code{fields} parameter. If you don't pass in options to the \code{fields} 66 | #' parameter, you get all variables back. 67 | #' 68 | #' To get the dimensions and variables, along with other metadata for a 69 | #' dataset, run \code{\link{info}}, and each will be shown, with their min 70 | #' and max values, and some other metadata. 71 | #' 72 | #' @section Where does the data go?: 73 | #' You can choose where data is stored. Be careful though. You can easily get a 74 | #' single file of hundreds of MB's (upper limit: 2 GB) in size with a single 75 | #' request. To the \code{store} parameter, pass \code{\link{memory}} if you 76 | #' want to store the data in memory (saved as a data.frame), or pass 77 | #' \code{\link{disk}} if you want to store on disk in a file. Note that 78 | #' \code{\link{memory}} and \code{\link{disk}} are not character strings, but 79 | #' function calls. \code{\link{memory}} does not accept any inputs, while 80 | #' \code{\link{disk}} does. Possibly will add other options, like 81 | #' \dQuote{sql} for storing in a SQL database. 82 | #' 83 | #' @section Non-lat/lon grid data: 84 | #' Some gridded datasets have latitude/longitude components, but some do not. 85 | #' When nc format gridded datasets have latitude and longitude we "melt" them into a 86 | #' data.frame for easy downstream consumption. When nc format gridded datasets do 87 | #' not have latitude and longitude components, we do not read in the data, throw 88 | #' a warning saying so. You can readin the nc file yourself with the file path. 89 | #' CSV format is not affected by this issue as CSV data is easily turned into 90 | #' a data.frame regardless of whether latitude/longitude data are present. 91 | #' 92 | #' @references https://upwell.pfeg.noaa.gov/erddap/rest.html 93 | -------------------------------------------------------------------------------- /man/browse.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/browse.R 3 | \name{browse} 4 | \alias{browse} 5 | \title{Browse a dataset webpage.} 6 | \usage{ 7 | browse(x, url = eurl(), ...) 8 | } 9 | \arguments{ 10 | \item{x}{datasetid or an object associated with a datasetid such 11 | \code{\link[=info]{info()}}, \code{\link[=griddap]{griddap()}} or \code{\link[=tabledap]{tabledap()}}} 12 | 13 | \item{url}{A URL for an ERDDAP™ server. Default: 14 | https://upwell.pfeg.noaa.gov/erddap/ - See \code{\link[=eurl]{eurl()}} for 15 | more information} 16 | 17 | \item{...}{Further args passed on to \code{utils::browseURL} 18 | (must be a named parameter)} 19 | } 20 | \value{ 21 | if in interactive mode, opens a URL in your default browser; 22 | if not, then prints the URL in the console 23 | } 24 | \description{ 25 | Browse a dataset webpage. 26 | } 27 | \examples{ 28 | \dontrun{ 29 | if (interactive()) { 30 | # browse by dataset_id 31 | browse('erdATastnhday') 32 | 33 | # browse info class 34 | my_info <- info('erdATastnhday') 35 | browse(my_info) 36 | 37 | # browse tabledap class 38 | my_tabledap <- tabledap('erdCalCOFIlrvsiz', fields=c('latitude','longitude','larvae_size', 39 | 'itis_tsn'), 'time>=2011-10-25', 'time<=2011-10-31') 40 | browse(my_tabledap) 41 | }} 42 | } 43 | \author{ 44 | Ben Tupper \email{btupper@bigelow.org} 45 | } 46 | -------------------------------------------------------------------------------- /man/cache_delete.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/cache_delete.R 3 | \name{cache_delete} 4 | \alias{cache_delete} 5 | \alias{cache_delete_all} 6 | \title{Delete cached files} 7 | \usage{ 8 | cache_delete(x, force = FALSE) 9 | 10 | cache_delete_all(force = FALSE) 11 | } 12 | \arguments{ 13 | \item{x}{File names} 14 | 15 | \item{force}{(logical) Should files be force deleted? Default: \code{FALSE}} 16 | } 17 | \description{ 18 | Delete cached files 19 | } 20 | \examples{ 21 | \dontrun{ 22 | # delete files by name in cache 23 | # cache_delete('9911750294a039b8b517c8bf288978ea.csv') 24 | # cache_delete(c('9911750294a039b8b517c8bf288978ea.csv', 25 | # 'b26825b6737da13d6a52c28c8dfe690f.csv')) 26 | 27 | # You can delete from the output of griddap or tabledap fxns 28 | ## tabledap 29 | (table_res <- tabledap('erdCinpKfmBT')) 30 | cache_delete(table_res) 31 | 32 | ## griddap 33 | (out <- info('erdQMekm14day')) 34 | (grid_res <- griddap(out, 35 | time = c('2015-12-28','2016-01-01'), 36 | latitude = c(24, 23), 37 | longitude = c(88, 90) 38 | )) 39 | cache_delete(grid_res) 40 | } 41 | } 42 | \seealso{ 43 | Other cache: 44 | \code{\link{cache_details}()}, 45 | \code{\link{cache_list}()}, 46 | \code{\link{cache_setup}()} 47 | } 48 | \concept{cache} 49 | -------------------------------------------------------------------------------- /man/cache_details.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/cache_details.R 3 | \name{cache_details} 4 | \alias{cache_details} 5 | \title{Get details of cached files} 6 | \usage{ 7 | cache_details(x) 8 | } 9 | \arguments{ 10 | \item{x}{File names} 11 | } 12 | \description{ 13 | Get details of cached files 14 | } 15 | \details{ 16 | Can be used to list details for all files, both .nc and .csv 17 | types, or details for just individual files of class \code{tabledap}, 18 | \code{griddap_nc}, and \code{griddap_csv} 19 | } 20 | \examples{ 21 | \dontrun{ 22 | # List details for all cached files 23 | cache_details() 24 | } 25 | } 26 | \seealso{ 27 | Other cache: 28 | \code{\link{cache_delete}()}, 29 | \code{\link{cache_list}()}, 30 | \code{\link{cache_setup}()} 31 | } 32 | \concept{cache} 33 | -------------------------------------------------------------------------------- /man/cache_list.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/cache_list.R 3 | \name{cache_list} 4 | \alias{cache_list} 5 | \title{List cached files} 6 | \usage{ 7 | cache_list() 8 | } 9 | \description{ 10 | List cached files 11 | } 12 | \examples{ 13 | \dontrun{ 14 | # list files in cache 15 | cache_list() 16 | 17 | # List info for files 18 | ## download some data first 19 | tabledap('erdCinpKfmBT') 20 | griddap('erdVHNchlamday', 21 | time = c('2015-04-01','2015-04-10'), 22 | latitude = c(18, 21), 23 | longitude = c(-120, -119) 24 | ) 25 | 26 | (x <- cache_list()) 27 | cache_details(x$nc[1]) 28 | cache_details(x$csv[1]) 29 | cache_details() 30 | 31 | # delete files by name in cache 32 | # cache_delete(x$nc[1]) 33 | # cache_delete(x$nc[2:3]) 34 | } 35 | } 36 | \seealso{ 37 | Other cache: 38 | \code{\link{cache_delete}()}, 39 | \code{\link{cache_details}()}, 40 | \code{\link{cache_setup}()} 41 | } 42 | \concept{cache} 43 | -------------------------------------------------------------------------------- /man/cache_setup.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/cache_setup.R 3 | \name{cache_setup} 4 | \alias{cache_setup} 5 | \alias{cache_info} 6 | \title{Setup cache path} 7 | \usage{ 8 | cache_setup(full_path = NULL, temp_dir = FALSE) 9 | 10 | cache_info() 11 | } 12 | \arguments{ 13 | \item{full_path}{(character) the full path to use for storing cached 14 | files.} 15 | 16 | \item{temp_dir}{(logical) if \code{TRUE} use a randomly assigned 17 | \code{tempdir} (and \code{full_path} is ignored), if \code{FALSE}, you 18 | can use \code{full_path}.} 19 | } 20 | \value{ 21 | the full cache path, a directory (character) 22 | } 23 | \description{ 24 | Setup cache path 25 | } 26 | \details{ 27 | On opening, by default a temporary directory is created for caching 28 | files. To have files cached elsewhere, give the full path of where to 29 | cache files. Adding \code{temp_dir = TRUE} will again use a temporary 30 | dirctory for cacheing. 31 | } 32 | \examples{ 33 | \dontrun{ 34 | # default path 35 | cache_setup() 36 | 37 | # you can define your own path 38 | cache_setup(path = "foobar") 39 | 40 | # set a tempdir - better for programming with to avoid prompt 41 | cache_setup(temp_dir = TRUE) 42 | 43 | # cache info 44 | cache_info() 45 | } 46 | } 47 | \seealso{ 48 | Other cache: 49 | \code{\link{cache_delete}()}, 50 | \code{\link{cache_details}()}, 51 | \code{\link{cache_list}()} 52 | } 53 | \concept{cache} 54 | -------------------------------------------------------------------------------- /man/colors.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/colors.R 3 | \docType{data} 4 | \name{colors} 5 | \alias{colors} 6 | \title{cmocean colors 7 | The cmocean color palette by Kristen Thyng as implemented in the R package "oce"} 8 | \format{ 9 | An object of class \code{list} of length 13. 10 | } 11 | \usage{ 12 | colors 13 | } 14 | \description{ 15 | str(colors) 16 | List of 13 17 | $ viridis 18 | $ cdom 19 | $ chlorophyll 20 | $ density 21 | $ freesurface 22 | $ oxygen 23 | $ par 24 | $ phase 25 | $ salinity 26 | $ temperature 27 | $ turbidity 28 | $ velocity 29 | $ vorticity 30 | } 31 | \keyword{datasets} 32 | -------------------------------------------------------------------------------- /man/convert_time.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/convert_time.R 3 | \name{convert_time} 4 | \alias{convert_time} 5 | \title{Convert a UDUNITS compatible time to ISO time} 6 | \usage{ 7 | convert_time( 8 | n = NULL, 9 | isoTime = NULL, 10 | units = "seconds since 1970-01-01T00:00:00Z", 11 | url = eurl(), 12 | method = "local", 13 | ... 14 | ) 15 | } 16 | \arguments{ 17 | \item{n}{numeric; A unix time number.} 18 | 19 | \item{isoTime}{character; A string time representation.} 20 | 21 | \item{units}{character; Units to return. Default: 22 | "seconds since 1970-01-01T00:00:00Z"} 23 | 24 | \item{url}{Base URL of the ERDDAP server. See \code{\link[=eurl]{eurl()}} for 25 | more information} 26 | 27 | \item{method}{(character) One of local or web. Local simply uses 28 | \code{\link[=as.POSIXct]{as.POSIXct()}}, while web method uses the ERDDAP time conversion service 29 | \verb{/erddap/convert/time.txt}} 30 | 31 | \item{...}{Curl options passed on to \link[crul:verb-GET]{crul::verb-GET}} 32 | } 33 | \description{ 34 | Convert a UDUNITS compatible time to ISO time 35 | } 36 | \details{ 37 | When \code{method = "web"} time zone is GMT/UTC 38 | } 39 | \examples{ 40 | \dontrun{ 41 | # local conversions 42 | convert_time(n = 473472000) 43 | convert_time(isoTime = "1985-01-02T00:00:00Z") 44 | 45 | # using an erddap web service 46 | convert_time(n = 473472000, method = "web") 47 | convert_time(isoTime = "1985-01-02T00:00:00Z", method = "web") 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /man/convert_units.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/convert_units.R 3 | \name{convert_units} 4 | \alias{convert_units} 5 | \title{Convert a CF Standard Name to/from a GCMD Science Keyword} 6 | \usage{ 7 | convert_units(udunits = NULL, ucum = NULL, url = eurl(), ...) 8 | } 9 | \arguments{ 10 | \item{udunits}{character; A UDUNITS character string 11 | https://www.unidata.ucar.edu/software/udunits/} 12 | 13 | \item{ucum}{character; A UCUM character string 14 | https://ucum.org/ucum.html} 15 | 16 | \item{url}{Base URL of the ERDDAP server. See \code{\link[=eurl]{eurl()}} for 17 | more information} 18 | 19 | \item{...}{Curl options passed on to \link[crul:verb-GET]{crul::verb-GET}} 20 | } 21 | \description{ 22 | Convert a CF Standard Name to/from a GCMD Science Keyword 23 | } 24 | \examples{ 25 | \dontrun{ 26 | convert_units(udunits = "degree_C meter-1") 27 | convert_units(ucum = "Cel.m-1") 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /man/disk.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils.R 3 | \name{disk} 4 | \alias{disk} 5 | \alias{memory} 6 | \title{Options for saving ERDDAP datasets.} 7 | \usage{ 8 | disk(path = NULL, overwrite = TRUE) 9 | 10 | memory() 11 | } 12 | \arguments{ 13 | \item{path}{Path to store files in. A directory, not a file. 14 | Default: the root cache path, see \code{\link{cache_setup}}} 15 | 16 | \item{overwrite}{(logical) Overwrite an existing file of the same name? 17 | Default: \code{TRUE}} 18 | } 19 | \description{ 20 | Options for saving ERDDAP datasets. 21 | } 22 | -------------------------------------------------------------------------------- /man/ed_search.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/search.R 3 | \name{ed_search} 4 | \alias{ed_search} 5 | \alias{ed_datasets} 6 | \title{Search for ERDDAP tabledep or griddap datasets} 7 | \usage{ 8 | ed_search( 9 | query, 10 | page = NULL, 11 | page_size = NULL, 12 | which = "griddap", 13 | url = eurl(), 14 | ... 15 | ) 16 | 17 | ed_datasets(which = "tabledap", url = eurl()) 18 | } 19 | \arguments{ 20 | \item{query}{(character) Search terms} 21 | 22 | \item{page}{(integer) Page number} 23 | 24 | \item{page_size}{(integer) Results per page} 25 | 26 | \item{which}{(character) One of tabledep or griddap.} 27 | 28 | \item{url}{A URL for an ERDDAP server. Default: 29 | https://upwell.pfeg.noaa.gov/erddap/ - See \code{\link[=eurl]{eurl()}} for 30 | more information} 31 | 32 | \item{...}{Curl options passed on to \link[crul:verb-GET]{crul::verb-GET} (must be 33 | named parameters)} 34 | } 35 | \description{ 36 | Search for ERDDAP tabledep or griddap datasets 37 | } 38 | \examples{ 39 | \dontrun{ 40 | (out <- ed_search(query='temperature')) 41 | out$alldata[[1]] 42 | (out <- ed_search(query='size')) 43 | out$info 44 | 45 | # List datasets 46 | ed_datasets('table') 47 | ed_datasets('grid') 48 | 49 | # use a different ERDDAP server 50 | ## Marine Institute (Ireland) 51 | ed_search("temperature", url = "http://erddap.marine.ie/erddap/") 52 | } 53 | } 54 | \references{ 55 | https://upwell.pfeg.noaa.gov/erddap/index.html 56 | } 57 | -------------------------------------------------------------------------------- /man/ed_search_adv.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/search_adv.R 3 | \name{ed_search_adv} 4 | \alias{ed_search_adv} 5 | \title{Advanced search for ERDDAP tabledep or griddap datasets} 6 | \usage{ 7 | ed_search_adv( 8 | query = NULL, 9 | page = 1, 10 | page_size = 1000, 11 | protocol = NULL, 12 | cdm_data_type = NULL, 13 | institution = NULL, 14 | ioos_category = NULL, 15 | keywords = NULL, 16 | long_name = NULL, 17 | standard_name = NULL, 18 | variableName = NULL, 19 | maxLat = NULL, 20 | minLon = NULL, 21 | maxLon = NULL, 22 | minLat = NULL, 23 | minTime = NULL, 24 | maxTime = NULL, 25 | url = eurl(), 26 | ... 27 | ) 28 | } 29 | \arguments{ 30 | \item{query}{(character) Search terms} 31 | 32 | \item{page}{(integer) Page number. Default: 1} 33 | 34 | \item{page_size}{(integer) Results per page: Default: 1000} 35 | 36 | \item{protocol}{(character) One of any (default), tabledep or griddap} 37 | 38 | \item{cdm_data_type}{(character) One of grid, other, point, profile, 39 | timeseries, timeseriesprofile, trajectory, trajectoryprofile} 40 | 41 | \item{institution}{(character) An institution. See the dataset 42 | \code{institutions}} 43 | 44 | \item{ioos_category}{(character) An ioos category See the dataset 45 | \code{ioos_categories}} 46 | 47 | \item{keywords}{(character) A keywords. See the dataset \code{keywords}} 48 | 49 | \item{long_name}{(character) A long name. See the dataset \code{longnames}} 50 | 51 | \item{standard_name}{(character) A standar dname. See the dataset 52 | \code{standardnames}} 53 | 54 | \item{variableName}{(character) A variable name. See the dataset 55 | \code{variablenames}} 56 | 57 | \item{minLon, maxLon}{(numeric) Minimum and maximum longitude. Some datasets 58 | have longitude values within -180 to 180, others use 0 to 360. If you 59 | specify min and max Longitude within -180 to 180 (or 0 to 360), ERDDAP will 60 | only find datasets that match the values you specify. Consider doing one 61 | search: longitude -180 to 360, or two searches: longitude -180 to 180, 62 | and 0 to 360.} 63 | 64 | \item{minLat, maxLat}{(numeric) Minimum and maximum latitude, between -90 65 | and 90} 66 | 67 | \item{minTime, maxTime}{(numeric/character) Minimum and maximum time. Time 68 | string with the format "yyyy-MM-ddTHH:mm:ssZ, (e.g., 2009-01-21T23:00:00Z). 69 | If you specify something, you must include at least yyyy-MM-dd; you can 70 | omit Z, :ss, :mm, :HH, and T. Always use UTC (GMT/Zulu) time. Or specify 71 | the number of seconds since 1970-01-01T00:00:00Z.} 72 | 73 | \item{url}{A URL for an ERDDAP server. Default: 74 | https://upwell.pfeg.noaa.gov/erddap/ - See \code{\link[=eurl]{eurl()}} for 75 | more information} 76 | 77 | \item{...}{Curl options passed on to \link[crul:verb-GET]{crul::verb-GET} (must be 78 | named parameters)} 79 | } 80 | \description{ 81 | Advanced search for ERDDAP tabledep or griddap datasets 82 | } 83 | \examples{ 84 | \dontrun{ 85 | ed_search_adv(query = 'temperature') 86 | ed_search_adv(query = 'temperature', protocol = "griddap") 87 | ed_search_adv(query = 'temperature', protocol = "tabledap") 88 | ed_search_adv(maxLat = 63, minLon = -107, maxLon = -87, minLat = 50, 89 | protocol = "griddap") 90 | ed_search_adv(maxLat = 63, minLon = -107, maxLon = -87, minLat = 50, 91 | protocol = "tabledap") 92 | ed_search_adv(minTime = "2010-01-01T00:00:00Z", 93 | maxTime="2010-02-01T00:00:00Z") 94 | (out <- ed_search_adv(maxLat = 63, minLon = -107, maxLon = -87, minLat = 50, 95 | minTime = "2010-01-01T00:00:00Z", 96 | maxTime="2010-02-01T00:00:00Z")) 97 | out$alldata[[1]] 98 | ed_search_adv(variableName = 'upwelling') 99 | ed_search_adv(query = 'upwelling', protocol = "tabledap") 100 | 101 | # use a different URL 102 | ed_search_adv(query = 'temperature', url = servers()$url[6]) 103 | } 104 | } 105 | \references{ 106 | https://upwell.pfeg.noaa.gov/erddap/index.html 107 | } 108 | -------------------------------------------------------------------------------- /man/eurl.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/default-url.R 3 | \name{eurl} 4 | \alias{eurl} 5 | \title{Default ERDDAP server URL} 6 | \usage{ 7 | eurl() 8 | } 9 | \description{ 10 | Default ERDDAP server URL 11 | } 12 | \details{ 13 | default url is https://upwell.pfeg.noaa.gov/erddap/ 14 | 15 | You can set a default using an environment variable so you 16 | don't have to pass anything to the URL parameter in your 17 | function calls. 18 | 19 | In your .Renviron file or similar set a URL for the environment 20 | variable \code{RERDDAP_DEFAULT_URL}, like 21 | \verb{RERDDAP_DEFAULT_URL=https://upwell.pfeg.noaa.gov/erddap/} 22 | 23 | It's important that you include a trailing slash in your URL 24 | } 25 | \examples{ 26 | eurl() 27 | Sys.setenv(RERDDAP_DEFAULT_URL = "https://google.com") 28 | Sys.getenv("RERDDAP_DEFAULT_URL") 29 | eurl() 30 | Sys.unsetenv("RERDDAP_DEFAULT_URL") 31 | eurl() 32 | } 33 | -------------------------------------------------------------------------------- /man/fipscounty.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/fipscounty.R 3 | \name{fipscounty} 4 | \alias{fipscounty} 5 | \title{Convert a FIPS County Code to/from a County Name} 6 | \usage{ 7 | fipscounty(county = NULL, code = NULL, url = eurl(), ...) 8 | } 9 | \arguments{ 10 | \item{county}{character; A county name.} 11 | 12 | \item{code}{numeric; A FIPS code.} 13 | 14 | \item{url}{A URL for an ERDDAP server. Default: 15 | https://upwell.pfeg.noaa.gov/erddap/ - See \code{\link[=eurl]{eurl()}} for 16 | more information} 17 | 18 | \item{...}{Curl options passed on to \link[crul:verb-GET]{crul::verb-GET}} 19 | } 20 | \description{ 21 | Convert a FIPS County Code to/from a County Name 22 | } 23 | \examples{ 24 | \dontrun{ 25 | fipscounty(code = "06053") 26 | fipscounty(county = "CA, Monterey") 27 | fipscounty(county = "OR, Multnomah") 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /man/global_search.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/global_search.R 3 | \name{global_search} 4 | \alias{global_search} 5 | \title{global_search} 6 | \usage{ 7 | global_search(query, server_list, which_service) 8 | } 9 | \arguments{ 10 | \item{query}{(character) Search terms} 11 | 12 | \item{server_list}{(list of character) List of ERDDAP servers to search} 13 | 14 | \item{which_service}{(character) One of tabledep or griddap.} 15 | } 16 | \value{ 17 | If successful a dataframe wih columns: 18 | \itemize{ 19 | \item title - the dataset title 20 | \item dataset_id - the datasetid on that ERDDAP server 21 | \item url - base url of dataset ERDDAP server 22 | } 23 | if urls are valid, no match is found, will return no match found 24 | else returns error message 25 | } 26 | \description{ 27 | Search for ERDDAP tabledap or griddap datasets from a list 28 | of ERDDAP servers based on search terms. 29 | } 30 | \details{ 31 | Uses the 'reddap' function ed_search() to search over 32 | the list of servers 33 | } 34 | \examples{ 35 | # get list of servers know by 36 | # https://irishmarineinstitute.github.io/awesome-erddap 37 | # e_servers <- servers()$url 38 | # select a couple to search 39 | # e_servers <- e_servers[c(1, 40)] 40 | # to meet CRAN time limits will only search 1 place 41 | e_servers <- "https://coastwatch.pfeg.noaa.gov/erddap/" 42 | test_query <- 'NOAA/NCDC Blended Monthly' 43 | query_results <- global_search(test_query, e_servers, "griddap") 44 | } 45 | \seealso{ 46 | \code{\link[crul]{HttpClient}} 47 | } 48 | -------------------------------------------------------------------------------- /man/griddap.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/grid.R 3 | \name{griddap} 4 | \alias{griddap} 5 | \title{Get ERDDAP™ gridded data} 6 | \usage{ 7 | griddap( 8 | datasetx, 9 | ..., 10 | fields = "all", 11 | stride = 1, 12 | fmt = "nc", 13 | url = eurl(), 14 | store = disk(), 15 | read = TRUE, 16 | callopts = list() 17 | ) 18 | } 19 | \arguments{ 20 | \item{datasetx}{Anything coercable to an object of class info. So the output of a 21 | call to \code{\link{info}}, or a datasetid, which will internally be passed 22 | through \code{\link{info}}} 23 | 24 | \item{...}{Dimension arguments. See examples. Can be any 1 or more of the 25 | dimensions for the particular dataset - and the dimensions vary by dataset. 26 | For each dimension, pass in a vector of length two, with min and max value 27 | desired. at least 1 required.} 28 | 29 | \item{fields}{(character) Fields to return, in a character vector.} 30 | 31 | \item{stride}{(integer) How many values to get. 1 = get every value, 2 = get 32 | every other value, etc. Default: 1 (i.e., get every value)} 33 | 34 | \item{fmt}{(character) One of csv or nc (for netcdf). Default: nc} 35 | 36 | \item{url}{A URL for an ERDDAP server. Default: 37 | https://upwell.pfeg.noaa.gov/erddap/ - See \code{\link[=eurl]{eurl()}} for 38 | more information} 39 | 40 | \item{store}{One of \code{\link{disk}} (default) or \code{\link{memory}}. You 41 | can pass options to \code{\link{disk}}. Beware: if you choose \code{fmt="nc"}, 42 | we force \code{store=disk()} because nc files have to be written to disk.} 43 | 44 | \item{read}{(logical) Read data into memory or not. Does not apply when 45 | \code{store} parameter is set to memory (which reads data into memory). 46 | For large csv, or especially netcdf files, you may want to set this to 47 | \code{FALSE}, which simply returns a summary of the dataset - and you can 48 | read in data piecemeal later. Default: \code{TRUE}} 49 | 50 | \item{callopts}{Curl options passed on to \code{\link[crul]{verb-GET}}} 51 | } 52 | \value{ 53 | An object of class \code{griddap_csv} if csv chosen or 54 | \code{griddap_nc} if nc file format chosen. 55 | 56 | \itemize{ 57 | \item \code{griddap_csv}: a data.frame created from the downloaded csv 58 | data 59 | \item \code{griddap_nc}: a list, with slots "summary" and "data". "summary" 60 | is the unclassed output from \code{ncdf4::nc_open}, from which you can 61 | do any netcdf operations you like. "data" is a data.frame created 62 | from the netcdf data. the data.frame may be empty if there were problems 63 | parsing the netcdf data 64 | } 65 | 66 | Both have the attributes: datasetid (the dataset id), path (the path on file 67 | for the csv or nc file), url (the url requested to the ERDDAP server) 68 | 69 | If \code{read=FALSE}, the data.frame for \code{griddap_csv} 70 | and the data.frame in the "data" slot is empty for \code{griddap_nc} 71 | } 72 | \description{ 73 | Get ERDDAP™ gridded data 74 | } 75 | \details{ 76 | Details: 77 | 78 | If you run into an error like "HTTP Status 500 - There was a (temporary?) 79 | problem. Wait a minute, then try again.". it's likely they are hitting 80 | up against a size limit, and they should reduce the amount of data they 81 | are requesting either via space, time, or variables. Pass in 82 | \code{config = verbose()} to the request, and paste the URL into your 83 | browser to see if the output is garbled to examine if there's a problem 84 | with servers or this package 85 | } 86 | \section{Dimensions and Variables}{ 87 | 88 | ERDDAP grid dap data has this concept of dimenions vs. variables. Dimensions 89 | are things like time, latitude, longitude, altitude, and depth. Whereas 90 | variables are the measured variables, e.g., temperature, salinity, air. 91 | 92 | You can't separately adjust values for dimensions for different variables. 93 | So, here's how it's gonna work: 94 | 95 | Pass in lower and upper limits you want for each dimension as a vector 96 | (e.g., \code{c(1,2)}), or leave to defaults (i.e., don't pass anything to 97 | a dimension). Then pick which variables you want returned via the 98 | \code{fields} parameter. If you don't pass in options to the \code{fields} 99 | parameter, you get all variables back. 100 | 101 | To get the dimensions and variables, along with other metadata for a 102 | dataset, run \code{\link{info}}, and each will be shown, with their min 103 | and max values, and some other metadata. 104 | } 105 | 106 | \section{Where does the data go?}{ 107 | 108 | You can choose where data is stored. Be careful though. You can easily get a 109 | single file of hundreds of MB's (upper limit: 2 GB) in size with a single 110 | request. To the \code{store} parameter, pass \code{\link{memory}} if you 111 | want to store the data in memory (saved as a data.frame), or pass 112 | \code{\link{disk}} if you want to store on disk in a file. Note that 113 | \code{\link{memory}} and \code{\link{disk}} are not character strings, but 114 | function calls. \code{\link{memory}} does not accept any inputs, while 115 | \code{\link{disk}} does. Possibly will add other options, like 116 | \dQuote{sql} for storing in a SQL database. 117 | } 118 | 119 | \section{Non-lat/lon grid data}{ 120 | 121 | Some gridded datasets have latitude/longitude components, but some do not. 122 | When nc format gridded datasets have latitude and longitude we "melt" them into a 123 | data.frame for easy downstream consumption. When nc format gridded datasets do 124 | not have latitude and longitude components, we do not read in the data, throw 125 | a warning saying so. You can readin the nc file yourself with the file path. 126 | CSV format is not affected by this issue as CSV data is easily turned into 127 | a data.frame regardless of whether latitude/longitude data are present. 128 | } 129 | 130 | \examples{ 131 | \dontrun{ 132 | # single variable dataset 133 | ## You can pass in the outpu of a call to info 134 | (out <- info('erdVHNchlamday')) 135 | ## Or, pass in a dataset id 136 | (res <- griddap('erdVHNchlamday', 137 | time = c('2015-04-01','2015-04-10'), 138 | latitude = c(18, 21), 139 | longitude = c(-120, -119) 140 | )) 141 | 142 | # multi-variable dataset 143 | (out <- info('erdQMekm14day')) 144 | (res <- griddap(out, 145 | time = c('2015-12-28','2016-01-01'), 146 | latitude = c(24, 23), 147 | longitude = c(88, 90) 148 | )) 149 | (res <- griddap(out, time = c('2015-12-28','2016-01-01'), 150 | latitude = c(24, 23), longitude = c(88, 90), fields = 'mod_current')) 151 | (res <- griddap(out, time = c('2015-12-28','2016-01-01'), 152 | latitude = c(24, 23), longitude = c(88, 90), fields = 'mod_current', 153 | stride = c(1,2,1,2))) 154 | (res <- griddap(out, time = c('2015-12-28','2016-01-01'), 155 | latitude = c(24, 23), longitude = c(88, 90), 156 | fields = c('mod_current','u_current'))) 157 | 158 | 159 | # Write to memory (within R), or to disk 160 | (out <- info('erdQSwindmday')) 161 | ## disk, by default (to prevent bogging down system w/ large datasets) 162 | ## you can also pass in path and overwrite options to disk() 163 | (res <- griddap(out, 164 | time = c('2006-07-11','2006-07-20'), 165 | longitude = c(166, 170), 166 | store = disk() 167 | )) 168 | ## the 2nd call is much faster as it's mostly just the time of reading in 169 | ## the table from disk 170 | system.time( griddap(out, 171 | time = c('2006-07-11','2006-07-15'), 172 | longitude = c(10, 15), 173 | store = disk() 174 | ) ) 175 | system.time( griddap(out, 176 | time = c('2006-07-11','2006-07-15'), 177 | longitude = c(10, 15), 178 | store = disk() 179 | ) ) 180 | 181 | ## memory - you have to choose fmt="csv" if you use memory 182 | (res <- griddap("erdMBchla1day", 183 | time = c('2015-01-01','2015-01-03'), 184 | latitude = c(14, 15), 185 | longitude = c(125, 126), 186 | fmt = "csv", store = memory() 187 | )) 188 | 189 | ## Use ncdf4 package to parse data 190 | info("erdMBchla1day") 191 | (res <- griddap("erdMBchla1day", 192 | time = c('2015-01-01','2015-01-03'), 193 | latitude = c(14, 15), 194 | longitude = c(125, 126) 195 | )) 196 | 197 | # Get data in csv format 198 | ## by default, we get netcdf format data 199 | (res <- griddap('erdMBchla1day', 200 | time = c('2015-01-01','2015-01-03'), 201 | latitude = c(14, 15), 202 | longitude = c(125, 126), 203 | fmt = "csv" 204 | )) 205 | 206 | # Use a different ERDDAP server url 207 | ## NOAA IOOS PacIOOS 208 | url = "https://cwcgom.aoml.noaa.gov/erddap/" 209 | out <- info("miamiacidification", url = url) 210 | (res <- griddap(out, 211 | time = c('2019-11-01','2019-11-03'), 212 | latitude = c(15, 16), 213 | longitude = c(-90, -88) 214 | )) 215 | ## pass directly into griddap() - if you pass a datasetid string directly 216 | ## you must pass in the url or you'll be querying the default ERDDAP url, 217 | ## which isn't the one you want if you're not using the default ERDDAP url 218 | griddap("miamiacidification", url = url, 219 | time = c('2019-11-01','2019-11-03'), 220 | latitude = c(15, 16), 221 | longitude = c(-90, -88) 222 | ) 223 | 224 | # Using 'last' 225 | ## with time 226 | griddap('erdVHNchlamday', 227 | time = c('last-5','last'), 228 | latitude = c(18, 21), 229 | longitude = c(-120, -119) 230 | ) 231 | ## with latitude 232 | griddap('erdVHNchlamday', 233 | time = c('2015-04-01','2015-04-10'), 234 | latitude = c('last', 'last'), 235 | longitude = c(-120, -119) 236 | ) 237 | ## with longitude 238 | griddap('erdVHNchlamday', 239 | time = c('2015-04-01','2015-04-10'), 240 | latitude = c(18, 21), 241 | longitude = c('last', 'last') 242 | ) 243 | 244 | # datasets without lat/lon grid and with fmt=nc 245 | # FIXME: this dataset is gone 246 | # (x <- info('glos_tds_5912_ca66_3f41')) 247 | # res <- griddap(x, 248 | # time = c('2018-04-01','2018-04-10'), 249 | # ny = c(1, 2), 250 | # nx = c(3, 5) 251 | # ) 252 | ## data.frame is empty 253 | # res$data 254 | ## read in from the nc file path 255 | # ncdf4::nc_open(res$summary$filename) 256 | } 257 | } 258 | \references{ 259 | https://upwell.pfeg.noaa.gov/erddap/rest.html 260 | } 261 | -------------------------------------------------------------------------------- /man/info.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/info.R 3 | \name{info} 4 | \alias{info} 5 | \alias{as.info} 6 | \title{Get information on an ERDDAP dataset.} 7 | \usage{ 8 | info(datasetid, url = eurl(), ...) 9 | 10 | as.info(x, url) 11 | } 12 | \arguments{ 13 | \item{datasetid}{Dataset id} 14 | 15 | \item{url}{A URL for an ERDDAP server. Default: 16 | https://upwell.pfeg.noaa.gov/erddap/ - See \code{\link[=eurl]{eurl()}} for 17 | more information} 18 | 19 | \item{...}{Further args passed on to \link[crul:verb-GET]{crul::verb-GET} (must be a 20 | named parameter)} 21 | 22 | \item{x}{A datasetid or the output of \code{info}} 23 | } 24 | \value{ 25 | Prints a summary of the data on return, but you can index to 26 | various information. 27 | 28 | The data is a list of length two with: 29 | \itemize{ 30 | \item variables - Data.frame of variables and their types 31 | \item alldata - List of data variables and their full attributes 32 | } 33 | 34 | Where \code{alldata} element has many data.frame's, one for each variable, 35 | with metadata for that variable. E.g., for griddap dataset 36 | \code{noaa_pfeg_696e_ec99_6fa6}, \code{alldata} has: 37 | \itemize{ 38 | \item NC_GLOBAL 39 | \item time 40 | \item latitude 41 | \item longitude 42 | \item sss 43 | } 44 | } 45 | \description{ 46 | Get information on an ERDDAP dataset. 47 | } 48 | \examples{ 49 | \dontrun{ 50 | # grid dap datasets 51 | info('erdATastnhday') 52 | 53 | (out <- ed_search(query='temperature')) 54 | info(out$info$dataset_id[5]) 55 | info(out$info$dataset_id[15]) 56 | info(out$info$dataset_id[25]) 57 | info(out$info$dataset_id[150]) 58 | info(out$info$dataset_id[400]) 59 | info(out$info$dataset_id[678]) 60 | 61 | out <- info(datasetid='erdMBchla1day') 62 | ## See brief overview of the variables and range of possible values, if given 63 | out$variables 64 | ## all information on longitude 65 | out$alldata$longitude 66 | ## all information on chlorophyll 67 | out$alldata$chlorophyll 68 | 69 | # table dap datasets 70 | (out <- ed_search(query='temperature', which = "table")) 71 | info(out$info$dataset_id[1]) 72 | info(out$info$dataset_id[2]) 73 | info(out$info$dataset_id[3]) 74 | info(out$info$dataset_id[4]) 75 | 76 | info('erdCinpKfmBT') 77 | out <- info('erdCinpKfmBT') 78 | ## See brief overview of the variables and range of possible values, if given 79 | out$variables 80 | ## all information on longitude 81 | out$alldata$longitude 82 | ## all information on Haliotis_corrugata_Mean_Density 83 | out$alldata$Haliotis_corrugata_Mean_Density 84 | 85 | # use a different ERDDAP server 86 | ## Marine Institute (Ireland) 87 | info("IMI_CONN_2D", url = "http://erddap.marine.ie/erddap/") 88 | } 89 | } 90 | \references{ 91 | https://upwell.pfeg.noaa.gov/erddap/index.html 92 | } 93 | -------------------------------------------------------------------------------- /man/institutions.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rerddap-package.r 3 | \docType{data} 4 | \name{institutions} 5 | \alias{institutions} 6 | \title{institutions} 7 | \format{ 8 | A character vector 9 | } 10 | \description{ 11 | institutions 12 | } 13 | \keyword{datasets} 14 | -------------------------------------------------------------------------------- /man/ioos_categories.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rerddap-package.r 3 | \docType{data} 4 | \name{ioos_categories} 5 | \alias{ioos_categories} 6 | \title{ioos_categories} 7 | \format{ 8 | A character vector 9 | } 10 | \description{ 11 | ioos_categories 12 | } 13 | \keyword{datasets} 14 | -------------------------------------------------------------------------------- /man/key_words.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/keywords.R 3 | \name{key_words} 4 | \alias{key_words} 5 | \title{Convert a CF Standard Name to/from a GCMD Science Keyword} 6 | \usage{ 7 | key_words(cf = NULL, gcmd = NULL, url = eurl(), ...) 8 | } 9 | \arguments{ 10 | \item{cf}{character; A cf standard name 11 | http://cfconventions.org/Data/cf-standard-names/27/build/cf-standard-name-table.html} 12 | 13 | \item{gcmd}{character; A GCMD science keyword 14 | http://gcmd.gsfc.nasa.gov/learn/keyword_list.html} 15 | 16 | \item{url}{A URL for an ERDDAP server. Default: 17 | https://upwell.pfeg.noaa.gov/erddap/. See \code{\link[=eurl]{eurl()}} for 18 | more information} 19 | 20 | \item{...}{Curl options passed on to \link[crul:verb-GET]{crul::verb-GET}} 21 | } 22 | \description{ 23 | Convert a CF Standard Name to/from a GCMD Science Keyword 24 | } 25 | \examples{ 26 | \dontrun{ 27 | key_words(cf = "air_pressure") 28 | cat(key_words(cf = "air_pressure")) 29 | 30 | # a different ERDDAP server 31 | # key_words(cf = "air_pressure", url = servers()$url[6]) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /man/keywords.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rerddap-package.r 3 | \docType{data} 4 | \name{keywords} 5 | \alias{keywords} 6 | \title{keywords} 7 | \format{ 8 | A character vector 9 | } 10 | \description{ 11 | keywords 12 | } 13 | \keyword{datasets} 14 | -------------------------------------------------------------------------------- /man/longnames.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rerddap-package.r 3 | \docType{data} 4 | \name{longnames} 5 | \alias{longnames} 6 | \title{longnames} 7 | \format{ 8 | A character vector 9 | } 10 | \description{ 11 | longnames 12 | } 13 | \keyword{datasets} 14 | -------------------------------------------------------------------------------- /man/rerddap.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rerddap-package.r 3 | \docType{package} 4 | \name{rerddap} 5 | \alias{rerddap-package} 6 | \alias{rerddap} 7 | \title{rerddap} 8 | \description{ 9 | General purpose R client for ERDDAP servers 10 | } 11 | \section{ERDDAP info}{ 12 | 13 | NOAA's ERDDAP service holds many datasets of interest. It's built on top of 14 | OPenDAP. You can search for datasets via 15 | \code{\link[=ed_search]{ed_search()}}, list datasets via \code{\link[=ed_datasets]{ed_datasets()}}, 16 | get information on a single dataset via \code{\link[=info]{info()}}, then get 17 | data you want for either tabledap type via \code{\link[=tabledap]{tabledap()}}, or 18 | for griddap type via \code{\link[=griddap]{griddap()}} 19 | } 20 | 21 | \section{tabledap/griddap}{ 22 | 23 | tabledap and griddap have different interfaces to query for data, so 24 | \code{\link[=tabledap]{tabledap()}} and \code{\link[=griddap]{griddap()}} are separated out as 25 | separate functions even though some of the internals are the same. In 26 | particular, with tabledap you can query on/subset all variables, whereas 27 | with gridddap, you can only query on/subset the dimension varibles (e.g., 28 | latitude, longitude, altitude). 29 | } 30 | 31 | \section{Data size}{ 32 | 33 | With griddap data via \code{\link[=griddap]{griddap()}} you can get a lot of 34 | data quickly. Try small searches of a dataset to start to get a sense for 35 | the data, then you can increase the amount of data you get. See 36 | \code{\link[=griddap]{griddap()}} for more details. 37 | } 38 | 39 | \section{Caching}{ 40 | 41 | \pkg{rerddap} by default caches the requests you make, so that if you happen to 42 | make the same request again, the data is restored from the cache, rather than 43 | having to go out and retrieve it remotely. For most applications, this is good, 44 | as it can speed things up when doing a lot of request in a script, and works 45 | because in most cases an ERDDAP request is "idempotent". This means that the 46 | the request will always return the same thing no matter what requests came 47 | before - it doesn't depend on state. However this is not true if the 48 | script uses either "last" in \code{\link[=griddap]{griddap()}} or "now" in \code{\link[=tabledap]{tabledap()}} as these 49 | will return different values as time elapses and data are added to the 50 | datasets. While it is desirable to have ERDDAP purely idempotent, the 51 | "last" and "now" constructs are very helpful for people using ERDDAP 52 | in dashboards, webpages, regular input to models and the like, and the 53 | benefits far outweigh the problems. However, if you are using either "last" 54 | or "now" in an \pkg{rerddap} based script, you want to be very careful to 55 | clear the \pkg{rerddap} cache, otherwise the request will be viewed as the 56 | same, and the data from the last request, rather than the latest data, 57 | will be returned. 58 | } 59 | 60 | \seealso{ 61 | Useful links: 62 | \itemize{ 63 | \item \url{https://docs.ropensci.org/rerddap/} 64 | \item \url{https://github.com/ropensci/rerddap} 65 | \item Report bugs at \url{https://github.com/ropensci/rerddap/issues} 66 | } 67 | 68 | } 69 | \author{ 70 | \strong{Maintainer}: Roy Mendelssohn \email{roy.mendelssohn@noaa.gov} [contributor] 71 | 72 | Authors: 73 | \itemize{ 74 | \item Scott Chamberlain 75 | } 76 | 77 | Other contributors: 78 | \itemize{ 79 | \item Ben Tupper [contributor] 80 | \item Salvador Jesús Fernández Bejarano [contributor] 81 | } 82 | 83 | } 84 | \keyword{internal} 85 | -------------------------------------------------------------------------------- /man/servers.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/servers.R 3 | \name{servers} 4 | \alias{servers} 5 | \title{ERDDAP server URLS and other info} 6 | \usage{ 7 | servers(...) 8 | } 9 | \arguments{ 10 | \item{...}{curl options passed on to \link[crul:verb-GET]{crul::verb-GET}} 11 | } 12 | \value{ 13 | data.frame with 3 columns: 14 | \itemize{ 15 | \item name (character): ERDDAP name 16 | \item url (character): ERDDAP url 17 | \item public (logical): whether it's public or not 18 | } 19 | } 20 | \description{ 21 | ERDDAP server URLS and other info 22 | } 23 | \examples{ 24 | \dontrun{ 25 | servers() 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /man/standardnames.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rerddap-package.r 3 | \docType{data} 4 | \name{standardnames} 5 | \alias{standardnames} 6 | \title{standardnames} 7 | \format{ 8 | A character vector 9 | } 10 | \description{ 11 | standardnames 12 | } 13 | \keyword{datasets} 14 | -------------------------------------------------------------------------------- /man/tabledap.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/table.R 3 | \name{tabledap} 4 | \alias{tabledap} 5 | \title{Get ERDDAP™ tabledap data.} 6 | \usage{ 7 | tabledap( 8 | x, 9 | ..., 10 | fields = NULL, 11 | distinct = FALSE, 12 | orderby = NULL, 13 | orderbymax = NULL, 14 | orderbymin = NULL, 15 | orderbyminmax = NULL, 16 | units = NULL, 17 | fmt = "csv", 18 | url = eurl(), 19 | store = disk(), 20 | callopts = list() 21 | ) 22 | } 23 | \arguments{ 24 | \item{x}{Anything coercable to an object of class info. So the output of 25 | a call to \code{\link[=info]{info()}}, or a datasetid, which will internally be passed 26 | through \code{\link[=info]{info()}}} 27 | 28 | \item{...}{Any number of key-value pairs in quotes as query constraints. 29 | See Details & examples} 30 | 31 | \item{fields}{Columns to return, as a character vector} 32 | 33 | \item{distinct}{If \code{TRUE} ERDDAP™ will sort all of the rows in the results 34 | table (starting with the first requested variable, then using the second 35 | requested variable if the first variable has a tie, ...), then remove all 36 | non-unique rows of data. In many situations, ERDDAP™ can return distinct 37 | values quickly and efficiently. But in some cases, ERDDAP™ must look through 38 | all rows of the source dataset.} 39 | 40 | \item{orderby}{If used, ERDDAP™ will sort all of the rows in the results 41 | table (starting with the first variable, then using the second variable 42 | if the first variable has a tie, ...). Normally, the rows of data in the 43 | response table are in the order they arrived from the data source. orderBy 44 | allows you to request that the results table be sorted in a specific way. 45 | For example, use \code{orderby=c("stationID,time")} to get the results 46 | sorted by stationID, then time. The orderby variables MUST be included in 47 | the list of requested variables in the fields parameter.} 48 | 49 | \item{orderbymax}{Give a vector of one or more fields, that must be included 50 | in the fields parameter as well. Gives back data given constraints. ERDDAP™ 51 | will sort all of the rows in the results table (starting with the first 52 | variable, then using the second variable if the first variable has a 53 | tie, ...) and then just keeps the rows where the value of the last sort 54 | variable is highest (for each combination of other values).} 55 | 56 | \item{orderbymin}{Same as \code{orderbymax} parameter, except returns 57 | minimum value.} 58 | 59 | \item{orderbyminmax}{Same as \code{orderbymax} parameter, except returns 60 | two rows for every combination of the n-1 variables: one row with the 61 | minimum value, and one row with the maximum value.} 62 | 63 | \item{units}{One of 'udunits' (units will be described via the UDUNITS 64 | standard (e.g.,degrees_C)) or 'ucum' (units will be described via the 65 | UCUM standard (e.g., Cel)).} 66 | 67 | \item{fmt}{whether download should be as '.csv' (default) or '.parquet'} 68 | 69 | \item{url}{A URL for an ERDDAP™ server. 70 | Default: https://upwell.pfeg.noaa.gov/erddap/ - See \code{\link[=eurl]{eurl()}} for 71 | more information} 72 | 73 | \item{store}{One of \code{disk} (default) or \code{memory}. You can pass 74 | options to \code{disk}} 75 | 76 | \item{callopts}{Curl options passed on to \link[crul:verb-GET]{crul::verb-GET} (must be 77 | named parameters)} 78 | } 79 | \value{ 80 | An object of class \code{tabledap}. This class is a thin wrapper 81 | around a data.frame, so the data you get back is a data.frame with metadata 82 | attached as attributes (datasetid, path (path where the csv is stored on 83 | your machine), url (url for the request)) 84 | } 85 | \description{ 86 | Get ERDDAP™ tabledap data. 87 | } 88 | \details{ 89 | For key-value pair query constraints, the valid operators are =, 90 | != (not equals), =~ (a regular expression test), <, <=, >, and >= . For 91 | regular expressions you need to add a regular expression. For others, nothing 92 | more is needed. Construct the entry like \code{'time>=2001-07-07'} with the 93 | parameter on the left, value on the right, and the operator in the middle, 94 | all within a set of quotes. Since ERDDAP accepts values other than \code{=}, 95 | we can't simply do \code{time = '2001-07-07'} as we normally would. 96 | 97 | Server-side functionality: Some tasks are done server side. You don't have 98 | to worry about what that means. They are provided via parameters in this 99 | function. See \code{distinct}, \code{orderby}, \code{orderbymax}, 100 | \code{orderbymin}, \code{orderbyminmax}, and \code{units}. 101 | 102 | Data is cached based on all parameters you use to get a dataset, including 103 | base url, query parameters. If you make the same exact call in the same or 104 | a different R session, as long you don't clear the cache, the function only 105 | reads data from disk, and does not have to request the data from the web 106 | again. 107 | 108 | If you run into an error like "HTTP Status 500 - There was a (temporary?) 109 | problem. Wait a minute, then try again.". it's likely they are hitting 110 | up against a size limit, and they should reduce the amount of data they 111 | are requesting either via space, time, or variables. Pass in 112 | \code{config = verbose()} to the request, and paste the URL into your 113 | browser to see if the output is garbled to examine if there's a problem 114 | with servers or this package 115 | } 116 | \examples{ 117 | \dontrun{ 118 | # Just passing the datasetid without fields gives all columns back 119 | tabledap('erdCinpKfmBT') 120 | 121 | # Pass time constraints 122 | tabledap('erdCinpKfmBT', 'time>=2006-08-24') 123 | 124 | # Pass in fields (i.e., columns to retrieve) & time constraints 125 | tabledap('erdCinpKfmBT', 126 | fields = c('longitude', 'latitude', 'Aplysia_californica_Mean_Density'), 127 | 'time>=2006-08-24' 128 | ) 129 | 130 | # Get info on a datasetid, then get data given information learned 131 | info('erdCalCOFIlrvsiz')$variables 132 | tabledap('erdCalCOFIlrvsiz', fields=c('latitude','longitude','larvae_size', 133 | 'itis_tsn'), 'time>=2011-10-25', 'time<=2011-10-31') 134 | 135 | # An example workflow 136 | ## Search for data 137 | (out <- ed_search(query='fish', which = 'table')) 138 | ## Using a datasetid, search for information on a datasetid 139 | id <- out$alldata[[1]]$dataset_id 140 | vars <- info(id)$variables 141 | ## Get data from the dataset 142 | vars$variable_name[1:3] 143 | tabledap(id, fields = vars$variable_name[1:3]) 144 | 145 | # Time constraint 146 | ## Limit by time with date only 147 | (info <- info('erdCinpKfmBT')) 148 | tabledap(info, fields = c( 149 | 'latitude','longitude','Haliotis_fulgens_Mean_Density'), 150 | 'time>=2001-07-14') 151 | 152 | # Use distinct parameter - compare to distinct = FALSE 153 | tabledap('sg114_3', 154 | fields=c('longitude','latitude','trajectory'), 155 | 'time>=2008-12-05', distinct = TRUE) 156 | 157 | # Use units parameter 158 | ## In this example, values are the same, but sometimes they can be different 159 | ## given the units value passed 160 | tabledap('erdCinpKfmT', fields=c('longitude','latitude','time','temperature'), 161 | 'time>=2007-09-19', 'time<=2007-09-21', units='udunits') 162 | tabledap('erdCinpKfmT', fields=c('longitude','latitude','time','temperature'), 163 | 'time>=2007-09-19', 'time<=2007-09-21', units='ucum') 164 | 165 | # Use orderby parameter 166 | tabledap('erdCinpKfmT', fields=c('longitude','latitude','time','temperature'), 167 | 'time>=2007-09-19', 'time<=2007-09-21', orderby='temperature') 168 | # Use orderbymax parameter 169 | tabledap('erdCinpKfmT', fields=c('longitude','latitude','time','temperature'), 170 | 'time>=2007-09-19', 'time<=2007-09-21', orderbymax='temperature') 171 | # Use orderbymin parameter 172 | tabledap('erdCinpKfmT', fields=c('longitude','latitude','time','temperature'), 173 | 'time>=2007-09-19', 'time<=2007-09-21', orderbymin='temperature') 174 | # Use orderbyminmax parameter 175 | tabledap('erdCinpKfmT', fields=c('longitude','latitude','time','temperature'), 176 | 'time>=2007-09-19', 'time<=2007-09-21', orderbyminmax='temperature') 177 | # Use orderbymin parameter with multiple values 178 | tabledap('erdCinpKfmT', 179 | fields=c('longitude','latitude','time','depth','temperature'), 180 | 'time>=2007-06-10', 'time<=2007-09-21', 181 | orderbymax=c('depth','temperature') 182 | ) 183 | 184 | # Integrate with taxize 185 | out <- tabledap('erdCalCOFIlrvcntHBtoHI', 186 | fields = c('latitude','longitude','scientific_name','itis_tsn'), 187 | 'time>=2007-06-10', 'time<=2007-09-21' 188 | ) 189 | tsns <- unique(out$itis_tsn[1:100]) 190 | library("taxize") 191 | classif <- classification(tsns, db = "itis") 192 | head(rbind(classif)); tail(rbind(classif)) 193 | 194 | # Write to memory (within R), or to disk 195 | (out <- info('erdCinpKfmBT')) 196 | ## disk, by default (to prevent bogging down system w/ large datasets) 197 | ## the 2nd call is much faster as it's mostly just the time of reading 198 | ## in the table from disk 199 | system.time( tabledap('erdCinpKfmBT', store = disk()) ) 200 | system.time( tabledap('erdCinpKfmBT', store = disk()) ) 201 | ## memory 202 | tabledap('erdCinpKfmBT', store = memory()) 203 | 204 | # use a different ERDDAP™ server 205 | ## NOAA IOOS NERACOOS 206 | url <- "http://www.neracoos.org/erddap/" 207 | tabledap("E01_optics_hist", url = url) 208 | } 209 | } 210 | \references{ 211 | https://upwell.pfeg.noaa.gov/erddap/index.html 212 | } 213 | -------------------------------------------------------------------------------- /man/variablenames.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rerddap-package.r 3 | \docType{data} 4 | \name{variablenames} 5 | \alias{variablenames} 6 | \title{variablenames} 7 | \format{ 8 | A character vector 9 | } 10 | \description{ 11 | variablenames 12 | } 13 | \keyword{datasets} 14 | -------------------------------------------------------------------------------- /man/version.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/version.R 3 | \name{version} 4 | \alias{version} 5 | \title{Get ERDDAP version} 6 | \usage{ 7 | version(url = eurl(), ...) 8 | } 9 | \arguments{ 10 | \item{url}{A URL for an ERDDAP server. Default: 11 | https://upwell.pfeg.noaa.gov/erddap/ - See \code{\link[=eurl]{eurl()}} for 12 | more information} 13 | 14 | \item{...}{Curl options passed on to \link[crul:verb-GET]{crul::verb-GET}} 15 | } 16 | \description{ 17 | Get ERDDAP version 18 | } 19 | \examples{ 20 | \dontrun{ 21 | version() 22 | ss <- servers() 23 | version(ss$url[2]) 24 | version(ss$url[3]) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /rerddap.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | ProjectId: 49713019-2203-4283-bf43-941360ea1a11 3 | 4 | RestoreWorkspace: Default 5 | SaveWorkspace: Default 6 | AlwaysSaveHistory: Default 7 | 8 | EnableCodeIndexing: Yes 9 | UseSpacesForTab: Yes 10 | NumSpacesForTab: 2 11 | Encoding: UTF-8 12 | 13 | RnwWeave: Sweave 14 | LaTeX: pdfLaTeX 15 | 16 | BuildType: Package 17 | PackageUseDevtools: Yes 18 | PackageInstallArgs: --no-multiarch --with-keep.source 19 | -------------------------------------------------------------------------------- /revdep/README.md: -------------------------------------------------------------------------------- 1 | # Platform 2 | 3 | |field |value | 4 | |:--------|:-------------------------------------------| 5 | |version |R version 4.0.4 Patched (2021-02-17 r80031) | 6 | |os |macOS Big Sur 10.16 | 7 | |system |x86_64, darwin17.0 | 8 | |ui |X11 | 9 | |language |(EN) | 10 | |collate |en_US.UTF-8 | 11 | |ctype |en_US.UTF-8 | 12 | |tz |US/Pacific | 13 | |date |2021-03-05 | 14 | 15 | # Dependencies 16 | 17 | |package |old |new |Δ | 18 | |:---------|:-----|:--------|:--| 19 | |rerddap |0.7.0 |0.7.1.92 |* | 20 | |cli |NA |2.3.1 |* | 21 | |crul |NA |1.1.0 |* | 22 | |dplyr |NA |1.0.4 |* | 23 | |lifecycle |NA |1.0.0 |* | 24 | |pillar |NA |1.5.1 |* | 25 | |tibble |NA |3.1.0 |* | 26 | 27 | # Revdeps 28 | 29 | -------------------------------------------------------------------------------- /revdep/failures.md: -------------------------------------------------------------------------------- 1 | *Wow, no problems at all. :)* -------------------------------------------------------------------------------- /revdep/problems.md: -------------------------------------------------------------------------------- 1 | *Wow, no problems at all. :)* -------------------------------------------------------------------------------- /vignettes/CPSPlot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci/rerddap/429d1829eaa9371513431cbd3738c67792a46163/vignettes/CPSPlot-1.png -------------------------------------------------------------------------------- /vignettes/CPSPlot-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci/rerddap/429d1829eaa9371513431cbd3738c67792a46163/vignettes/CPSPlot-2.png -------------------------------------------------------------------------------- /vignettes/MUR_sst.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci/rerddap/429d1829eaa9371513431cbd3738c67792a46163/vignettes/MUR_sst.png -------------------------------------------------------------------------------- /vignettes/NAtlSSS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci/rerddap/429d1829eaa9371513431cbd3738c67792a46163/vignettes/NAtlSSS.png -------------------------------------------------------------------------------- /vignettes/NDBC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci/rerddap/429d1829eaa9371513431cbd3738c67792a46163/vignettes/NDBC.png -------------------------------------------------------------------------------- /vignettes/NDBCTS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci/rerddap/429d1829eaa9371513431cbd3738c67792a46163/vignettes/NDBCTS.png -------------------------------------------------------------------------------- /vignettes/VIIIRS_chla.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci/rerddap/429d1829eaa9371513431cbd3738c67792a46163/vignettes/VIIIRS_chla.png -------------------------------------------------------------------------------- /vignettes/VIIRS_chla.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci/rerddap/429d1829eaa9371513431cbd3738c67792a46163/vignettes/VIIRS_chla.png -------------------------------------------------------------------------------- /vignettes/VIIRS_sst.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci/rerddap/429d1829eaa9371513431cbd3738c67792a46163/vignettes/VIIRS_sst.png -------------------------------------------------------------------------------- /vignettes/VIIRS_sst_series.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci/rerddap/429d1829eaa9371513431cbd3738c67792a46163/vignettes/VIIRS_sst_series.png -------------------------------------------------------------------------------- /vignettes/atn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci/rerddap/429d1829eaa9371513431cbd3738c67792a46163/vignettes/atn.png -------------------------------------------------------------------------------- /vignettes/calCOFIPlot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci/rerddap/429d1829eaa9371513431cbd3738c67792a46163/vignettes/calCOFIPlot-1.png -------------------------------------------------------------------------------- /vignettes/calCOFIPlot-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci/rerddap/429d1829eaa9371513431cbd3738c67792a46163/vignettes/calCOFIPlot-2.png -------------------------------------------------------------------------------- /vignettes/coho_anomaly.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci/rerddap/429d1829eaa9371513431cbd3738c67792a46163/vignettes/coho_anomaly.png -------------------------------------------------------------------------------- /vignettes/glider.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci/rerddap/429d1829eaa9371513431cbd3738c67792a46163/vignettes/glider.png -------------------------------------------------------------------------------- /vignettes/ifrPSA.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci/rerddap/429d1829eaa9371513431cbd3738c67792a46163/vignettes/ifrPSA.png -------------------------------------------------------------------------------- /vignettes/maxslp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci/rerddap/429d1829eaa9371513431cbd3738c67792a46163/vignettes/maxslp.png -------------------------------------------------------------------------------- /vignettes/rerddap.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: rerddap introduction 3 | author: Scott Chamberlain 4 | date: "2023-06-29" 5 | output: rmarkdown::html_vignette 6 | vignette: > 7 | %\VignetteIndexEntry{rerddap introduction} 8 | %\VignetteEngine{knitr::rmarkdown} 9 | %\VignetteEncoding{UTF-8} 10 | --- 11 | 12 | 13 | 14 | 15 | `rerddap` is a general purpose R client for working with ERDDAP™ servers. ERDDAP™ is a server built on top of OPenDAP, which serves some NOAA data. You can get gridded data ([griddap](https://upwell.pfeg.noaa.gov/erddap/griddap/documentation.html)), which lets you query from gridded datasets, or table data ([tabledap](https://upwell.pfeg.noaa.gov/erddap/tabledap/documentation.html)) which lets you query from tabular datasets. In terms of how we interface with them, there are similarties, but some differences too. We try to make a similar interface to both data types in `rerddap`. 16 | 17 | ## NetCDF 18 | 19 | `rerddap` supports NetCDF format, and is the default when using the `griddap()` function. NetCDF is a binary file format, and will have a much smaller footprint on your disk than csv. The binary file format means it's harder to inspect, but the `ncdf4` package makes it easy to pull data out and write data back into a NetCDF file. Note the the file extension for NetCDF files is `.nc`. Whether you choose NetCDF or csv for small files won't make much of a difference, but will with large files. 20 | 21 | ## Caching 22 | 23 | Data files downloaded are cached in a single hidden directory `~/.rerddap` on your machine. It's hidden so that you don't accidentally delete the data, but you can still easily delete the data if you like. 24 | 25 | When you use `griddap()` or `tabledap()` functions, we construct a MD5 hash from the base URL, and any query parameters - this way each query is separately cached. Once we have the hash, we look in `~/.rerddap` for a matching hash. If there's a match we use that file on disk - if no match, we make a http request for the data to the ERDDAP™ server you specify. 26 | 27 | ## ERDDAP™ servers 28 | 29 | You can get a data.frame of ERDDAP™ servers using the function `servers()`. The list of ERDDAP™ servers is drawn from the *Awesome ERDDAP™* page maintained by the Irish Marine Institute . If you know of more ERDDAP™ servers, follow the instructions on that page to add the server. 30 | 31 | ## Install 32 | 33 | Stable version from CRAN 34 | 35 | 36 | ```r 37 | install.packages("rerddap") 38 | ``` 39 | 40 | Or, the development version from GitHub 41 | 42 | 43 | ```r 44 | remotes::install_github("ropensci/rerddap") 45 | ``` 46 | 47 | 48 | ```r 49 | library("rerddap") 50 | ``` 51 | 52 | ## Search 53 | 54 | First, you likely want to search for data, specify either `griddadp` or `tabledap` 55 | 56 | 57 | ```r 58 | ed_search(query = 'size', which = "table") 59 | #> # A tibble: 36 × 2 60 | #> title dataset_id 61 | #> 62 | #> 1 CCE Prey Size and Hard Part Size Regressions mmtdPreyS… 63 | #> 2 CCE Teleost Prey Size and Hard Part Size Measurements mmtdTeleo… 64 | #> 3 CalCOFI Larvae Sizes erdCalCOF… 65 | #> 4 CCE Non-Teleost Prey Size and Hard Part Size Measurements mmtdNonTe… 66 | #> 5 Channel Islands, Kelp Forest Monitoring, Size and Frequency, Natu… erdCinpKf… 67 | #> 6 File Names from the AWS S3 noaa-goes16 Bucket awsS3Noaa… 68 | #> 7 File Names from the AWS S3 noaa-goes17 Bucket awsS3Noaa… 69 | #> 8 PacIOOS Beach Camera 001: Waikiki, Oahu, Hawaii BEACHCAM-… 70 | #> 9 PacIOOS Beach Camera 003: Waimea Bay, Oahu, Hawaii BEACHCAM-… 71 | #> 10 PacIOOS Beach Camera 004: Waimea Bay (Offshore), Oahu, Hawaii BEACHCAM-… 72 | #> # ℹ 26 more rows 73 | ``` 74 | 75 | 76 | ```r 77 | ed_search(query = 'size', which = "grid") 78 | #> # A tibble: 103 × 2 79 | #> title dataset_id 80 | #> 81 | #> 1 Audio data from a local source. testGridW… 82 | #> 2 Main Hawaiian Islands Multibeam Bathymetry Synthesis: 50-m Bathym… hmrg_bath… 83 | #> 3 Main Hawaiian Islands Multibeam Bathymetry Synthesis: 50-m Bathym… hmrg_bath… 84 | #> 4 Coastal Upwelling Transport Index (CUTI), Daily erdCUTIda… 85 | #> 5 SST smoothed frontal gradients FRD_SSTgr… 86 | #> 6 Coastal Upwelling Transport Index (CUTI), Monthly erdCUTImo… 87 | #> 7 SST smoothed frontal gradients, Lon0360 FRD_SSTgr… 88 | #> 8 Biologically Effective Upwelling Transport Index (BEUTI), Daily erdBEUTId… 89 | #> 9 Biologically Effective Upwelling Transport Index (BEUTI), Monthly erdBEUTIm… 90 | #> 10 Daily averaged and put on grid 4x daily NCEP reanalysis (psi.2012) noaa_psl_… 91 | #> # ℹ 93 more rows 92 | ``` 93 | 94 | There is now a convenience function to search over a list of ERDDAP™ servers, designed to work with the function `servers()` 95 | 96 | 97 | ```r 98 | server_list <- c( 99 | emodnet_physics = 'https://erddap.emodnet-physics.eu/erddap/', 100 | irish_marine_institute = 'https://erddap.marine.ie/erddap/' 101 | ) 102 | global_search(query = 'size', server_list, 'griddap') 103 | #> title 104 | #> 1 EMODnet Physics - Total Suspended Matter - GridSeriesObservation - Concentration of total suspended matter - BALTIC SEA 105 | #> 2 EMODnet Physics - Total Suspended Matter - GridSeriesObservation - Concentration of total suspended matter - MEDITERRANEAN SEA 106 | #> 3 EMODnet Physics - Total Suspended Matter - GridSeriesObservation - Concentration of total suspended matter - MEDITERRANEAN SEA - LOW RESOLUTION 107 | #> 4 EMODnet Physics - TEMPERATURE YEARLY RECORDING DENSITY 108 | #> 5 EMODPACE - Monthly sea level derived from CMEMS-DUACS (DT-2018) satellite altimetry (1993-2019) 109 | #> 6 EMODnet Physics - Total Suspended Matter - GridSeriesObservation - Concentration of total suspended matter - NORTH SEA 110 | #> 7 EMODPACE - Absolute sea level trend (1993 – 2019) - derived from CMEMS-DUACS (DT-2018) satellite altimetry 111 | #> 8 EMODPACE - Sea Level monthly mean, EurAsia. This product is based, uses and reprocess the CMEMS product id. SEALEVEL_GLO_PHY_CLIMATE_L4_REP_OBSERVATIONS_008_057 112 | #> 9 COMPASS-NEATL Hindcast 2016-2020 113 | #> dataset_id 114 | #> 1 TSM_BALTICSEA 115 | #> 2 TSM_MBSEA 116 | #> 3 TSM_MBSEA_LOWRESOLUTION 117 | #> 4 ERD_EP_TEMP_DNS 118 | #> 5 EMODPACE_SLEV_MONTHLY_MEAN_DESEASONALIZED 119 | #> 6 TSM_NORTHSEA 120 | #> 7 EMODPACE_SLEV_TREND 121 | #> 8 EMODPACE_SLEV_MONTHLY_MEAN 122 | #> 9 compass_neatl_hindcast_grid 123 | #> url 124 | #> 1 https://erddap.emodnet-physics.eu/erddap/ 125 | #> 2 https://erddap.emodnet-physics.eu/erddap/ 126 | #> 3 https://erddap.emodnet-physics.eu/erddap/ 127 | #> 4 https://erddap.emodnet-physics.eu/erddap/ 128 | #> 5 https://erddap.emodnet-physics.eu/erddap/ 129 | #> 6 https://erddap.emodnet-physics.eu/erddap/ 130 | #> 7 https://erddap.emodnet-physics.eu/erddap/ 131 | #> 8 https://erddap.emodnet-physics.eu/erddap/ 132 | #> 9 https://erddap.marine.ie/erddap/ 133 | ``` 134 | 135 | ## Information 136 | 137 | Then you can get information on a single dataset 138 | 139 | 140 | ```r 141 | info('erdCalCOFIlrvsiz') 142 | #> erdCalCOFIlrvsiz 143 | #> Base URL: https://upwell.pfeg.noaa.gov/erddap 144 | #> Dataset Type: tabledap 145 | #> Variables: 146 | #> calcofi_species_code: 147 | #> Range: 19, 946 148 | #> common_name: 149 | #> cruise: 150 | #> itis_tsn: 151 | #> larvae_10m2: 152 | ... 153 | ``` 154 | 155 | ## griddap (gridded) data 156 | 157 | First, get information on a dataset to see time range, lat/long range, and variables. 158 | 159 | 160 | ```r 161 | (out <- info('erdMBchla1day')) 162 | #> erdMBchla1day 163 | #> Base URL: https://upwell.pfeg.noaa.gov/erddap 164 | #> Dataset Type: griddap 165 | #> Dimensions (range): 166 | #> time: (2006-01-01T12:00:00Z, 2023-06-27T12:00:00Z) 167 | #> altitude: (0.0, 0.0) 168 | #> latitude: (-45.0, 65.0) 169 | #> longitude: (120.0, 320.0) 170 | #> Variables: 171 | #> chlorophyll: 172 | #> Units: mg m-3 173 | ``` 174 | 175 | Then query for gridded data using the `griddap()` function 176 | 177 | 178 | ```r 179 | (res <- griddap(out, 180 | time = c('2015-01-01','2015-01-03'), 181 | latitude = c(14, 15), 182 | longitude = c(125, 126) 183 | )) 184 | #> erdMBchla1day 185 | #> Path: [/var/folders/xw/mcmsdzzx4mgbttplylgs7ysh0000gp/T//RtmpoME6FV/R/rerddap/4d844aa48552049c3717ac94ced5f9b8.nc] 186 | #> Last updated: [2023-06-29 13:18:53.945082] 187 | #> File size: [0.03 mb] 188 | #> Dimensions (dims/vars): [4 X 1] 189 | #> Dim names: time, altitude, latitude, longitude 190 | #> Variable names: Chlorophyll Concentration in Sea Water 191 | #> data.frame (rows/columns): [5043 X 5] 192 | #> # A tibble: 5,043 × 5 193 | #> longitude latitude altitude time chlorophyll 194 | #> 195 | #> 1 125 14 0 2015-01-01T12:00:00Z NA 196 | #> 2 125. 14 0 2015-01-01T12:00:00Z NA 197 | #> 3 125. 14 0 2015-01-01T12:00:00Z NA 198 | #> 4 125. 14 0 2015-01-01T12:00:00Z NA 199 | #> 5 125. 14 0 2015-01-01T12:00:00Z NA 200 | #> 6 125. 14 0 2015-01-01T12:00:00Z NA 201 | #> 7 125. 14 0 2015-01-01T12:00:00Z NA 202 | #> 8 125. 14 0 2015-01-01T12:00:00Z NA 203 | #> 9 125. 14 0 2015-01-01T12:00:00Z NA 204 | #> 10 125. 14 0 2015-01-01T12:00:00Z NA 205 | #> # ℹ 5,033 more rows 206 | ``` 207 | 208 | The output of `griddap()` is a list that you can explore further. Get the summary 209 | 210 | 211 | ```r 212 | res$summary 213 | #> $filename 214 | #> [1] "/var/folders/xw/mcmsdzzx4mgbttplylgs7ysh0000gp/T//RtmpoME6FV/R/rerddap/4d844aa48552049c3717ac94ced5f9b8.nc" 215 | #> 216 | #> $writable 217 | #> [1] FALSE 218 | #> 219 | #> $id 220 | #> [1] 65536 221 | #> 222 | #> $error 223 | #> [1] FALSE 224 | #> 225 | #> $safemode 226 | #> [1] FALSE 227 | #> 228 | ... 229 | ``` 230 | 231 | Get the dimension variables 232 | 233 | 234 | ```r 235 | names(res$summary$dim) 236 | #> [1] "time" "altitude" "latitude" "longitude" 237 | ``` 238 | 239 | Get the data.frame (beware: you may want to just look at the `head` of the data.frame if large) 240 | 241 | 242 | ```r 243 | head(res$data) 244 | #> longitude latitude altitude time chlorophyll 245 | #> 1 125.000 14 0 2015-01-01T12:00:00Z NA 246 | #> 2 125.025 14 0 2015-01-01T12:00:00Z NA 247 | #> 3 125.050 14 0 2015-01-01T12:00:00Z NA 248 | #> 4 125.075 14 0 2015-01-01T12:00:00Z NA 249 | #> 5 125.100 14 0 2015-01-01T12:00:00Z NA 250 | #> 6 125.125 14 0 2015-01-01T12:00:00Z NA 251 | ``` 252 | 253 | ## tabledap (tabular) data 254 | 255 | 256 | ```r 257 | (out <- info('erdCalCOFIlrvsiz')) 258 | #> erdCalCOFIlrvsiz 259 | #> Base URL: https://upwell.pfeg.noaa.gov/erddap 260 | #> Dataset Type: tabledap 261 | #> Variables: 262 | #> calcofi_species_code: 263 | #> Range: 19, 946 264 | #> common_name: 265 | #> cruise: 266 | #> itis_tsn: 267 | #> larvae_10m2: 268 | ... 269 | ``` 270 | 271 | 272 | ```r 273 | (dat <- tabledap('erdCalCOFIlrvsiz', fields=c('latitude','longitude','larvae_size', 274 | 'scientific_name'), 'time>=2011-01-01', 'time<=2011-12-31')) 275 | #> erdCalCOFIlrvsiz 276 | #> Path: [/var/folders/xw/mcmsdzzx4mgbttplylgs7ysh0000gp/T//RtmpoME6FV/R/rerddap/db7389db5b5b0ed9c426d5c13bc43d18.csv] 277 | #> Last updated: [2023-06-29 13:18:57.579066] 278 | #> File size: [0.05 mb] 279 | #> # A tibble: 1,304 × 4 280 | #> latitude longitude larvae_size scientific_name 281 | #> 282 | #> 1 32.956665 -117.305 4.5 Engraulis mordax 283 | #> 2 32.91 -117.4 5.0 Merluccius productus 284 | #> 3 32.511665 -118.21167 2.0 Merluccius productus 285 | #> 4 32.511665 -118.21167 3.0 Merluccius productus 286 | #> 5 32.511665 -118.21167 5.5 Merluccius productus 287 | #> 6 32.511665 -118.21167 6.0 Merluccius productus 288 | #> 7 32.511665 -118.21167 2.8 Merluccius productus 289 | #> 8 32.511665 -118.21167 3.0 Sardinops sagax 290 | #> 9 32.511665 -118.21167 5.0 Sardinops sagax 291 | #> 10 32.511665 -118.21167 2.5 Engraulis mordax 292 | #> # ℹ 1,294 more rows 293 | ``` 294 | 295 | Since both `griddap()` and `tabledap()` give back data.frame's, it's easy to do downstream manipulation. For example, we can use `dplyr` to filter, summarize, group, and sort: 296 | 297 | 298 | ```r 299 | library("dplyr") 300 | dat$larvae_size <- as.numeric(dat$larvae_size) 301 | dat %>% 302 | group_by(scientific_name) %>% 303 | summarise(mean_size = mean(larvae_size)) %>% 304 | arrange(desc(mean_size)) 305 | #> # A tibble: 7 × 2 306 | #> scientific_name mean_size 307 | #> 308 | #> 1 Anoplopoma fimbria 23.3 309 | #> 2 Engraulis mordax 9.26 310 | #> 3 Sardinops sagax 7.28 311 | #> 4 Merluccius productus 5.48 312 | #> 5 Tactostoma macropus 5 313 | #> 6 Scomber japonicus 3.4 314 | #> 7 Trachurus symmetricus 3.29 315 | ``` 316 | -------------------------------------------------------------------------------- /vignettes/rerddap.Rmd.og: -------------------------------------------------------------------------------- 1 | --- 2 | title: rerddap introduction 3 | author: Scott Chamberlain 4 | date: "`r Sys.Date()`" 5 | output: rmarkdown::html_vignette 6 | vignette: > 7 | %\VignetteIndexEntry{rerddap introduction} 8 | %\VignetteEngine{knitr::rmarkdown} 9 | %\VignetteEncoding{UTF-8} 10 | --- 11 | 12 | ```{r echo=FALSE} 13 | library("knitr") 14 | hook_output <- knitr::knit_hooks$get("output") 15 | knitr::knit_hooks$set(output = function(x, options) { 16 | lines <- options$output.lines 17 | if (is.null(lines)) { 18 | return(hook_output(x, options)) # pass to default hook 19 | } 20 | x <- unlist(strsplit(x, "\n")) 21 | more <- "..." 22 | if (length(lines) == 1) { # first n lines 23 | if (length(x) > lines) { 24 | # truncate the output, but add .... 25 | x <- c(head(x, lines), more) 26 | } 27 | } else { 28 | x <- c(if (abs(lines[1]) > 1) more else NULL, 29 | x[lines], 30 | if (length(x) > lines[abs(length(lines))]) more else NULL 31 | ) 32 | } 33 | # paste these lines together 34 | x <- paste(c(x, ""), collapse = "\n") 35 | hook_output(x, options) 36 | }) 37 | 38 | knitr::opts_chunk$set( 39 | comment = "#>", 40 | collapse = TRUE, 41 | warning = FALSE, 42 | message = FALSE 43 | ) 44 | ``` 45 | 46 | 47 | `rerddap` is a general purpose R client for working with ERDDAP servers. ERDDAP is a server built on top of OPenDAP, which serves some NOAA data. You can get gridded data ([griddap](https://upwell.pfeg.noaa.gov/erddap/griddap/documentation.html)), which lets you query from gridded datasets, or table data ([tabledap](https://upwell.pfeg.noaa.gov/erddap/tabledap/documentation.html)) which lets you query from tabular datasets. In terms of how we interface with them, there are similarties, but some differences too. We try to make a similar interface to both data types in `rerddap`. 48 | 49 | ## NetCDF 50 | 51 | `rerddap` supports NetCDF format, and is the default when using the `griddap()` function. NetCDF is a binary file format, and will have a much smaller footprint on your disk than csv. The binary file format means it's harder to inspect, but the `ncdf4` package makes it easy to pull data out and write data back into a NetCDF file. Note the the file extension for NetCDF files is `.nc`. Whether you choose NetCDF or csv for small files won't make much of a difference, but will with large files. 52 | 53 | ## Caching 54 | 55 | Data files downloaded are cached in a single hidden directory `~/.rerddap` on your machine. It's hidden so that you don't accidentally delete the data, but you can still easily delete the data if you like. 56 | 57 | When you use `griddap()` or `tabledap()` functions, we construct a MD5 hash from the base URL, and any query parameters - this way each query is separately cached. Once we have the hash, we look in `~/.rerddap` for a matching hash. If there's a match we use that file on disk - if no match, we make a http request for the data to the ERDDAP server you specify. 58 | 59 | ## ERDDAP servers 60 | 61 | You can get a data.frame of ERDDAP servers using the function `servers()`. The list of ERDDAP servers is drawn from the *Awesome ERDDAP* page maintained by the Irish Marine Institute . If you know of more ERDDAP servers, follow the instructions on that page to add the server. 62 | 63 | ## Install 64 | 65 | Stable version from CRAN 66 | 67 | ```{r eval=FALSE} 68 | install.packages("rerddap") 69 | ``` 70 | 71 | Or, the development version from GitHub 72 | 73 | ```{r eval=FALSE} 74 | remotes::install_github("ropensci/rerddap") 75 | ``` 76 | 77 | ```{r} 78 | library("rerddap") 79 | ``` 80 | 81 | ## Search 82 | 83 | First, you likely want to search for data, specify either `griddadp` or `tabledap` 84 | 85 | ```{r} 86 | ed_search(query = 'size', which = "table") 87 | ``` 88 | 89 | ```{r} 90 | ed_search(query = 'size', which = "grid") 91 | ``` 92 | 93 | There is now a convenience function to search over a list of ERDDAP servers, designed to work with the function `servers()` 94 | 95 | ```{r} 96 | server_list <- c( 97 | emodnet_physics = 'https://erddap.emodnet-physics.eu/erddap/', 98 | irish_marine_institute = 'https://erddap.marine.ie/erddap/' 99 | ) 100 | global_search(query = 'size', server_list, 'griddap') 101 | ``` 102 | 103 | ## Information 104 | 105 | Then you can get information on a single dataset 106 | 107 | ```{r output.lines=1:10} 108 | info('erdCalCOFIlrvsiz') 109 | ``` 110 | 111 | ## griddap (gridded) data 112 | 113 | First, get information on a dataset to see time range, lat/long range, and variables. 114 | 115 | ```{r} 116 | (out <- info('erdMBchla1day')) 117 | ``` 118 | 119 | Then query for gridded data using the `griddap()` function 120 | 121 | ```{r} 122 | (res <- griddap(out, 123 | time = c('2015-01-01','2015-01-03'), 124 | latitude = c(14, 15), 125 | longitude = c(125, 126) 126 | )) 127 | ``` 128 | 129 | The output of `griddap()` is a list that you can explore further. Get the summary 130 | 131 | ```{r output.lines=1:15} 132 | res$summary 133 | ``` 134 | 135 | Get the dimension variables 136 | 137 | ```{r} 138 | names(res$summary$dim) 139 | ``` 140 | 141 | Get the data.frame (beware: you may want to just look at the `head` of the data.frame if large) 142 | 143 | ```{r} 144 | head(res$data) 145 | ``` 146 | 147 | ## tabledap (tabular) data 148 | 149 | ```{r output.lines=1:10} 150 | (out <- info('erdCalCOFIlrvsiz')) 151 | ``` 152 | 153 | ```{r} 154 | (dat <- tabledap('erdCalCOFIlrvsiz', fields=c('latitude','longitude','larvae_size', 155 | 'scientific_name'), 'time>=2011-01-01', 'time<=2011-12-31')) 156 | ``` 157 | 158 | Since both `griddap()` and `tabledap()` give back data.frame's, it's easy to do downstream manipulation. For example, we can use `dplyr` to filter, summarize, group, and sort: 159 | 160 | ```{r} 161 | library("dplyr") 162 | dat$larvae_size <- as.numeric(dat$larvae_size) 163 | dat %>% 164 | group_by(scientific_name) %>% 165 | summarise(mean_size = mean(larvae_size)) %>% 166 | arrange(desc(mean_size)) 167 | ``` 168 | -------------------------------------------------------------------------------- /vignettes/sardines.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci/rerddap/429d1829eaa9371513431cbd3738c67792a46163/vignettes/sardines.png -------------------------------------------------------------------------------- /vignettes/soda70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci/rerddap/429d1829eaa9371513431cbd3738c67792a46163/vignettes/soda70.png --------------------------------------------------------------------------------