Skip to content

Commit 514257e

Browse files
committed
Merge wiDButil
1 parent 7bd0a44 commit 514257e

22 files changed

+2073
-261
lines changed

.Rbuildignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@
1414
>>>>>>> 79146b21e9e5f977d8ddab23bba1f84504844c48
1515
^doc$
1616
^Meta$
17+
^Rdev$

.gitignore

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,39 @@
1-
.Rproj.user
1+
# History files
22
.Rhistory
3+
.Rapp.history
4+
5+
# Session Data files
36
.RData
4-
.Ruserdata
7+
8+
# User-specific files
9+
.Ruserdata
10+
11+
# Example code in package build process
12+
*-Ex.R
13+
14+
# Output files from R CMD build
15+
/*.tar.gz
16+
17+
# Output files from R CMD check
18+
/*.Rcheck/
19+
20+
# RStudio files
21+
.Rproj.user/
22+
23+
# produced vignettes
24+
vignettes/*.html
25+
vignettes/*.pdf
26+
27+
# OAuth2 token, see https://github.com/hadley/httr/releases/tag/v0.3
28+
.httr-oauth
29+
30+
# knitr and R markdown default cache directories
31+
*_cache/
32+
/cache/
33+
34+
# Temporary files created by R markdown
35+
*.utf8.md
36+
*.knit.md
37+
38+
# Downloads
39+
/downloads/

.travis.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ language: R
44
cache: packages
55
before_install:
66
- sudo apt-get install libgdal-dev
7-
- R -e 'install.packages("rgdal", repos=c("http://R-Forge.R-project.org", "http://cran.rstudio.com"))'
87

98
r_packages:
109
- covr

DESCRIPTION

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
Package: isoWater
22
Type: Package
3-
Title: Infer source of water using stable isotope data
4-
Version: 0.2.0.9000
5-
Author: Gabe Bowen
6-
Maintainer: Gabe Bowen <gabe.bowen@utah.edu>
7-
Description: Bayesian inference of the source and source isotope composition of water samples that may have experienced evaporation. Original algorithms presented in Bowen et al. (2018) <doi:10.1007/s00442-018-4192-5>.
8-
Imports: R2jags, parallel, abind, R2WinBUGS, doParallel, foreach
3+
Title: Discovery, Retrieval, and Analysis of Water Isotope Data
4+
Version: 0.2.1
5+
Authors@R: person("Gabriel", "Bowen", email = "gabe.bowen@utah.edu",
6+
role = c("aut", "cre"))
7+
Description: wiDB_ functions provide interface to the public API of
8+
the wiDB: build, check and submit queries, and receive and
9+
unpack responses. Data analysis functions support Bayesian
10+
inference of the source and source isotope composition of water
11+
samples that may have experienced evaporation. Algorithms
12+
adapted from Bowen et al. (2018) <doi:10.1007/s00442-018-4192-5>.
13+
Imports: R2jags, parallel, abind, R2WinBUGS, doParallel, foreach,
14+
httr, jsonlite
915
Depends: R (>= 3.5)
1016
Suggests:
1117
knitr,

NAMESPACE

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,16 @@ export(mwlSource)
22
export(mixSource)
33
export(mwl)
44
export(iso)
5+
export(wiDB_sites)
6+
export(wiDB_data)
7+
export(wiDB_values)
8+
importFrom(httr, GET, content)
9+
importFrom(jsonlite, fromJSON)
510
importFrom(doParallel, registerDoParallel, stopImplicitCluster)
611
importFrom(foreach, foreach, "%dopar%")
712
importFrom(R2jags, jags)
813
importFrom(R2WinBUGS, monitor)
914
importFrom(stats, sd, var)
1015
importFrom(graphics, abline, lines, par, points)
11-
importFrom(abind, abind)
16+
importFrom(abind, abind)
17+
importFrom(utils, read.csv, unzip)

NEWS.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
# isoWater news
22

3-
## isoWater 0.2.0.9000
4-
* Updated documentation
3+
## isoWater 0.2.1
4+
* Merged functions and documentation from wiDButil package
5+
* Updated documentation and vignette
6+
57

68
## isoWater 0.2.0
79
* Reformatted code to create package

R/constructors.R

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ mwl = function(HO, plot = TRUE){
2525
stop("Non-numeric values in HO")
2626
}
2727
ns = nrow(HO)
28+
HO = HO[!(is.na(HO[,1]) | is.na(HO[,2])),]
29+
if(nrow(HO) != ns){
30+
warning("Missing values removed from HO")
31+
}
2832
if(ns < 3){
2933
stop("At least 3 sample values required")
3034
}

R/watercomp.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ mwlSource = function(obs, MWL=c(8.01, 9.57, -8.096, 2564532.2, 5.76, 80672),
8989
#takes values of observed and hypothesized endmember source waters (each type 'iso'),hypothesized EL slope,
9090
#prior (as relative contribution of each source to mixture), and number of parameter draws
9191
mixSource = function(obs, sources, slope, prior=rep(1,nrow(sources)),
92-
shp=2, ngens=1e5, ncores = 1){
92+
shp=1, ngens=1e5, ncores = 1){
9393

9494
if(class(obs)[2] != "iso"){
9595
warning("Expecting iso object for obs, this argument may be

R/wiDBfunctions.R

Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
#####
2+
#Validate query input
3+
#####
4+
wiDB_validate = function(minLat, maxLat, minLong, maxLong, minElev, maxElev,
5+
minDate, maxDate, countries, states, types, projects){
6+
7+
qStr = ""
8+
9+
if(!is.null(minLat)){
10+
if(class(minLat) != "numeric"){stop("minLat must be numeric")}
11+
qStr = paste0(qStr, "&minLat=", minLat)
12+
}
13+
if(!is.null(maxLat)){
14+
if(class(maxLat) != "numeric"){stop("maxLat must be numeric")}
15+
qStr = paste0(qStr, "&maxLat=", maxLat)
16+
}
17+
if(!is.null(minLong)){
18+
if(class(minLong) != "numeric"){stop("minLong must be numeric")}
19+
qStr = paste0(qStr, "&minLong=", minLong)
20+
}
21+
if(!is.null(maxLong)){
22+
if(class(maxLong) != "numeric"){stop("maxLong must be numeric")}
23+
qStr = paste0(qStr, "&maxLong=", maxLong)
24+
}
25+
if(!is.null(minElev)){
26+
if(class(minElev) != "numeric"){stop("minElev must be numeric")}
27+
qStr = paste0(qStr, "&minElev=", minElev)
28+
}
29+
if(!is.null(maxElev)){
30+
if(class(maxElev) != "numeric"){stop("maxElev must be numeric")}
31+
qStr = paste0(qStr, "&maxElev=", maxElev)
32+
}
33+
if(!is.null(minDate)){
34+
if(class(minDate) != "character"){stop("minDate must be string")}
35+
td = c(as.numeric(substr(minDate, 1, 4)), as.numeric(substr(minDate, 6, 7)),
36+
as.numeric(substr(minDate, 9, 10)))
37+
if(NA %in% td){stop("minDate format must be YYYY-MM-DD")}
38+
qStr = paste0(qStr, "&minDate=", minDate)
39+
}
40+
if(!is.null(maxDate)){
41+
if(class(maxDate) != "character"){stop("maxDate must be string")}
42+
td = c(as.numeric(substr(maxDate, 1, 4)), as.numeric(substr(maxDate, 6, 7)),
43+
as.numeric(substr(maxDate, 9, 10)))
44+
if(NA %in% td){stop("maxDate format must be YYYY-MM-DD")}
45+
qStr = paste0(qStr, "&maxDate=", maxDate)
46+
}
47+
if(!is.null(countries)){
48+
if(class(countries) != "character"){stop("countries must be string")}
49+
countries = gsub(" ", "", countries)
50+
countries = gsub(" ", "", countries)
51+
if(length(countries > 1)){
52+
countries = paste0(countries, collapse = ",")
53+
}
54+
qStr = paste0(qStr, "&countries=", countries)
55+
}
56+
if(!is.null(states)){
57+
if(class(states) != "character"){stop("states must be string")}
58+
states = gsub(" ", "", states)
59+
states = gsub(" ", "", states)
60+
if(length(states > 1)){
61+
states = paste0(states, collapse = ",")
62+
}
63+
qStr = paste0(qStr, "&states=", states)
64+
}
65+
if(!is.null(types)){
66+
if(class(types) != "character"){stop("types must be string")}
67+
types = gsub(" ", "", types)
68+
types = gsub(" ", "", types)
69+
if(length(types > 1)){
70+
types = paste0(types, collapse = ",")
71+
}
72+
qStr = paste0(qStr, "&types=", types)
73+
}
74+
if(!is.null(projects)){
75+
if(class(projects) != "character"){stop("projects must be string")}
76+
projects = gsub(" ", "", projects)
77+
projects = gsub(" ", "", projects)
78+
if(length(types > 1)){
79+
types = paste0(types, collapse = ",")
80+
}
81+
qStr = paste0(qStr, "&projects=", projects)
82+
}
83+
84+
if(nchar(qStr) == 0){stop("No query arguments provided")}
85+
86+
qStr = paste0("?", substr(qStr, 2, nchar(qStr)))
87+
88+
return(qStr)
89+
}
90+
91+
#####
92+
#Find sites
93+
#####
94+
wiDB_sites = function(minLat = NULL, maxLat = NULL, minLong = NULL, maxLong = NULL,
95+
minElev = NULL, maxElev = NULL, minDate = NULL, maxDate = NULL,
96+
countries = NULL, states = NULL, types = NULL, projects = NULL){
97+
98+
qStr = wiDB_validate(minLat, maxLat, minLong, maxLong, minElev, maxElev,
99+
minDate, maxDate, countries, states, types, projects)
100+
101+
baseStr = "https://wateriso.utah.edu/api/v1/sites.php"
102+
q = paste0(baseStr, qStr)
103+
d = GET(q)
104+
105+
if(d$status_code != 200){stop(paste("Request returned error code", d$status_code))}
106+
107+
resp = fromJSON(content(d, as = "text", encoding = "UTF-8"))
108+
109+
if(length(resp$sites) == 0){
110+
warning("No sites returned")
111+
return(NULL)
112+
}
113+
114+
return(resp$sites)
115+
}
116+
117+
#####
118+
#Obtain data
119+
#####
120+
wiDB_data = function(minLat = NULL, maxLat = NULL, minLong = NULL, maxLong = NULL,
121+
minElev = NULL, maxElev = NULL, minDate = NULL, maxDate = NULL,
122+
countries = NULL, states = NULL, types = NULL, projects = NULL,
123+
fields = NULL, tmpdir = tempdir(), clean = TRUE){
124+
125+
qStr = wiDB_validate(minLat, maxLat, minLong, maxLong, minElev, maxElev,
126+
minDate, maxDate, countries, states, types, projects)
127+
128+
if(!dir.exists(tmpdir)){
129+
warning("Directory doesn't exist, trying to create")
130+
dir.create(tmpdir)
131+
if(!dir.exists(tmpdir)){stop("Unable to create directory")}
132+
}
133+
134+
if(class(clean) != "logical"){stop("clean must be TRUE/FALSE")}
135+
136+
flist = c("Site_ID", "Site_Name", "Latitude", "Longitude", "Elevation",
137+
"Sample_ID", "Type", "Start_Date", "Start_Time_Zone",
138+
"Collection_Date", "Collection_Time_Zone", "Phase",
139+
"Depth_meters", "Sample_Comments", "d2H", "d18O",
140+
"d2H_Analytical_SD", "d18O_Analytical_SD", "WI_Analysis_Source",
141+
"Project_ID")
142+
143+
if(!is.null(fields)){
144+
if(class(fields) != "character"){stop("fields must be a string")}
145+
fields = gsub(" ", "", fields)
146+
fields = gsub(" ", "", fields)
147+
fels = strsplit(fields, ",")
148+
fels = fels[[1]]
149+
for(i in 1:length(fels)){
150+
if(!(fels[i] %in% flist)){stop(paste("Value", i, "in fields is not a valid field name"))}
151+
}
152+
qStr = paste0(qStr, "&return=", fields)
153+
}
154+
155+
baseStr = "https://wateriso.utah.edu/api/v1/download.php"
156+
q = paste0(baseStr, qStr)
157+
g = GET(q)
158+
159+
if(g$status_code != 200){stop(paste("Request returned error code", g$status_code))}
160+
161+
fn = g$headers$`content-disposition`
162+
fn = strsplit(fn, "=")[[1]][2]
163+
writeBin(g$content, paste0(tmpdir, "/", fn))
164+
165+
#unzip and output .csv
166+
unzip(paste0(tmpdir, "/", fn), exdir = paste0(tmpdir, "/downloads"))
167+
168+
#get and order file list
169+
froot = strsplit(fn, "-")[[1]][1]
170+
df = paste0(tmpdir, "/downloads/", froot, "-data.csv")
171+
pf = paste0(tmpdir, "/downloads/", froot, "-project.csv")
172+
173+
if(file.size(df) == 0){
174+
file.remove(c(paste0(tmpdir, "/", fn), df, pf))
175+
warning("No records returned")
176+
return(NULL)
177+
}
178+
179+
#read in data
180+
d = read.csv(df)
181+
182+
#read in projects
183+
p = read.csv(pf)
184+
185+
file.remove(paste0(tmpdir, "/", fn))
186+
187+
if(clean){
188+
file.remove(c(df, pf))
189+
}
190+
191+
return(list("data" = d, "projects" = p))
192+
}
193+
194+
#####
195+
#Get field values
196+
#####
197+
wiDB_values = function(fields){
198+
199+
if(!is.character(fields)){
200+
stop("fields values must be character strings")
201+
}
202+
for(i in 1:length(fields)){
203+
if(!(fields[i] %in% c("countries", "states", "types", "projects",
204+
"Site_ID", "Sample_ID", "WI_Analysis_ID",
205+
"Climate_ID"))){
206+
stop("One or more fields values not supported")
207+
}
208+
}
209+
210+
baseStr = "https://wateriso.utah.edu/api/v1/values.php?fields="
211+
q = baseStr
212+
for(i in fields){
213+
q = paste0(q, i, ",")
214+
}
215+
q = substr(q, 1, nchar(q) - 1)
216+
d = GET(q)
217+
218+
if(d$status_code != 200){stop(paste("Request returned error code", d$status_code))}
219+
220+
resp = fromJSON(content(d, as = "text", encoding = "UTF-8"))
221+
222+
return(resp)
223+
}

README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
# isoWater
22

3-
An R package for inferring the source of waters based on their isotopic composition and allowing for isotope effects associated with partial evaporation. Install from GitHub using the devtools package:
3+
An R package for obtaining and analyzing water isotope data. Includes interfaces to the Waterisotopes Database and tools for inferring the source of waters based on their isotopic composition accounting for isotope effects associated with partial evaporation. Install the latest release from GitHub using the devtools package:
44

55
```
66
library(devtools)
7-
install_GitHub("SPATIAL-Lab/isoWater")
7+
install_GitHub("SPATIAL-Lab/isoWater@*release")
88
library(isoWater)
99
```
1010

1111
References:
1212

13-
Bowen, G. J., Putman, A., Brooks, J. R., Bowling, D. R., Oerter, E. J., & Good, S. P. (2018). Inferring the source of evaporated waters using stable H and O isotopes. Oecologia, 187(4), 1025-1039.
13+
Bowen, G. J., Putman, A. L., Brooks, J. R., Bowling, D. R., Oerter, E. J., & Good, S. P. (2018) Inferring the source of evaporated waters using stable H and O isotopes. Oecologia, 187(4), 1025-1039.
14+
15+
Putman, A. L., & Bowen, G. J. (2019) A global database of the stable isotopic ratios of meteoric and terrestrial waters. Hydrology and Earth System Sciences 23(10), 4389-4396.

0 commit comments

Comments
 (0)