#' Get SNOTEL data for specified sites.
#'
#' \code{GetSnotel} downloads SNOTEL data tables and creates a dataframe.
#'
#' \code{GetSnotel} downloads SNOTEL for
#' specified sites and outputs a dataframe with consistent date and data columns
#' for use with other rwrfhydro tools.
#'
#' @param siteIDs A single site ID or vector of site IDs to download and process. Site IDs
#' should match the standardized SNOTEL IDs (integers). See snotelMeta for a list of
#' site IDs (as of June 2015).
#' @param report (DEFAULT="STAND") Type of report to generate. Options (from NRCS)
#' are: \itemize{ \item "STAND" (standard snotel) \item "SOIL" (soil temp and moisture)
#' \item "SCAN" (standard scan) \item "ALL" (all) \item "WEATHER" (atmospheric) }
#' @param series (DEFAULT="Daily") Time series to generate. Options (from NRCS)
#' are: \itemize{ \item "Daily" \item "Hourly" \item "Hour:HH" (a single hour specified
#' by HH) }
#' @param intervaltype (DEFAULT="Historic") Options (from NRCS)
#' are: \itemize{ \item "Historic" \item "Current" }
#' @param current (DEFAULT="DAY") Only used if intervaltype="Current". Options (from NRCS)
#' are: \itemize{ \item "DAY" \item "WEEK" \item "YEAR" \item "WATERYEAR" }
#' @param duration (DEFAULT="WY") Only used if intervaltype="Historic". Options
#' are: \itemize{ \item "CY" (calendar year) \item "WY" (water year) }
#' @param startYr (OPTIONAL) The first year to download files for.
#' @param endYr (OPTIONAL) The last year to download files for.
#' @param month (OPTIONAL) The month to download files for.
#' @param day (OPTIONAL) The day of month to download files for.
#' @param quiet (OPTIONAL) Whether to suppress output (TRUE=suppress output;
#' DEFAULT=FALSE).
#' @return dataframe
#' @examples
#' \dontrun{
#' sno.santafe <- GetSnotel(c("921","922"), series="Daily", startYr=2009, endYr=2010)
#' sno.niwot <- GetSnotel(c("663"), series="Hourly", startYr=2009, month=4)
#' sno.santafe <- GetSnotel(c("921","922"), intervaltype="Current", current="WEEK")
#' } #dontrun
#' @keywords IO
#' @concept SNOTEL
#' @family SNOTEL
#' @export
GetSnotel <- function(siteIDs,
report="STAND", series="Daily",
intervaltype="Historic",
current="DAY",
duration="WY",
startYr=NULL, endYr=NULL,
month=NULL, day=NULL,
quiet=FALSE) {
# test: siteIDs="663"; report="STAND"; series="Hourly"; intervaltype="Historic";
# current="DAY"; duration="WY"; startYr=NULL; endYr=NULL; month=NULL; day=NULL
# test: siteIDs=c("663","922"); report="STAND"; series="Hourly"; intervaltype="Historic";
# current="DAY"; duration="WY"; startYr=2005; endYr=2015; month=NULL; day=NULL
#"http://www.wcc.nrcs.usda.gov/nwcc/view?intervalType=$INTERVALTYPE+&report=$REPORT&
#timeseries=$SERIES&format=copy&sitenum=$STATION&year=$YEAR&month=$MONTH&day=$DAY"
# Setup
server="https://wcc.sc.egov.usda.gov/nwcc/"
# initialize dataframe
data <- data.frame()
years <- c()
# All SNOTEL timestamps are PST (UTC-8, no daylight savings)
uo <- -8
# Parse arguments for URL
if (is.null(endYr)) endYr <- startYr
if (!is.null(startYr)) years <- seq(startYr, endYr, 1)
if (!is.null(month)) if (nchar(month)==1) month <- paste0("0",month)
if (!is.null(day)) if (nchar(day)==1) day <- paste0("0",day)
if (is.null(month)) month <- duration
if (intervaltype=="Current") years <- format(Sys.Date(), "%Y")
# Loop through sites and years
for (i in 1:length(siteIDs)) {
siteID <- siteIDs[i]
if (!quiet) print(paste("Site:", siteID))
for (j in 1:length(years)) {
if (intervaltype=="Current") {
if (!quiet) print(paste(" - processing current", current))
# Form URL
baseurl <- paste0(server,
"view?intervalType=", intervaltype,
"+&report=", report,
"×eries=", series,
"&format=copy&sitenum=", siteID,
"&interval=", current)
} else {
if (!quiet) print(paste(" - processing year:", years[j]))
# Form URL
baseurl <- paste0(server,
"view?intervalType=", intervaltype,
"+&report=", report,
"×eries=", series,
"&format=copy&sitenum=", siteID,
"&year=", years[j],
"&month=", month,
"&day=", day)
}
# Download data
tmp <- RCurl::getURL(baseurl)
tmpData <- read.table(textConnection(tmp), sep = ",", header=TRUE, skip=2,
strip.white=T, stringsAsFactors=FALSE,
na.strings=c(-99.9))
tmpData$X <- NULL
tmpHead <- read.table(textConnection(tmp), sep = "\t", nrows=1, strip.white=T,
stringsAsFactors=FALSE)
# Process time. Note that we are using "Date" not "POSIXct" format for daily data
if (length(grep("Hour", series))>0) {
tmpData$POSIXct <- as.POSIXct( paste(as.character(tmpData$Date),
as.character(tmpData$Time), sep=" "),
format="%Y-%m-%d %H:%M", tz="UTC" ) - (uo*3600)
tmpData$wy <- CalcWaterYear(tmpData$POSIXct)
} else {
# Using this timezone because it is UTC-8 with and without daylight savings,
# which matches SNOTEL PST timestamp, although this is just to get the WY correct
# so doesn't actually matter as long as we are consistent...
tmpData$Date <- as.Date(as.character(tmpData$Date), format="%Y-%m-%d")
tmpData$wy <- CalcWaterYear(as.POSIXct(format(tmpData$Date,
tz="America/Metlakatla"),
tz="America/Metlakatla"))
}
if ("Site.Id" %in% names(tmpData)) {
names(tmpData)[which(names(tmpData)=="Site.Id")]<-"site_id"}
# Do unit conversions where necessary
if ("WTEQ.I.1..in." %in% names(tmpData)) {
tmpData$SWE_mm <- sapply(tmpData$WTEQ.I.1..in., FUN=function(x) max(x*25.4, 0.0))
tmpData$SWE_mm <- as.numeric(as.character(tmpData$SWE_mm))
}
if ("PREC.I.1..in." %in% names(tmpData)) {
tmpData$CumPrec_mm <- as.numeric(as.character(tmpData$PREC.I.1..in.)) * 25.4
tmpData$Prec_mm[2:nrow(tmpData)] <- diff(tmpData$CumPrec_mm)
tmpData$Prec_mm[tmpData$Prec_mm<0] <- 0.0
}
if ("SNWD.I.1..in." %in% names(tmpData)) {
tmpData$SNWD_mm <- sapply(tmpData$SNWD.I.1..in., FUN=function(x) max(x*25.4, 0.0))
tmpData$SNWD_mm <- as.numeric(as.character(tmpData$SNWD_mm))
}
# Rename temperature fields (already in ok units)
if ("TOBS.I.1..degC." %in% names(tmpData)) {
names(tmpData)[which(names(tmpData)=="TOBS.I.1..degC.")]<-"Tobs_C"}
if ("TMAX.D.1..degC." %in% names(tmpData)) {
names(tmpData)[which(names(tmpData)=="TMAX.D.1..degC.")]<-"Tmax_C"}
if ("TMIN.D.1..degC." %in% names(tmpData)) {
names(tmpData)[which(names(tmpData)=="TMIN.D.1..degC.")]<-"Tmin_C"}
if ("TAVG.D.1..degC." %in% names(tmpData)) {
names(tmpData)[which(names(tmpData)=="TAVG.D.1..degC.")]<-"Tavg_C"}
# Tack on to end of master dataset
data <- plyr::rbind.fill(data, tmpData)
} # end for years
} # end for sites
return(data)
}
#' SNOTEL site metadata
#'
#' Metadata for the SNOTEL sites (as of June 2015) including lat/lon.
#'
#' @usage
#' snotelMeta
#'
#' @format
#' data.frame: 854 obs. of 11 variables:
#' \describe{
#' \item{ntwk}{Observation network}
#' \item{state}{State where site is located}
#' \item{site_name}{Site name}
#' \item{site_id}{Site integer ID}
#' \item{start}{Start date for the observation record at the site}
#' \item{lat}{Site latitude}
#' \item{lon}{Site longitude}
#' \item{elev}{Site elevation in feet}
#' \item{county}{County where site is located}
#' \item{huc}{HUC name where site is locted}
#' \item{huc_id}{HUC ID where site is located}
#' }
#'
#' @family SNOTEL
#' @concept data
#' @keywords data
"snotelMeta"
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.