├── data └── bdmep_meta.rda ├── tests ├── testthat.R └── testthat │ └── test-bdmep_import.R ├── .travis.yml ├── .gitignore ├── .Rbuildignore ├── NAMESPACE ├── man ├── pipe.Rd ├── nvalid.Rd ├── str_empty.Rd ├── bdmep_coords.Rd ├── set_bdmep_user.Rd ├── bdmep_read.Rd ├── bdmep_description.Rd ├── bdmep_template.Rd ├── inmetr.Rd ├── bdmep_stations.Rd ├── bdmep_data_status.Rd ├── bdmep_meta.Rd ├── bdmep_import_station.Rd └── bdmep_import.Rd ├── inmetr.Rproj ├── R ├── inmetr.R ├── utils.R ├── metadata.R └── bdmep.R ├── inst └── CITATION ├── DESCRIPTION ├── LICENSE ├── NEWS.md ├── issue8-inmetr.R └── README.md /data/bdmep_meta.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lhmet/inmetr/HEAD/data/bdmep_meta.rda -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(inmetr) 3 | 4 | test_check("inmetr") 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # R for travis: see documentation at https://docs.travis-ci.com/user/languages/r 2 | 3 | language: R 4 | sudo: false 5 | cache: packages 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .Ruserdata 5 | inst/doc 6 | README.Rmd 7 | NEWS.Rmd 8 | .csv 9 | release 10 | data-raw 11 | .R 12 | -------------------------------------------------------------------------------- /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^.*\.Rproj$ 2 | ^\.Rproj\.user$ 3 | ^README\.Rmd$ 4 | ^NEWS\.Rmd$ 5 | ^inmetr\.Rproj$ 6 | ^.*\.csv$ 7 | ^\.travis\.yml$ 8 | ^data-raw$ 9 | ^release$ 10 | ^issue8-inmetr\.R$ 11 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export("%>%") 4 | export(bdmep_description) 5 | export(bdmep_import) 6 | importFrom(dplyr,"%>%") 7 | importFrom(stats,setNames) 8 | importFrom(utils,head) 9 | importFrom(utils,read.csv2) 10 | -------------------------------------------------------------------------------- /man/pipe.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils.R 3 | \name{\%>\%} 4 | \alias{\%>\%} 5 | \title{Pipe operator} 6 | \usage{ 7 | lhs \%>\% rhs 8 | } 9 | \description{ 10 | See \code{\link[dplyr]{\%>\%}} for more details. 11 | } 12 | \keyword{internal} 13 | -------------------------------------------------------------------------------- /man/nvalid.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils.R 3 | \name{nvalid} 4 | \alias{nvalid} 5 | \title{Count valid data} 6 | \usage{ 7 | nvalid(x) 8 | } 9 | \arguments{ 10 | \item{x}{a numeric vector} 11 | } 12 | \value{ 13 | total non-missing values of x. 14 | } 15 | \description{ 16 | Count valid data 17 | } 18 | -------------------------------------------------------------------------------- /inmetr.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | 15 | BuildType: Package 16 | PackageUseDevtools: Yes 17 | PackageInstallArgs: --no-multiarch --with-keep.source 18 | PackageRoxygenize: rd,collate,namespace 19 | -------------------------------------------------------------------------------- /man/str_empty.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils.R 3 | \name{str_empty} 4 | \alias{str_empty} 5 | \title{Detect if a string is empty} 6 | \usage{ 7 | str_empty(string) 8 | } 9 | \arguments{ 10 | \item{string}{Input vector. Either a character vector, or something coercible to one.} 11 | } 12 | \value{ 13 | logical, TRUE in the absence of a string (""), otherwise FALSE. 14 | } 15 | \description{ 16 | Detect if a string is empty 17 | } 18 | -------------------------------------------------------------------------------- /man/bdmep_coords.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/metadata.R 3 | \name{bdmep_coords} 4 | \alias{bdmep_coords} 5 | \title{Get coordinates on meteorological stations} 6 | \usage{ 7 | bdmep_coords() 8 | } 9 | \value{ 10 | A data frame is returned with metadata, including the stations 11 | \code{id}, and coordinates (\code{lon}, \code{lat}, \code{alt}) 12 | } 13 | \description{ 14 | Fetch the coordinates on meteorological stations from INMET 15 | \url{http://www.inmet.gov.br/projetos/rede/pesquisa/lista_estacao.php} 16 | } 17 | \author{ 18 | Jonatan Tatsch 19 | } 20 | -------------------------------------------------------------------------------- /man/set_bdmep_user.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/bdmep.R 3 | \name{set_bdmep_user} 4 | \alias{set_bdmep_user} 5 | \title{Set username and password to login BDMEP} 6 | \usage{ 7 | set_bdmep_user(lnk, email, passwd) 8 | } 9 | \arguments{ 10 | \item{lnk}{url to BDMEP access} 11 | 12 | \item{email}{your BDMEP username} 13 | 14 | \item{passwd}{your BDMEP password} 15 | } 16 | \value{ 17 | a named list with user name, password and text of button access 18 | } 19 | \description{ 20 | Set username and password to login BDMEP 21 | } 22 | \author{ 23 | Jonatan Tatsch 24 | } 25 | -------------------------------------------------------------------------------- /R/inmetr.R: -------------------------------------------------------------------------------- 1 | #'inmetr:A package for import data from Brazilian meteorological stations 2 | #' 3 | #' The inmetr package offers a set of functions to import historical data from Brazilian meteorological stations available in the Meteorological Database for Education and Research \href{http://www.inmet.gov.br/projetos/rede/pesquisa}{BDMEP} of National Institute of Meteorology \href{http://www.inmet.gov.br}{INMET} 4 | #' 5 | #'@section inmetr functions: 6 | #'The main functions are: 7 | #' \itemize{ 8 | #' \item \code{\link{bdmep_import}} 9 | #' \item \code{\link{bdmep_description}} 10 | #' } 11 | #' The data included in \code{inmetr} is: 12 | #' \itemize{ 13 | #' \item \code{\link{bdmep_meta}} 14 | #' } 15 | #'@docType package 16 | #'@name inmetr 17 | NULL 18 | -------------------------------------------------------------------------------- /man/bdmep_read.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/bdmep.R 3 | \name{bdmep_read} 4 | \alias{bdmep_read} 5 | \title{Read data downaloaded from BDMEP} 6 | \usage{ 7 | bdmep_read(x) 8 | } 9 | \arguments{ 10 | \item{x}{a numeric vector with the meteorological station code} 11 | } 12 | \value{ 13 | a data frame with variables in columns and observations along rows 14 | } 15 | \description{ 16 | Read and tidy data downloaded with \code{\link{bdmep_import}} 17 | } 18 | \details{ 19 | A minimum quality control check is applied to the data 20 | This include: a chronological sequence check; filling missing dates with NA; 21 | remove duplicated data; aggregate time and date information into a POSIX object 22 | } 23 | \author{ 24 | Jonatan Tatsch 25 | } 26 | -------------------------------------------------------------------------------- /man/bdmep_description.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/metadata.R 3 | \name{bdmep_description} 4 | \alias{bdmep_description} 5 | \title{Description of meteorological variables} 6 | \usage{ 7 | bdmep_description() 8 | } 9 | \value{ 10 | a data frame is returned with 11 | \code{varname}, \code{description}, \code{unit} 12 | } 13 | \description{ 14 | Get variable names, description and units 15 | } 16 | \details{ 17 | This function describe the Meteorological variables imported by \code{\link{bdmep_import}} 18 | 19 | to information about instruments see \url{http://www.inmet.gov.br/portal/index.php?r=home/page&page=instrumentos} 20 | } 21 | \examples{ 22 | met_vars <- bdmep_description() 23 | met_vars 24 | 25 | } 26 | \author{ 27 | Jonatan Tatsch 28 | } 29 | -------------------------------------------------------------------------------- /man/bdmep_template.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/bdmep.R 3 | \name{bdmep_template} 4 | \alias{bdmep_template} 5 | \title{Template bdmep dataframe to be used when the status of a request was not successfully executed.} 6 | \usage{ 7 | bdmep_template(.id, .req_status) 8 | } 9 | \arguments{ 10 | \item{.id}{a character scalar with the meteorological station code} 11 | 12 | \item{.req_status}{character scalar with information on the status of a request} 13 | } 14 | \value{ 15 | a dataframe with variables filled with NA, except for id and request_status 16 | } 17 | \description{ 18 | Template bdmep dataframe to be used when the status of a request was not successfully executed. 19 | } 20 | \details{ 21 | This is used when the status of a request code is not 200. 22 | } 23 | -------------------------------------------------------------------------------- /man/inmetr.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/inmetr.R 3 | \docType{package} 4 | \name{inmetr} 5 | \alias{inmetr} 6 | \title{inmetr:A package for import data from Brazilian meteorological stations} 7 | \description{ 8 | The inmetr package offers a set of functions to import historical data from Brazilian meteorological stations available in the Meteorological Database for Education and Research \href{http://www.inmet.gov.br/projetos/rede/pesquisa}{BDMEP} of National Institute of Meteorology \href{http://www.inmet.gov.br}{INMET} 9 | } 10 | \section{inmetr functions}{ 11 | 12 | The main functions are: 13 | \itemize{ 14 | \item \code{\link{bdmep_import}} 15 | \item \code{\link{bdmep_description}} 16 | } 17 | The data included in \code{inmetr} is: 18 | \itemize{ 19 | \item \code{\link{bdmep_meta}} 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /inst/CITATION: -------------------------------------------------------------------------------- 1 | citHeader("To cite package 'inmetr' in publications use:") 2 | 3 | year <- as.integer(format(Sys.Date(), "%Y")) 4 | vers <- paste("R package version", "0.2.5") 5 | 6 | citEntry(entry = "Manual", 7 | title = "inmetr: Historical Data from Brazilian Meteorological Stations in R", 8 | author = personList(as.person("Jonatan Tatsch")), 9 | year = year, 10 | note = vers, 11 | doi = "https://doi.org/10.5281/zenodo.580813", 12 | 13 | textVersion = paste0("Tatsch, J.D. ", 14 | year, 15 | ". inmetr R package (v 0.2.5): Historical Data from Brazilian Meteorological Stations in R. ", 16 | "Zenodo. https://doi.org/10.5281/zenodo.580813." 17 | 18 | ), 19 | institution = "Universidade Federal de Santa Maria-UFSM", 20 | url = "https://github.com/lhmet/inmetr") 21 | -------------------------------------------------------------------------------- /man/bdmep_stations.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/metadata.R 3 | \name{bdmep_stations} 4 | \alias{bdmep_stations} 5 | \title{Get basic information on meteorological station from INMET} 6 | \usage{ 7 | bdmep_stations() 8 | } 9 | \value{ 10 | a data frame is returned with 11 | \code{name}, \code{state}, \code{id} 12 | } 13 | \description{ 14 | Get OMM code, state and station name on meteorological stations from INMET 15 | \url{http://www.inmet.gov.br/projetos/rede/pesquisa/lista_estacao.php} 16 | } 17 | \details{ 18 | This function is used to find the OMM station ID that can be 19 | used to import BDMEP data using \code{\link{bdmep_import}} 20 | } 21 | \examples{ 22 | 23 | \dontrun{ 24 | # tyr get information from inmet web site 25 | stns <- bdmep_stations() 26 | head(stns, 15) 27 | #save(stns, file = "data/stns.rda") 28 | } 29 | } 30 | \author{ 31 | Jonatan Tatsch 32 | } 33 | -------------------------------------------------------------------------------- /man/bdmep_data_status.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils.R 3 | \name{bdmep_data_status} 4 | \alias{bdmep_data_status} 5 | \title{Report status of each variable} 6 | \usage{ 7 | bdmep_data_status(data_bdmep = xtidy) 8 | } 9 | \arguments{ 10 | \item{data_bdmep}{data processed by \code{\link{bdmep_read}} in 11 | \code{\link{bdmep_import_station}}.} 12 | } 13 | \value{ 14 | data frame with the percentage of valid observations for each variable 15 | \describe{ 16 | \item{id}{station id} 17 | \item{sdate}{start date of observations} 18 | \item{edate}{end date of observations} 19 | \item{rows}{number of rows in data file} 20 | \item{request_status}{character scalar with information on the status of a request} 21 | \item{prec}{valid observations of prec in percentage} 22 | \item{...}{valid observations of ith variable in percentage} 23 | \item{ws}{valid observations of ws in percentage} 24 | } 25 | } 26 | \description{ 27 | Report status of each variable 28 | } 29 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: inmetr 2 | Title: Import Historical Data from Brazilian Meteorological 3 | Stations 4 | Version: 0.3.0.9000 5 | Authors@R: 6 | person(given = "Jonatan", 7 | family = "Tatsch", 8 | role = c("aut", "cre"), 9 | email = "jdtatsch@gmail.com") 10 | Description: Import historical data measured by meteorological 11 | stations from Instituto Nacional de Meteorologia (INMET), Brazil. 12 | License: BSD_3_clause + file LICENSE 13 | URL: http://github.com/lhmet/inmetr 14 | BugReports: http://github.com/lhmet/inmetr/issues 15 | Depends: 16 | R (>= 3.2.4) 17 | Imports: 18 | dplyr (>= 0.8.5), 19 | httr (>= 1.4.1), 20 | lubridate (>= 1.7.8), 21 | magrittr (>= 1.5), 22 | purrr (>= 0.3.3), 23 | readr (>= 1.3.1), 24 | rvest (>= 0.3.5), 25 | selectr (>= 0.4.2), 26 | stringi (>= 1.4.6), 27 | stringr (>= 1.4.0), 28 | tibble (>= 3.0.0), 29 | tidyr (>= 1.0.2), 30 | xml2 (>= 1.3.1) 31 | Suggests: 32 | knitr (>= 1.27), 33 | rmarkdown (>= 2.0), 34 | testthat (>= 2.3.1) 35 | LazyData: true 36 | RoxygenNote: 7.0.2 37 | -------------------------------------------------------------------------------- /man/bdmep_meta.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/metadata.R 3 | \docType{data} 4 | \name{bdmep_meta} 5 | \alias{bdmep_meta} 6 | \title{Metadata on 394 meteorological stations of INMET} 7 | \format{\code{bdmep_meta} is supplied with the \code{inmetr} package and 8 | consists of the following information in a data frame with 394 rows and 9 columns. 9 | \describe{ 10 | \item{id}{station id, character with 5 digits corresponding to OMM code} 11 | \item{lon}{longitude in decimal degrees} 12 | \item{lat}{latitude in decimal degrees} 13 | \item{alt}{altitude in metres} 14 | \item{name}{station name} 15 | \item{state}{Full name of state} 16 | \item{uf}{Federative Unit} 17 | \item{time_zone}{time zone} 18 | \item{offset_utc}{UTC offset} 19 | }} 20 | \source{ 21 | \code{bdmep_meta} was compiled from 22 | \url{http://www.inmet.gov.br/webcdp/climatologia/normais/imagens/normais/planilhas/Relac_Est_Meteo_NC.xls} 23 | } 24 | \usage{ 25 | bdmep_meta 26 | } 27 | \description{ 28 | Spatial coordinates, altitude and others informations of INMET's 29 | meteorological stations. 30 | } 31 | \examples{ 32 | head(bdmep_meta) 33 | with(bdmep_meta, 34 | plot(lon, lat, 35 | pch = 20, 36 | col = abs(offset_utc), 37 | main = "Met. stations of INMET") 38 | ) 39 | legend("bottomleft", 40 | c("UTC-5", "UTC-4", "UTC-3"), 41 | col = c(5:3), 42 | pch = 20, 43 | title = "time zone") 44 | } 45 | \keyword{datasets} 46 | -------------------------------------------------------------------------------- /man/bdmep_import_station.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/bdmep.R 3 | \name{bdmep_import_station} 4 | \alias{bdmep_import_station} 5 | \title{Import data of a meteorological station} 6 | \usage{ 7 | bdmep_import_station( 8 | .id = "83844", 9 | .sdate, 10 | .edate, 11 | .email, 12 | .passwd, 13 | .verbose = TRUE, 14 | .destdir = NULL, 15 | .na.strings = "-9999" 16 | ) 17 | } 18 | \arguments{ 19 | \item{.id}{a character vector with the meteorological station code} 20 | 21 | \item{.sdate}{start date in "d/m/Y" format} 22 | 23 | \item{.edate}{end date in "d/m/Y" format, default values \code{format(Sys.Date(), "\%d/\%m/\%Y")}} 24 | 25 | \item{.email}{e-mail to access BDMEP} 26 | 27 | \item{.passwd}{password to access BDMEP} 28 | 29 | \item{.verbose}{Optional. Logical. If set to TRUE (default), print messages.} 30 | 31 | \item{.destdir}{Optional. Character Local file path to write file out to.If NULL (default) files are not written to disk.} 32 | 33 | \item{.na.strings}{a character string which is to be interpreted as NA values.} 34 | } 35 | \value{ 36 | a data frame with variables in columns (see \code{\link{bdmep_description}}) and observations (date and time) along rows. 37 | } 38 | \description{ 39 | Import data of a meteorological station 40 | } 41 | \details{ 42 | The data are in sub-daily time scale. A minimum data quality control is applied to the data. 43 | This include: a chronological sequence check; filling data from missing dates with NA; 44 | remove duplicated data. Time variables (year, month, day, hour) are aggregated into a POSIX object in UTC 45 | } 46 | \author{ 47 | Jonatan Tatsch 48 | } 49 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) "2020, by Laboratório de Hidrometeorologia 4 | Contributors: Jônatan Dupont Tatsch 5 | Afiliation: Universidade Federal de Santa Maria 6 | URL: https://github.com/lhmet 7 | Citation: Tatsch, J.D. 2017. inmetr: Historical Data from Brazilian Meteorological Stations in R. Zenodo, doi:10.5281/zenodo.59652." 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without 11 | modification, are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, this 14 | list of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, 17 | this list of conditions and the following disclaimer in the documentation 18 | and/or other materials provided with the distribution. 19 | 20 | * Neither the name of the copyright holder nor the names of its 21 | contributors may be used to endorse or promote products derived from 22 | this software without specific prior written permission. 23 | 24 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 25 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 27 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 28 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 30 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 31 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 32 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 33 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /man/bdmep_import.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/bdmep.R 3 | \name{bdmep_import} 4 | \alias{bdmep_import} 5 | \title{Import data from Brazilian meteorological stations} 6 | \usage{ 7 | bdmep_import( 8 | id = c("83844", "83967"), 9 | sdate = "01/01/1961", 10 | edate = format(Sys.Date(), "\%d/\%m/\%Y"), 11 | email = "your@email.com", 12 | passwd = "your-password", 13 | verbose = TRUE, 14 | destdir = NULL, 15 | na.strings = "-9999" 16 | ) 17 | } 18 | \arguments{ 19 | \item{id}{A character vector with codes of meteorological stations} 20 | 21 | \item{sdate}{Start date in "d/m/Y" format} 22 | 23 | \item{edate}{End date in "d/m/Y" format, default values \code{format(Sys.Date(), "\%d/\%m/\%Y")}} 24 | 25 | \item{email}{E-mail to access BDMEP} 26 | 27 | \item{passwd}{Password to access BDMEP} 28 | 29 | \item{verbose}{If TRUE, prints login sucessfull.} 30 | 31 | \item{destdir}{A character string with the path where the downloaded data is saved. If it is NULL, data will not be saved in disk.} 32 | 33 | \item{na.strings}{a character string which is to be interpreted as NA values. \code{na.strings} is only used when destdir is not NULL.} 34 | } 35 | \value{ 36 | A data frame with variables in columns (see \code{\link{bdmep_description}}) and observations (date and time) along rows. 37 | } 38 | \description{ 39 | Import data from Brazilian meteorological stations 40 | } 41 | \details{ 42 | The data are in sub-daily time scale. A minimum data quality control is applied to the data. 43 | This include: a chronological sequence check; filling data from missing dates with NA; 44 | remove duplicated data. Time variables (year, month, day, hour) are aggregated into a POSIX object in UTC 45 | } 46 | \examples{ 47 | \dontrun{ 48 | # download data for Santa Maria and Porto Alegre 49 | metdata <- bdmep_import(id = c("83936", "83967"), 50 | sdate = "01/01/2015", # could be "01/01/1961" 51 | edate = format(Sys.Date(), '\%d/\%m/\%Y'), 52 | email = "your@email.com", 53 | passwd = "your-password", 54 | verbose = TRUE) 55 | head(metdata) 56 | tail(metdata) 57 | summary(metdata) 58 | } 59 | 60 | } 61 | \author{ 62 | Jonatan Tatsch 63 | } 64 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | News 2 | ================ 3 | 4 | 5 | 6 | # inmetr 0.3.0.9999 7 | 8 | - \[ \] add function to compute mean daily data. 9 | - \[ \] remove stations not available in BDMEP\[\] (although they 10 | still are in `bdmep_meta()`). 11 | - \[ \] check if stations in 12 | [climatology 1981-2010](http://www.inmet.gov.br/portal/index.php?r=clima/normaisClimatologicas) 13 | are available in BDMEP. 14 | 15 | # inmetr 0.3.0 16 | 17 | - \[x\] fix issue \#8, thanks to @patrickgoulart12 18 | - \[x\] add testing for bdmep\_import() 19 | 20 | # inmetr 0.2.8 21 | 22 | - \[x\] improve arguments check for `sdate` and `edate` arguments in 23 | `bdmep_import()`. Now, whitespace are removed from start and end of 24 | those arguments before building the url string to BDMEP. Thanks to 25 | @danielalthoff for reporting your case. 26 | 27 | # inmetr 0.2.7 28 | 29 | - \[x\] fix issue related to station MACAPA - AP (OMM: 82098), thanks 30 | to William Barbosa (ESALQ/USP). 31 | - \[x\] split up bdmep\_import in `bdmep_write_csv()` and 32 | `bdmep_data_status()` 33 | 34 | # inmetr 0.2.6.9999 35 | 36 | - \[x\] fix issue \#3, thanks to @DominickAugustine 37 | - \[x\] add function to write csv files of station data. 38 | - \[x\] include `bdmep_meta()`. 39 | 40 | # inmetr 0.2.5 41 | 42 | - \[x\] include metadata of 394 meteorological stations as a dataset 43 | named `bdmep_meta`. 44 | - \[x\] Functions (see below) were renamed to have consistent names. 45 | Now all functions have a ‘bdmep’ prefix. This allows you to type the 46 | prefix and see all the members of bdmep’s family functions. 47 | - `import_bdmep` changes to `bdmep_import` 48 | - `data_description` changes to `bdmep_description` 49 | - \[x\] `bdmep_import()` changes: 50 | - supports a vector of stations IDs allowing to data import from 51 | multiple meteorological stations. 52 | - returned data frame include a new column `request status` 53 | (character) to inform on the outcome of the execution of the 54 | request on the server. 55 | 56 | # inmetr 0.0.3 57 | 58 | - \[x\] fixed issue (\#1, @sillasgonzaga). 59 | 60 | - \[x\] `import_bmep()` has a new argument `verbose` to print if the 61 | status of connection is ok. 62 | -------------------------------------------------------------------------------- /tests/testthat/test-bdmep_import.R: -------------------------------------------------------------------------------- 1 | context("Time span") 2 | 3 | test_that("Time span not available in database", { 4 | 5 | # template data ------------------------------------------------------------- 6 | id <- "83743" 7 | # for a span not available in bdmep 8 | sdate <- format(Sys.Date() - 90, "%d/%m/%Y") 9 | edate <- format(Sys.Date(), "%d/%m/%Y") 10 | msg_nodata_req <- .build_msg_nodata(.id = id, .sdate = sdate, .edate = edate) 11 | data_ref <- bdmep_template(.id = id, .req_status = msg_nodata_req) 12 | 13 | # request data 14 | expect_message((data_req <- bdmep_import(id, 15 | sdate, 16 | edate, 17 | email = "jdtatsch@gmail.com", 18 | passwd = "d17ulev5", 19 | verbose = TRUE 20 | )), paste0("Nao existem dados disponiveis da estacao: Rio de Janeiro-RJ para o periodo de ", sdate, " a ", edate)) 21 | 22 | expect_identical(data_req, data_ref) 23 | }) 24 | 25 | 26 | test_that("Time span partially available in database", { 27 | 28 | # template data ------------------------------------------------------------- 29 | id <- "83743" 30 | # for a span not avaialable in bdmep 31 | sdate <- "31/03/2002" 32 | edate <- format(Sys.Date(), "%d/%m/%Y") 33 | # msg_nodata_req <- .build_msg_nodata(.id = id, .sdate = sdate, .edate = edate) 34 | # data_ref <- bdmep_template(.id = id, .req_status = msg_nodata_req) 35 | 36 | # request data 37 | expect_message( 38 | (data_req <- bdmep_import(id, 39 | sdate, 40 | edate, 41 | email = "jdtatsch@gmail.com", 42 | passwd = "d17ulev5", 43 | verbose = TRUE 44 | )), 45 | message( 46 | "\n", "------------------------------", "\n", 47 | "station: ", id, "\n", 48 | "\n", 49 | "OK (HTTP 200).", 50 | paste0( 51 | "Returning data available span: ", 52 | paste(as.Date((lubridate::dmy(sdate)))), 53 | "--", 54 | paste(as.Date(dplyr::last(data_req$date))) 55 | ) 56 | ) 57 | ) 58 | }) 59 | 60 | 61 | 62 | test_that("Time span not available in database 2", { 63 | 64 | # template data ------------------------------------------------------------- 65 | id <- "83743" 66 | # for a span not available in bdmep 67 | sdate <- "01/01/1931" 68 | edate <- "31/12/1959" 69 | #msg_nodata_req <- .build_msg_nodata(.id = id, .sdate = sdate, .edate = edate) 70 | #data_ref <- bdmep_template(.id = id, .req_status = msg_nodata_req) 71 | 72 | # request data 73 | expect_message((data_req <- bdmep_import(id, 74 | sdate, 75 | edate, 76 | email = "jdtatsch@gmail.com", 77 | passwd = "d17ulev5", 78 | verbose = TRUE 79 | )), paste0("Nao existem dados disponiveis da estacao: Rio de Janeiro-RJ para o periodo de ", sdate, " a ", edate)) 80 | 81 | #expect_identical(data_req, data_ref) 82 | }) 83 | -------------------------------------------------------------------------------- /issue8-inmetr.R: -------------------------------------------------------------------------------- 1 | # https://github.com/lhmet/inmetr/issues/8 2 | 3 | usethis::use_build_ignore("issue8-inmetr.R") 4 | usethis::use_git_ignore("issue8") 5 | 6 | # ctrl + s, to save this file 7 | # maybe in the future put this test in /test with testthat 8 | 9 | # devtools::install_github("lhmet/inmetr", force = TRUE) 10 | 11 | # Installing package into ‘/home/hidrometeorologista/.R/libs’ 12 | # (as ‘lib’ is unspecified) 13 | # * installing *source* package ‘inmetr’ ... 14 | # ** using staged installation 15 | # ** R 16 | # ** data 17 | # *** moving datasets to lazyload DB 18 | # ** inst 19 | # ** byte-compile and prepare package for lazy loading 20 | # Note: wrong number of arguments to 'seq_along' <---------------??? 21 | # ** help 22 | # *** installing help indices 23 | # ** building package indices 24 | # ** testing if installed package can be loaded from temporary location 25 | # ** testing if installed package can be loaded from final location 26 | # ** testing if installed package keeps a record of temporary installation path 27 | # * DONE (inmetr) 28 | 29 | pcks <- c("devtools", "inmetr") 30 | easypackages::libraries(pcks) 31 | 32 | # ------------------------------------------------------------------------------ 33 | # Normal test 34 | stations <- c("Santa Maria", "Macapá") 35 | # random sample of two stations names 36 | #stations <- sample(bdmep_meta$name, 2) 37 | stations_rows <- pmatch(stations, bdmep_meta$name) 38 | bdmep_meta[stations_rows, ] 39 | #> id lon lat alt name state uf 40 | #> 320 83936 -53.70000 -29.70 95.00 Santa Maria Rio Grande do Sul RS 41 | #> 31 82098 -51.11667 -0.05 14.46 Macapá Amapá AP 42 | #> time_zone offset_utc time_zone.1 offset_utc.1 43 | #> 320 America/Sao_Paulo -3 America/Sao_Paulo -3 44 | #> 31 America/Belem -3 America/Belem -3 45 | stns_codes <- bdmep_meta[stations_rows, "id"] 46 | stns_codes 47 | 48 | start_date <- "01/01/1961" 49 | end_date <- format(Sys.Date(), "%d/%m/%Y") 50 | met_data <- bdmep_import(id = stns_codes, 51 | sdate = start_date, 52 | edate = end_date, 53 | email = "jdtatsch@gmail.com", 54 | passwd = "d17ulev5", 55 | verbose = TRUE) 56 | 57 | # that's fine 58 | 59 | # ------------------------------------------------------------------------------ 60 | 61 | stations <- c("Rio de Janeiro", "São Paulo (Mir. de Santana)", "Belo Horizonte", 62 | "Porto Alegre", "Florianópolis", "Vitória", "Curitiba", 63 | "Goiás", "Rio Branco", "Manaus", "Brasília", "Campo Grande", 64 | "Recife (Curado)", "Natal", "Aracaju", "Salvador (Ondina)", 65 | "Palmas", "Fortaleza", "São Luis", "Cuiabá", 66 | "João Pessoa", "Teresina", "Porto Velho", "Boa Vista", 67 | "Belém", "Macapá") 68 | 69 | stations_rows <- pmatch(stations, bdmep_meta$name) 70 | bdmep_meta[stations_rows, ] 71 | 72 | stns_codes <- bdmep_meta[stations_rows, "id"] 73 | 74 | stns_codes 75 | 76 | (start_date <- "01/01/2018") 77 | (end_date <- format(Sys.Date(), "%d/%m/%Y")) 78 | 79 | met_data <- bdmep_import(id = stns_codes[c(1, 8, 12, 17)], 80 | sdate = start_date, 81 | edate = end_date, 82 | email = "jdtatsch@gmail.com", 83 | passwd = "d17ulev5", 84 | verbose = TRUE) 85 | 86 | 87 | stns_codes[c(1, 8, 12, 17)] 88 | 89 | # stations with the same error 90 | #station: 83860 91 | #OK (HTTP 200). 92 | #Error in (rowheader + 1):(length(x) - 1) : argument of length 0 93 | 94 | 95 | -------------------------------------------------------------------------------- /R/utils.R: -------------------------------------------------------------------------------- 1 | utils::globalVariables(c( 2 | ".", "data", "hora", "codigo", 3 | "prec", "site", 4 | "ws", "tcomp", "id", "request_status", 5 | "wd", "day", "ws", "xtidy", ".verbose", 6 | ".na.strings", ".destdir", "rows", 7 | "nome_estacao", "data_span", "bdmep_meta", 8 | ".id" 9 | )) 10 | 11 | #' Pipe operator 12 | #' 13 | #' See \code{\link[dplyr]{\%>\%}} for more details. 14 | #' 15 | #' @name %>% 16 | #' @rdname pipe 17 | #' @keywords internal 18 | #' @export 19 | #' @importFrom dplyr %>% 20 | #' @usage lhs \%>\% rhs 21 | NULL 22 | 23 | 24 | #' Detect if a string is empty 25 | #' 26 | #' @param string Input vector. Either a character vector, or something coercible to one. 27 | #' 28 | #' @return logical, TRUE in the absence of a string (""), otherwise FALSE. 29 | str_empty <- function(string) { 30 | string <- as.character(string) 31 | string == "" 32 | } 33 | 34 | 35 | #' Count valid data 36 | #' 37 | #' @param x a numeric vector 38 | #' 39 | #' @return total non-missing values of x. 40 | #' 41 | nvalid <- function(x) { 42 | # if(all(is.na(x))) return(0) 43 | sum(!is.na(x)) 44 | } 45 | 46 | 47 | 48 | bdmep_write_csv <- function(data_bdmep = xtidy, 49 | folder = .destdir, 50 | na.strings = .na.strings, 51 | verbose = .verbose) { 52 | # if(!stringr::str_detect(.destfile, "\\.[a-z]{3,}")){ 53 | stopifnot( 54 | dir.exists(folder), 55 | all(c( 56 | "date", "id", "request_status", 57 | "prec", "ws" 58 | ) %in% names(data_bdmep)) 59 | ) 60 | .id <- data_bdmep[1, "id"] 61 | .file <- file.path(folder, paste0(.id, ".csv")) 62 | 63 | # readr::write_csv(x = dplyr::mutate(xtidy, date = as.character(date)), 64 | readr::write_csv( 65 | x = data_bdmep, 66 | path = .file, 67 | na = na.strings, 68 | append = FALSE 69 | ) 70 | 71 | if (file.exists(.file)) { 72 | if (verbose) message("Data saved in ", .file) 73 | res <- .file 74 | } else { 75 | message("Cannot save data file ", .file) 76 | res <- NA_character_ 77 | } 78 | return(invisible(res)) 79 | } 80 | 81 | 82 | 83 | #' Report status of each variable 84 | #' 85 | #' @param data_bdmep data processed by \code{\link{bdmep_read}} in 86 | #' \code{\link{bdmep_import_station}}. 87 | #' 88 | #' @return data frame with the percentage of valid observations for each variable 89 | ##' \describe{ 90 | ##' \item{id}{station id} 91 | ##' \item{sdate}{start date of observations} 92 | ##' \item{edate}{end date of observations} 93 | ##' \item{rows}{number of rows in data file} 94 | ##' \item{request_status}{character scalar with information on the status of a request} 95 | ##' \item{prec}{valid observations of prec in percentage} 96 | ##' \item{...}{valid observations of ith variable in percentage} 97 | ##' \item{ws}{valid observations of ws in percentage} 98 | ##' } 99 | #' 100 | bdmep_data_status <- function(data_bdmep = xtidy) { 101 | 102 | stopifnot( 103 | all( 104 | c( 105 | "date", "id", "request_status", 106 | "prec", "ws" 107 | ) %in% names(data_bdmep) 108 | ) 109 | ) 110 | 111 | data_avail <- dplyr::select( 112 | data_bdmep, date, id, request_status 113 | ) 114 | data_avail <- dplyr::group_by(data_avail, id) 115 | data_avail <- dplyr::summarise( 116 | data_avail, 117 | sdate = min(date, na.rm = TRUE), 118 | edate = max(date, na.rm = TRUE), 119 | rows = length(date), 120 | request_status = unique(request_status) 121 | ) 122 | 123 | data_status <- dplyr::select(data_bdmep, -date) 124 | data_status <- dplyr::group_by(data_bdmep, id) 125 | data_status <- dplyr::summarise_at( 126 | data_status, 127 | .vars = dplyr::vars(prec:ws), 128 | .funs = dplyr::funs(nvalid) 129 | ) 130 | data_status <- dplyr::full_join( 131 | data_avail, 132 | data_status, 133 | by = "id" 134 | ) 135 | data_status <- dplyr::mutate_at( 136 | data_status, 137 | dplyr::vars(prec:ws), 138 | .funs = dplyr::funs(. / rows * 100) 139 | ) 140 | 141 | return(data_status) 142 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | DEPRECATED - no longer actively maintained 2 | ================ 3 | 4 | > Due to changes in access to the BDMEP-INMET data acquisition system, 5 | > {inmetr} is no longer supported. See 6 | > 7 | > and consider using instead. 8 | 9 | ## inmetr: Historical Data from Brazilian Meteorological Stations in R 10 | 11 | 12 | 13 | [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.580813.svg)](https://doi.org/10.5281/zenodo.580813) 14 | [![Build 15 | Status](https://travis-ci.org/lhmet/inmetr.svg?branch=master)](https://travis-ci.org/lhmet/inmetr) 16 | 17 | ### Overview 18 | 19 | `inmetr` provide access to historical data measured by meteorological 20 | stations available in the Meteorological Database for Education and 21 | Research ([BDMEP](http://www.inmet.gov.br/projetos/rede/pesquisa/)) from 22 | National Institute of Meteorology (Instituto Nacional de Meteorologia - 23 | [INMET](http://www.inmet.gov.br)), Brazil. 24 | 25 | ### Installation 26 | 27 | `inmetr` is easy to install from Git Hub using the `devtools` package. 28 | 29 | ``` r 30 | library(devtools) 31 | ``` 32 | 33 | ``` r 34 | install_github('lhmet/inmetr') 35 | ``` 36 | 37 | Load package 38 | 39 | ``` r 40 | library(inmetr) 41 | ``` 42 | 43 | ### Stations ID 44 | 45 | To search a meteorological station from INMET we can use metadata of 46 | INMET stations included in `inmetr` package as `bdmep_meta`. 47 | 48 | ``` r 49 | head(bdmep_meta) 50 | tail(bdmep_meta) 51 | ``` 52 | 53 | `bdmep_meta` is a data frame providing the `id` of stations, a numeric 54 | code defined by 55 | [OMM](http://www.wmo.int/pages/prog/www/ois/volume-a/StationIDs_Global_1509.pdf). 56 | This `id` is a necessary argument to `bdmep_import()` function which 57 | allows to download data from meteorological stations into R. 58 | 59 | Here, we show how to find the [OMM 60 | code](http://www.wmo.int/pages/prog/www/ois/volume-a/StationIDs_Global_1509.pdf) 61 | for meteorological stations at two cities (randomly sampled). 62 | 63 | ``` r 64 | #stations <- c("Santa Maria", "Macapá") 65 | stations <- c("Rio de Janeiro", "Goiás") 66 | # random sample of two stations names 67 | #stations <- sample(bdmep_meta$name, 2) 68 | stations_rows <- pmatch(stations, bdmep_meta$name) 69 | bdmep_meta[stations_rows, ] 70 | stns_codes <- bdmep_meta[stations_rows, "id"] 71 | stns_codes 72 | ``` 73 | 74 | ### Import data 75 | 76 | Now we can import data for the two cities from 1961 to the current date. 77 | 78 | ``` r 79 | start_date <- "01/01/1961" 80 | end_date <- format(Sys.Date(), "%d/%m/%Y") 81 | met_data <- bdmep_import(id = stns_codes, 82 | sdate = start_date, 83 | edate = end_date, 84 | email = "your-email", 85 | passwd = "your-password", 86 | verbose = TRUE) 87 | ``` 88 | 89 | ``` r 90 | # check de start date 91 | head(met_data) 92 | ``` 93 | 94 | ``` r 95 | # check de end date 96 | tail(met_data) 97 | ``` 98 | 99 | You can save data in a CSV file setting argument `destdir = 100 | "path/to/write/files"` in `bdmep_import` function. Data will be save one 101 | file per station. 102 | 103 | A description of meteorological variables can be obtained by: 104 | 105 | ``` r 106 | bdmep_description() 107 | ``` 108 | 109 | Eventually, if the request failed a message will be prompted with the 110 | [HTTP status 111 | code](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes), for 112 | example: 113 | 114 | ``` shell 115 | ------------------------ 116 | station: `r stns_codes[1]` 117 | Bad Gateway (HTTP 502). 118 | ------------------------ 119 | station: `r stns_codes[2]` 120 | Bad Gateway (HTTP 502). 121 | ``` 122 | 123 | In this case the outcome data frame will be filled with `NA`, except for 124 | `request_status` which will return information on the request status. 125 | 126 | ### To cite this software 127 | 128 | ``` r 129 | citation("inmetr") 130 | 131 | To cite package 'inmetr' in publications use: 132 | 133 | Tatsch, J.D. 2020. inmetr R package (v 0.2.5): Historical Data from 134 | Brazilian Meteorological Stations in R. Zenodo. 135 | https://doi.org/10.5281/zenodo.580813. 136 | 137 | A BibTeX entry for LaTeX users is 138 | 139 | @Manual{, 140 | title = {inmetr: Historical Data from Brazilian Meteorological Stations in R}, 141 | author = {Jonatan Tatsch}, 142 | year = {2020}, 143 | note = {R package version 0.2.5}, 144 | doi = {https://doi.org/10.5281/zenodo.580813}, 145 | institution = {Universidade Federal de Santa Maria-UFSM}, 146 | url = {https://github.com/lhmet/inmetr}, 147 | } 148 | ``` 149 | -------------------------------------------------------------------------------- /R/metadata.R: -------------------------------------------------------------------------------- 1 | ##' Metadata on 394 meteorological stations of INMET 2 | ##' 3 | ##' Spatial coordinates, altitude and others informations of INMET's 4 | ##' meteorological stations. 5 | ##' 6 | ##' @name bdmep_meta 7 | ##' @keywords datasets 8 | ##' @docType data 9 | ##' 10 | ##' @format \code{bdmep_meta} is supplied with the \code{inmetr} package and 11 | ##' consists of the following information in a data frame with 394 rows and 9 columns. 12 | ##' \describe{ 13 | ##' \item{id}{station id, character with 5 digits corresponding to OMM code} 14 | ##' \item{lon}{longitude in decimal degrees} 15 | ##' \item{lat}{latitude in decimal degrees} 16 | ##' \item{alt}{altitude in metres} 17 | ##' \item{name}{station name} 18 | ##' \item{state}{Full name of state} 19 | ##' \item{uf}{Federative Unit} 20 | ##' \item{time_zone}{time zone} 21 | ##' \item{offset_utc}{UTC offset} 22 | ##' } 23 | ##' 24 | ##' @source \code{bdmep_meta} was compiled from 25 | ##' \url{http://www.inmet.gov.br/webcdp/climatologia/normais/imagens/normais/planilhas/Relac_Est_Meteo_NC.xls} 26 | ##' @examples 27 | ##' head(bdmep_meta) 28 | ##' with(bdmep_meta, 29 | ##' plot(lon, lat, 30 | ##' pch = 20, 31 | ##' col = abs(offset_utc), 32 | ##' main = "Met. stations of INMET") 33 | ##' ) 34 | ##' legend("bottomleft", 35 | ##' c("UTC-5", "UTC-4", "UTC-3"), 36 | ##' col = c(5:3), 37 | ##' pch = 20, 38 | ##' title = "time zone") 39 | "bdmep_meta" 40 | 41 | 42 | ##' Description of meteorological variables 43 | ##' 44 | ##' This function describe the Meteorological variables imported by \code{\link{bdmep_import}} 45 | ##' @description Get variable names, description and units 46 | ##' @importFrom dplyr %>% 47 | ##' @details to information about instruments see \url{http://www.inmet.gov.br/portal/index.php?r=home/page&page=instrumentos} 48 | ##' @return a data frame is returned with 49 | ##' \code{varname}, \code{description}, \code{unit} 50 | ##' @export 51 | ##' @author Jonatan Tatsch 52 | ##' @examples 53 | ##' met_vars <- bdmep_description() 54 | ##' met_vars 55 | ##' 56 | bdmep_description <- function() { 57 | desc <- data.frame( 58 | varname = c( 59 | "date", 60 | "id", 61 | "prec", 62 | "tair", 63 | "tw", 64 | "tmax", 65 | "tmin", 66 | "urmax", 67 | "patm", 68 | "pnmm", 69 | "wd", 70 | "wsmax", 71 | "n", 72 | "cc", 73 | "evap", 74 | "ur", 75 | "ws" 76 | ), 77 | description = c( 78 | "date and time information", 79 | "station ID", 80 | "precipitation", 81 | "air temperature", 82 | "wet bulb temperature", 83 | "maximum air temperature", 84 | "minimum air temperature", 85 | "maximum relative humidity", 86 | "atmospheric pressure", 87 | "mean sea level atmospheric pressure", 88 | "wind direction", 89 | "wind gust", 90 | "sunshine hours", 91 | "cloud cover", 92 | "evaporation", 93 | "relative humidity", 94 | "wind speed" 95 | ), 96 | unit = c( 97 | "-", 98 | "-", 99 | "mm", 100 | "deg C", 101 | "deg C", 102 | "deg C", 103 | "deg C", 104 | "%", 105 | "hPa", 106 | "hPa", 107 | "deg", 108 | "m/s", 109 | "h", 110 | "-", 111 | "mm", 112 | "%", 113 | "m/s" 114 | ), 115 | stringsAsFactors = FALSE 116 | ) 117 | new_line <- tibble::tibble( 118 | varname = "request_status", 119 | description = "Information on the status of a request", 120 | unit = NA_character_ 121 | ) 122 | desc <- dplyr::bind_rows(desc, new_line) 123 | return(desc) 124 | } 125 | 126 | 127 | ##' Get coordinates on meteorological stations 128 | ##' 129 | ##' Fetch the coordinates on meteorological stations from INMET 130 | ##' \url{http://www.inmet.gov.br/projetos/rede/pesquisa/lista_estacao.php} 131 | ##' 132 | ##' @importFrom dplyr %>% 133 | ##' @return A data frame is returned with metadata, including the stations 134 | ##' \code{id}, and coordinates (\code{lon}, \code{lat}, \code{alt}) 135 | ##' @author Jonatan Tatsch 136 | 137 | bdmep_coords <- function() { 138 | # omm id, lat, lon, alt 139 | link_stns_info <- "http://www.inmet.gov.br/sim/sonabra/index.php" 140 | 141 | txt <- httr::GET(link_stns_info) %>% 142 | httr::content("text") %>% 143 | textConnection() %>% 144 | readLines() 145 | 146 | closeAllConnections() 147 | rm(link_stns_info) 148 | 149 | txt_subset <- 150 | txt %>% 151 | stringi::stri_trans_general("latin-ascii") %>% 152 | stringr::str_subset("Codigo OMM") 153 | 154 | txt_info_num <- txt_subset %>% 155 | stringr::str_extract_all("[-+]?([0-9]*\\.[0-9]+|[0-9]+)") 156 | 157 | # rm(txt) 158 | 159 | tab_info <- 160 | txt_info_num %>% 161 | purrr::map_df(function(x) { 162 | # x <- a 163 | n <- length(x) 164 | x[c(3, n - (2:0))] %>% 165 | matrix(nrow = 1) %>% 166 | tibble::as_tibble() %>% 167 | return() 168 | }) %>% 169 | setNames(c("id", "lat", "lon", "alt")) %>% 170 | dplyr::select_("id", "lon", "lat", "alt") %>% 171 | dplyr::mutate_at(dplyr::vars(dplyr::one_of(c("lat", "lon", "alt"))), as.numeric) %>% 172 | data.frame() 173 | 174 | # tab_info <- dplyr::full_join(bdmep_stations(), tab_info, by = "id") 175 | 176 | return(tab_info) 177 | } # end function 178 | 179 | 180 | 181 | 182 | 183 | 184 | ##' Get basic information on meteorological station from INMET 185 | ##' 186 | ##' This function is used to find the OMM station ID that can be 187 | ##' used to import BDMEP data using \code{\link{bdmep_import}} 188 | ##' @description Get OMM code, state and station name on meteorological stations from INMET 189 | ##' \url{http://www.inmet.gov.br/projetos/rede/pesquisa/lista_estacao.php} 190 | ##' @importFrom dplyr %>% 191 | ##' @return a data frame is returned with 192 | ##' \code{name}, \code{state}, \code{id} 193 | ##' @author Jonatan Tatsch 194 | ##' @examples 195 | ##' 196 | ##' \dontrun{ 197 | ##' # tyr get information from inmet web site 198 | ##' stns <- bdmep_stations() 199 | ##' head(stns, 15) 200 | ##' #save(stns, file = "data/stns.rda") 201 | ##' } 202 | bdmep_stations <- function() { 203 | link_stns_l <- "http://www.inmet.gov.br/projetos/rede/pesquisa/lista_estacao.php" 204 | tab <- httr::GET(link_stns_l) %>% 205 | httr::content("text") %>% 206 | xml2::read_html() %>% 207 | rvest::html_node("table") %>% 208 | rvest::html_table(header = TRUE) 209 | 210 | ## remove colum named " " 211 | tab <- tab %>% 212 | names() %>% 213 | stringr::str_trim(.) %>% 214 | purrr::discard(str_empty) %>% 215 | subset(tab, sel = .) 216 | 217 | tab <- tab %>% 218 | names() %>% 219 | tolower() %>% 220 | # replace accented characters with non-accented counterpart 221 | stringi::stri_trans_general("latin-ascii") %>% 222 | stringr::str_replace_all(" ", "_") %>% 223 | stringr::str_replace("_da", "") %>% 224 | setNames(tab, nm = .) %>% 225 | tidyr::separate(nome_estacao, c("nome", "estado"), sep = " - ") 226 | tab <- tab %>% 227 | data.frame() %>% 228 | setNames(c("name", "state", "id")) %>% 229 | dplyr::mutate(id = as.character(id)) 230 | return(tab) 231 | } -------------------------------------------------------------------------------- /R/bdmep.R: -------------------------------------------------------------------------------- 1 | ##' Read data downaloaded from BDMEP 2 | ##' 3 | ##' Read and tidy data downloaded with \code{\link{bdmep_import}} 4 | ##' 5 | ##' @importFrom utils read.csv2 head 6 | ##' 7 | ##' @details A minimum quality control check is applied to the data 8 | ##' This include: a chronological sequence check; filling missing dates with NA; 9 | ##' remove duplicated data; aggregate time and date information into a POSIX object 10 | ##' 11 | ##' @param x a numeric vector with the meteorological station code 12 | ##' 13 | ##' @return a data frame with variables in columns and observations along rows 14 | ##' @author Jonatan Tatsch 15 | ##' 16 | bdmep_read <- function(x) { 17 | # x = r2 18 | # find line with variables names 19 | rowheader <- x %>% 20 | # toUTF8() 21 | stringr::str_detect("Data;Hora;") %>% 22 | which() 23 | # variable names 24 | h <- x[rowheader] 25 | 26 | # extract header and fix it 27 | h_fix <- h %>% 28 | stringr::str_replace("VelocidadeVentoInsolacao;", "VelocidadeVento;Insolacao;") %>% 29 | stringr::str_split(";") %>% 30 | unlist() 31 | 32 | to_discard <- h_fix %>% 33 | magrittr::equals("") %>% 34 | which() 35 | 36 | h_fix <- h_fix[-to_discard] 37 | h_fix <- gsub(" ", "", as.character(h_fix)) 38 | 39 | ## replace original vnames by the new ones 40 | # new_vnames <- c("codigo", "data","hora", 41 | # "prec", "tair", "tw", "tmax", "tmin", "urmax", 42 | # "patm", "pnmm", "wd", "wsmax", "n", "cc", "evap", "tcomp", "ur", "ws") 43 | # vnames <- doBy::recodeVar(as.character(h_fix), 44 | # src = as.list(as.character(h_fix)), 45 | # tgt = as.list(new_vnames)) 46 | 47 | vnames <- dplyr::recode(h_fix, 48 | Estacao = "codigo", 49 | Data = "data", 50 | Hora = "hora", 51 | Precipitacao = "prec", 52 | TempBulboSeco = "tair", 53 | TempBulboUmido = "tw", 54 | TempMaxima = "tmax", 55 | TempMinima = "tmin", 56 | UmidadeRelativa = "urmax", 57 | PressaoAtmEstacao = "patm", 58 | PressaoAtmMar = "pnmm", 59 | DirecaoVento = "wd", 60 | VelocidadeVento = "wsmax", 61 | Insolacao = "n", 62 | Nebulosidade = "cc", 63 | EvaporacaoPiche = "evap", 64 | TempCompMedia = "tcomp", # unnecessary, but recode can deal with 65 | UmidadeRelativaMedia = "ur", 66 | VelocidadedoVentoMedia = "ws" 67 | ) 68 | 69 | x_clean <- x %>% 70 | magrittr::extract((rowheader + 1):(length(x) - 1)) %>% 71 | stringr::str_replace(";$", "") 72 | 73 | bdmepd <- read.csv2( 74 | text = x_clean, 75 | header = FALSE, 76 | stringsAsFactors = FALSE, 77 | na.strings = "" 78 | ) 79 | bdmepd <- tibble::as_tibble(bdmepd) 80 | 81 | # stop if there is conflict between ncol(x) and length(hvec) 82 | if (ncol(bdmepd) != length(vnames)) { 83 | print(head(bdmepd)) 84 | cat( 85 | "ncol(x) = ", ncol(bdmepd), "\n", 86 | "hvec = ", vnames, "\n", "\n" 87 | ) 88 | 89 | stop("num. of data columns does not match the num. of variables") 90 | } else { 91 | names(bdmepd) <- vnames 92 | } # end if 93 | 94 | # bdmepd_bck <- bdmepd 95 | 96 | # coercion to numeric due to na.strings = "" 97 | sel_vars <- names(bdmepd)[!names(bdmepd) %in% c("codigo", "data", "hora")] 98 | bdmepd <- bdmepd %>% 99 | dplyr::mutate_at(sel_vars, as.numeric) 100 | 101 | ## date conversion 102 | bdmepd <- bdmepd %>% 103 | # dplyr::mutate(hora = doBy::recodeVar(as.character(hora), 104 | # src = as.list(c("1800","0","1200")), 105 | # tgt = as.list(c("18:00","00:00","12:00")) 106 | # ), 107 | dplyr::mutate( 108 | hora = dplyr::recode(as.character(hora), 109 | `1800` = "18:00", 110 | `0` = "00:00", 111 | `1200` = "12:00" 112 | ), 113 | date = as.POSIXct(paste(as.Date(data, 114 | format = "%d/%m/%Y" 115 | ), 116 | hora, 117 | sep = " " 118 | ), 119 | tz = "UTC" 120 | ), 121 | data = NULL, 122 | hora = NULL, 123 | id = as.character(codigo), 124 | codigo = NULL 125 | ) 126 | # reorder columns 127 | bdmepd <- bdmepd %>% 128 | # dplyr::select(date, id, prec:ws, -tcomp) 129 | dplyr::select(date, id, prec:ws) 130 | 131 | # duplicated rows 132 | bdmepd <- dplyr::distinct(bdmepd) 133 | 134 | return(bdmepd) 135 | } ## end function readInmet 136 | 137 | 138 | #' Set username and password to login BDMEP 139 | #' 140 | #' @param lnk url to BDMEP access 141 | #' @param email your BDMEP username 142 | #' @param passwd your BDMEP password 143 | #' 144 | ##' @return a named list with user name, password and text of button access 145 | ##' @author Jonatan Tatsch 146 | ##' 147 | set_bdmep_user <- function(lnk, email, passwd) { 148 | txt <- httr::GET(lnk) 149 | attrs_name_passwd_bt <- txt %>% 150 | httr::content("text") %>% 151 | xml2::read_html() %>% 152 | rvest::html_nodes("form") %>% 153 | rvest::html_nodes("input") %>% 154 | magrittr::extract(c(3:4, 6)) %>% 155 | rvest::html_attr("name") 156 | 157 | vals_name_passwd_bt <- txt %>% 158 | httr::content("text") %>% 159 | xml2::read_html() %>% 160 | rvest::html_nodes("form") %>% 161 | rvest::html_nodes("input") %>% 162 | magrittr::extract(c(3:4, 6)) %>% 163 | rvest::html_attr("value") 164 | 165 | # put values in a named list 166 | l <- seq_along(vals_name_passwd_bt) %>% 167 | lapply(function(i) vals_name_passwd_bt[i]) %>% 168 | setNames(attrs_name_passwd_bt) 169 | # add email and passwd 170 | l <- purrr::update_list(l, mCod = email, mSenha = passwd) 171 | return(l) 172 | } 173 | 174 | 175 | 176 | bdmep_rawdata <- function(id, 177 | sdate = "01/01/1961", 178 | edate = format(Sys.Date(), "%d/%m/%Y"), 179 | email, 180 | passwd, 181 | verbose = TRUE) { 182 | # id = stns_codes[1]; sdate; edate; email 183 | # step 1 - login 184 | link <- "http://www.inmet.gov.br/projetos/rede/pesquisa/inicio.php" 185 | bdmep_form_l <- set_bdmep_user(link, email, passwd) 186 | r <- httr::POST(link, body = bdmep_form_l, encode = "form") 187 | 188 | # to avoid getting flagged as a spammer 189 | Sys.sleep(1) 190 | 191 | if (httr::status_code(r) == 200 & verbose) { 192 | message( 193 | "\n", "------------------------------", "\n", 194 | "station: ", id 195 | ) 196 | } 197 | # visualize(r) 198 | 199 | # step 2 - get data 200 | # all attributes selected - previous version 201 | # my_att <- "1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1," 202 | 203 | # SOLUTION FOR ISSUE with "82098" MACAPA-AP station 204 | # excluding Temp Comp Media (which was removed after in bdmep_read) 205 | # before request data 206 | my_att <- "1,1,1,1,1,1,1,1,1,1,1,1,1,,1,1," 207 | # 1,,,,,,,,,,,,,,,,# tair - TempBulboSeco 208 | # ,1,,,,,,,,,,,,,,,# tw - TempBulboUmido 209 | # ,,1,,,,,,,,,,,,,,# tmax - TempMaxima 210 | # ,,,1,,,,,,,,,,,,,# tmin - TempMinima 211 | # ,,,,1,,,,,,,,,,,,# ur - UmidadeRelativa 212 | # ,,,,,1,,,,,,,,,,,# patm - PressaoAtmEstacao 213 | # ,,,,,,1,,,,,,,,,,# pnmm - PressaoAtmMar 214 | # ,,,,,,,1,,,,,,,,,# wd - DirecaoVento 215 | # ,,,,,,,,1,,,,,,,,# ws - VelocidadeVento 216 | # ,,,,,,,,,1,,,,,,,# n - insolacao 217 | # ,,,,,,,,,,1,,,,,,# prec - precipitacao 218 | # ,,,,,,,,,,,1,,,,,# cc - Nebulosidade 219 | # ,,,,,,,,,,,,1,,,,# evap - Evaporacao Piche 220 | # ,,,,,,,,,,,,,1,,,# tcomp - Temp Comp Media 221 | # ,,,,,,,,,,,,,,1,,# ur - Umidade Relativa Media 222 | # ,,,,,,,,,,,,,,,1,# ws_avg - Velocidade do Vento Media 223 | 224 | url_data <- "http://www.inmet.gov.br/projetos/rede/pesquisa/gera_serie_txt.php?&mRelEstacao=XXXXX&btnProcesso=serie&mRelDtInicio=dd/mm/yyyy&mRelDtFim=DD/MM/YYYY&mAtributos=my_att" 225 | url_data <- gsub("my_att", my_att, url_data) 226 | # url_data <- "http://www.inmet.gov.br/projetos/rede/pesquisa/gera_serie_txt.php?&mRelEstacao=82098&btnProcesso=serie&mRelDtInicio=01/01/1961&mRelDtFim=30/04/2018&mAtributos=,,1,1,,,,,,1,1,,1,1,1,1," 227 | # url_data <- "http://www.inmet.gov.br/projetos/rede/pesquisa/gera_serie_txt.php?&mRelEstacao=83980&btnProcesso=serie&mRelDtInicio=01/01/1961&mRelDtFim=01/01/2017&mAtributos=1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1," 228 | 229 | # link to station data 230 | url_data <- url_data %>% 231 | stringr::str_replace("XXXXX", as.character(id)) %>% 232 | stringr::str_replace("dd/mm/yyyy", sdate) %>% 233 | stringr::str_replace("DD/MM/YYYY", edate) 234 | 235 | # request data 236 | r2 <- httr::GET(url_data) 237 | 238 | # to avoid getting flagged as a spammer 239 | Sys.sleep(1) 240 | 241 | return(r2) 242 | } 243 | 244 | 245 | .build_msg_nodata <- function(.id, .sdate, .edate){ 246 | msg_nodata_req <- paste0( 247 | "Nao existem dados disponiveis da estacao: ", 248 | paste(c( 249 | t( 250 | dplyr::filter(bdmep_meta, id == .id) %>% 251 | dplyr::select(dplyr::one_of(c("name", "uf"))) 252 | ) 253 | ), 254 | collapse = "-" 255 | ), 256 | " para o periodo de ", 257 | .sdate, 258 | " a ", 259 | .edate 260 | ) 261 | } 262 | 263 | ##' Import data of a meteorological station 264 | ##' 265 | ##' @importFrom stats setNames 266 | ##' @importFrom dplyr %>% 267 | ##' 268 | ##' @details The data are in sub-daily time scale. A minimum data quality control is applied to the data. 269 | ##' This include: a chronological sequence check; filling data from missing dates with NA; 270 | ##' remove duplicated data. Time variables (year, month, day, hour) are aggregated into a POSIX object in UTC 271 | ##' 272 | ##' @param .id a character vector with the meteorological station code 273 | ##' @param .sdate start date in "d/m/Y" format 274 | ##' @param .edate end date in "d/m/Y" format, default values \code{format(Sys.Date(), "\%d/\%m/\%Y")} 275 | ##' @param .email e-mail to access BDMEP 276 | ##' @param .passwd password to access BDMEP 277 | ##' @param .verbose Optional. Logical. If set to TRUE (default), print messages. 278 | ##' @param .destdir Optional. Character Local file path to write file out to.If NULL (default) files are not written to disk. 279 | ##' @param .na.strings a character string which is to be interpreted as NA values. 280 | ##' @return a data frame with variables in columns (see \code{\link{bdmep_description}}) and observations (date and time) along rows. 281 | ##' @author Jonatan Tatsch 282 | ##' 283 | bdmep_import_station <- function(.id = "83844", 284 | .sdate, 285 | .edate, 286 | .email, 287 | .passwd, 288 | .verbose = TRUE, 289 | .destdir = NULL, 290 | .na.strings = "-9999") { 291 | 292 | # start and end dates are to the to the available span in bdmep_rawdata() 293 | r2 <- bdmep_rawdata(id = .id, email = .email, passwd = .passwd, verbose = .verbose) 294 | 295 | msg <- httr::http_status(r2)$message 296 | 297 | # httr::stop_for_status(r2) 298 | if (.verbose) { 299 | httr::message_for_status(r2) 300 | cat("\n") 301 | } 302 | 303 | # to deal with network connection problem, add column to inform request status 304 | if (httr::status_code(r2) != 200) { 305 | xtidy <- bdmep_template(.id, msg) 306 | return(xtidy) 307 | } 308 | 309 | # convert request data to text 310 | x <- r2 %>% 311 | httr::content("text") %>% 312 | textConnection(local = TRUE) %>% 313 | readLines() 314 | 315 | # if there are no data in database for 1961-current date 316 | pos_warn <- which(stringr::str_detect(x, "existem dados disp")) 317 | if (length(pos_warn) > 0) { 318 | msg_nodata <- stringr::str_replace(x[pos_warn], "
", "")
319 |     if (.verbose) message(msg_nodata)
320 |     xtidy <- bdmep_template(.id, msg_nodata)
321 |     return(xtidy)
322 |   }
323 | 
324 |   # tidy data and output
325 |   xtidy <- bdmep_read(x)
326 | 
327 |   # filter data for requested dates interval
328 |   xtidy <- dplyr::filter(xtidy, date >= lubridate::dmy(.sdate) & date <= lubridate::dmy(.edate))
329 |   if (nrow(xtidy) > 0) {
330 |     date_span <- as.Date(range(xtidy$date))
331 |     date_req <- as.Date(lubridate::dmy(c(.sdate, .edate)))
332 |     check_dates_span <- dplyr::between(date_req, date_span[1], date_span[2])
333 |     if (any(!isTRUE(check_dates_span))) {
334 |       if (.verbose) message("Returning data available span: ", paste(date_span, collapse = "--"))
335 |     }
336 |   } else {
337 |     # if there are no data in the requested span
338 |     msg_nodata_req <- .build_msg_nodata(.id, .sdate, .edate)
339 |     if (.verbose) {
340 |       message(msg_nodata_req)
341 |     }
342 |     
343 |     xtidy <- bdmep_template(.id, msg_nodata_req)
344 |     return(xtidy)
345 |   }
346 | 
347 | 
348 |   # column with status
349 |   xtidy <- dplyr::mutate(xtidy, request_status = msg)
350 | 
351 |   if (!is.null(.destdir)) {
352 |     bdmep_write_csv(
353 |       data_bdmep = xtidy,
354 |       folder = .destdir,
355 |       na.strings = .na.strings,
356 |       verbose = .verbose
357 |     )
358 | 
359 |     data_status <- bdmep_data_status(xtidy)
360 |     return(data_status)
361 |   }
362 | 
363 |   return(xtidy)
364 | }
365 | 
366 | 
367 | ##' Import data from Brazilian meteorological stations
368 | ##'
369 | ##' @importFrom dplyr %>%
370 | ##' @details The data are in sub-daily time scale. A minimum data quality control is applied to the data.
371 | ##' This include: a chronological sequence check; filling data from missing dates with NA;
372 | ##' remove duplicated data. Time variables (year, month, day, hour) are aggregated into a POSIX object in UTC
373 | ##'
374 | ##' @param id A character vector with codes of meteorological stations
375 | ##' @param sdate Start date in "d/m/Y" format
376 | ##' @param edate End date in "d/m/Y" format, default values \code{format(Sys.Date(), "\%d/\%m/\%Y")}
377 | ##' @param email E-mail to access BDMEP
378 | ##' @param passwd Password to access BDMEP
379 | ##' @param verbose If TRUE, prints login sucessfull.
380 | ##' @param destdir A character string with the path where the downloaded data is saved. If it is  NULL, data will not be saved in disk.
381 | ##' @param na.strings a character string which is to be interpreted as NA values. \code{na.strings} is only used when destdir is not NULL.
382 | ##'
383 | ##' @return A data frame with variables in columns (see \code{\link{bdmep_description}}) and observations (date and time) along rows.
384 | ##' @export
385 | ##' @author Jonatan Tatsch
386 | ##' @examples
387 | ##' \dontrun{
388 | ##' # download data for Santa Maria and Porto Alegre
389 | ##' metdata <- bdmep_import(id = c("83936", "83967"),
390 | ##'                         sdate = "01/01/2015", # could be "01/01/1961"
391 | ##'                         edate = format(Sys.Date(), '%d/%m/%Y'),
392 | ##'                         email = "your@email.com",
393 | ##'                         passwd = "your-password",
394 | ##'                         verbose = TRUE)
395 | ##' head(metdata)
396 | ##' tail(metdata)
397 | ##' summary(metdata)
398 | ##' }
399 | ##'
400 | bdmep_import <- function(id = c("83844", "83967"),
401 |                          sdate = "01/01/1961",
402 |                          edate = format(Sys.Date(), "%d/%m/%Y"),
403 |                          email = "your@email.com",
404 |                          passwd = "your-password",
405 |                          verbose = TRUE,
406 |                          destdir = NULL,
407 |                          na.strings = "-9999") {
408 | 
409 |   # check arguments precondition ----------------------------------------------
410 |   id <- as.character(id)
411 |   sdate <- stringr::str_trim(as.character(sdate))
412 |   edate <- stringr::str_trim(as.character(edate))
413 | 
414 |   stopifnot(
415 |     unique(nchar(id)) == 5,
416 |     all(id %in% inmetr::bdmep_meta$id),
417 |     length(unlist(stringr::str_extract_all(sdate, "/"))) == 2,
418 |     length(unlist(stringr::str_extract_all(edate, "/"))) == 2,
419 |     stringr::str_detect(email, "@"),
420 |     is.character(passwd),
421 |     is.logical(verbose),
422 |     is.null(destdir) | is.character(destdir)
423 |   )
424 |   if (!is.null(destdir)) stopifnot(dir.exists(destdir))
425 |   # import data ---------------------------------------------------------------
426 |   purrr::map_df(id, ~ bdmep_import_station(.x,
427 |     .sdate = sdate,
428 |     .edate = edate,
429 |     .email = email,
430 |     .passwd = passwd,
431 |     .verbose = verbose,
432 |     .destdir = destdir,
433 |     .na.strings = na.strings
434 |   ))
435 | }
436 | 
437 | 
438 | #' Template bdmep dataframe to be used when the status of a request was not successfully executed.
439 | #'
440 | #' @details This is used when the status of a request code is not 200.
441 | #'
442 | #' @param .id a character scalar with the meteorological station code
443 | #' @param .req_status character scalar with information on the status of a request
444 | #'
445 | #' @importFrom dplyr %>%
446 | #' @return a dataframe with variables filled with NA, except for id and request_status
447 | bdmep_template <- function(.id, .req_status) {
448 |   varnames <- bdmep_description()[, "varname"]
449 |   templ_df <- as.data.frame(
450 |     t(rep(NA, length(varnames))),
451 |     stringsAsFactors = FALSE
452 |   )
453 |   templ_df <- templ_df %>%
454 |     setNames(varnames) %>%
455 |     dplyr::mutate(
456 |       id = as.character(.id),
457 |       request_status = as.character(.req_status)
458 |     )
459 |   templ_df
460 | }


--------------------------------------------------------------------------------