├── tests ├── testthat │ ├── setup.R │ ├── test_data │ │ ├── pxm1_test.rda │ │ ├── filter_query.json │ │ ├── test_query_px.json │ │ └── test_query_sdmx.json │ ├── test-README.R │ ├── test-defunct.R │ ├── test-pxweb_api_catalogue.R │ ├── test-pxweb_test_api.R │ ├── test-pxweb_api_paths.R │ ├── test-pxweb_data_comments.R │ ├── test-pxweb_as_dataframe.R │ └── test-pxweb_constructor.R └── testthat.R ├── .github ├── .gitignore └── workflows │ ├── check-release.yaml │ ├── test-coverage.yaml │ ├── check-standard.yaml │ ├── R-CMD-check.yaml │ └── rogtemplate-gh-pages.yaml ├── paper ├── .gitignore ├── README.md ├── RJwrapper.tex ├── main.R ├── softwarereview.tex ├── bookreview.tex └── codesnippet.tex ├── man ├── figures │ └── logo.png ├── pxweb_fix_url.Rd ├── pxweb_c.Rd ├── pxweb_data_c.Rd ├── pxe_data_url.Rd ├── add_pxe_defaults.Rd ├── pxweb_query_dim.Rd ├── assert_pxweb.Rd ├── pxweb_tempdir.Rd ├── assert_pxweb_data.Rd ├── pxweb_get_api_test_data_frame.Rd ├── assert_pxweb_url.Rd ├── pxe_position_title.Rd ├── pxweb_metadata_dim.Rd ├── assert_pxweb_config.Rd ├── assert_pxweb_levels.Rd ├── pxweb_data_dim.Rd ├── as_pxweb_levels.Rd ├── assert_pxweb_calls.Rd ├── is_pxweb_config_response.Rd ├── parse_url_or_fail.Rd ├── pxweb_as_json.Rd ├── pxweb_data_colnames.Rd ├── assert_pxweb_metadata.Rd ├── assert_pxweb_query.Rd ├── pxe_position_is_metadata.Rd ├── pxweb_query_filter.Rd ├── pxweb_metadata_time.Rd ├── pxweb_query_values.Rd ├── pxe_print_download_code.Rd ├── assert_pxweb_rda_file_path.Rd ├── pxe_position_multiple_choice_allowed.Rd ├── assert_pxweb_api_catalogue.Rd ├── assert_pxweb_data_comments.Rd ├── assert_pxweb_database_list.Rd ├── pxweb_cite.Rd ├── pxe_position_is_api_catalogue.Rd ├── pxweb_data.Rd ├── pxweb_metadata_elimination.Rd ├── pxweb_query_as_rcode.Rd ├── str_pad.Rd ├── pxe_metadata_variable_names.Rd ├── pxweb_interactive_input.Rd ├── pxweb_levels.Rd ├── pxweb_test_create_api_paths.Rd ├── pxe_pxobj_at_position.Rd ├── pxweb_add_api_subpath.Rd ├── pxweb_metadata.Rd ├── print.pxweb_api_catalogue_entry.Rd ├── pxe_position_choice_size.Rd ├── assert_pxweb_input_allowed.Rd ├── pxe_position_is_full_query.Rd ├── pxe_position_variable_can_be_eliminated.Rd ├── pxe_metadata_choices.Rd ├── pxweb_add_config.Rd ├── pxweb_data_jsonstat.Rd ├── str_trim.Rd ├── pxweb_clear_cache.Rd ├── pxweb_database_list.Rd ├── assert_query_can_be_split_to_batches.Rd ├── pxweb_test_time_limit.Rd ├── assert_pxweb_data_jsonstat.Rd ├── split_dimensions_left_right.Rd ├── pxe_interactive_get_data.Rd ├── generate_permutations.Rd ├── pxweb_add_call.Rd ├── pxweb_add_mandatory_variables.Rd ├── pxweb_parse_response.Rd ├── save_pxweb.Rd ├── pxd_values_to_valuetexts.Rd ├── build_pxweb_url.Rd ├── pxweb_api_catalogue_entry.Rd ├── pxe_back_position.Rd ├── pxweb_add_metadata_to_query.Rd ├── pxweb_api_catalogue.Rd ├── build_pxweb_config_url.Rd ├── pxweb_metadata_add_null_values.Rd ├── http_was_redirected.Rd ├── pxe_handle_input.Rd ├── pxe_input.Rd ├── pxweb_query_dim_splittable.Rd ├── pxe_allowed_input.Rd ├── pxweb_query_as_json.Rd ├── permutations.Rd ├── pxweb_data_column_comment.Rd ├── build_pxweb_rda_file_path.Rd ├── pxweb_split_query.Rd ├── pxweb_data_comments.Rd ├── pxweb_validate_query_with_metadata.Rd ├── pxweb_http_log_on.Rd ├── pxweb_interactive.Rd ├── pxweb_query.Rd ├── pxweb.Rd ├── pxweb_advanced_get.Rd ├── pxweb_get_data.Rd ├── pxweb_test_api.Rd ├── pxweb-package.Rd ├── api_catalogue.Rd ├── pxweb_explorer.Rd ├── pxweb_get.Rd ├── pxweb_as_data_frame.Rd └── pxweb_api_name.Rd ├── LICENSE ├── vignettes ├── d_example.rda ├── pxd_example.rda ├── pxfp_example.rda ├── px_meta_example.rda ├── pxjstat_example.rda ├── main.R ├── px_levels_example.rda └── pxweb_cite_example.rda ├── inst ├── examples │ ├── hierarchy.RData │ ├── ex_statfi_getdata.R │ ├── ex_time_tracking_graphs.R │ ├── ex_get_data.R │ ├── ex_data_mining.R │ └── ex_dimension_mining.R ├── extras │ ├── cheatsheet_pxweb.pptx │ ├── build.cran.sh │ ├── document.R │ └── old │ │ ├── StatfiTests.R │ │ └── TODO.md ├── extdata │ ├── test_files │ │ ├── testFiles.Rdata │ │ ├── responseTest.Rdata │ │ └── json_queries │ │ │ ├── json_single_query_test.json │ │ │ └── json_full_test_query.json │ └── examples │ │ ├── json_query_example.json │ │ ├── json-stat_query_example.json │ │ ├── json_query_last_names.json │ │ ├── json_query_variables_example.json │ │ ├── sq-api_table_statfin_eot_pxt_132a.px.json │ │ └── json_query_agg_example.json └── CITATION ├── pkgdown ├── favicon │ ├── favicon.ico │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── apple-touch-icon.png │ ├── apple-touch-icon-120x120.png │ ├── apple-touch-icon-152x152.png │ ├── apple-touch-icon-180x180.png │ ├── apple-touch-icon-60x60.png │ └── apple-touch-icon-76x76.png └── _pkgdown.yml ├── tests_bash └── pxweb.sh ├── R ├── onAttach.R ├── utils_tests.R ├── pxweb_as_json.R ├── pxweb-package.R ├── pxweb_parse_url_or_fail.R ├── pxweb_load_save.R ├── pxweb_data_jsonstat.R ├── pxweb_cite.R ├── pxweb_build_pxweb_rda_file_path.R ├── pxweb_clear_cache.R ├── pxweb_add_api_subpath.R ├── pxweb_add_call.R ├── pxweb_levels.R ├── pxweb_database_list.R ├── pxweb_parse_response.R ├── pxweb_build_pxweb_urls.R ├── defunct_functions.R ├── pxweb_c.R ├── pxweb_logs.R ├── pxweb_assert.R ├── pxweb.R ├── pxweb_add_config.R ├── pxweb_metadata.R ├── pxweb_data.R └── pxweb_api_catalogue.R ├── .gitignore ├── .Rbuildignore ├── CONTRIBUTING.md ├── NEWS.md ├── NAMESPACE ├── DESCRIPTION ├── CODE_OF_CONDUCT.md ├── README.Rmd └── README.md /tests/testthat/setup.R: -------------------------------------------------------------------------------- 1 | library(httptest) 2 | -------------------------------------------------------------------------------- /.github/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | R-version 3 | *.Rds 4 | -------------------------------------------------------------------------------- /paper/.gitignore: -------------------------------------------------------------------------------- 1 | old 2 | RJwrapper.aux 3 | RJwrapper.out 4 | RJwrapper.log 5 | *~ 6 | -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | print(Sys.getenv("NOT_CRAN")) 2 | testthat::test_check("pxweb") 3 | -------------------------------------------------------------------------------- /man/figures/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rOpenGov/pxweb/HEAD/man/figures/logo.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | YEAR: 2013-2021 2 | COPYRIGHT HOLDER: Mans Magnusson, Love Hansson, Leo Lahti 3 | 4 | -------------------------------------------------------------------------------- /vignettes/d_example.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rOpenGov/pxweb/HEAD/vignettes/d_example.rda -------------------------------------------------------------------------------- /vignettes/pxd_example.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rOpenGov/pxweb/HEAD/vignettes/pxd_example.rda -------------------------------------------------------------------------------- /vignettes/pxfp_example.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rOpenGov/pxweb/HEAD/vignettes/pxfp_example.rda -------------------------------------------------------------------------------- /inst/examples/hierarchy.RData: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rOpenGov/pxweb/HEAD/inst/examples/hierarchy.RData -------------------------------------------------------------------------------- /pkgdown/favicon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rOpenGov/pxweb/HEAD/pkgdown/favicon/favicon.ico -------------------------------------------------------------------------------- /vignettes/px_meta_example.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rOpenGov/pxweb/HEAD/vignettes/px_meta_example.rda -------------------------------------------------------------------------------- /vignettes/pxjstat_example.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rOpenGov/pxweb/HEAD/vignettes/pxjstat_example.rda -------------------------------------------------------------------------------- /paper/README.md: -------------------------------------------------------------------------------- 1 | To reproduce the figures, tables, and manuscript PDF run in R: 2 | source("main.R") 3 | 4 | 5 | -------------------------------------------------------------------------------- /vignettes/main.R: -------------------------------------------------------------------------------- 1 | library(knitr) 2 | library(rmarkdown) 3 | 4 | render("pxweb.Rmd") 5 | knit("pxweb.Rmd") 6 | -------------------------------------------------------------------------------- /vignettes/px_levels_example.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rOpenGov/pxweb/HEAD/vignettes/px_levels_example.rda -------------------------------------------------------------------------------- /inst/extras/cheatsheet_pxweb.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rOpenGov/pxweb/HEAD/inst/extras/cheatsheet_pxweb.pptx -------------------------------------------------------------------------------- /pkgdown/favicon/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rOpenGov/pxweb/HEAD/pkgdown/favicon/favicon-16x16.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rOpenGov/pxweb/HEAD/pkgdown/favicon/favicon-32x32.png -------------------------------------------------------------------------------- /vignettes/pxweb_cite_example.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rOpenGov/pxweb/HEAD/vignettes/pxweb_cite_example.rda -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rOpenGov/pxweb/HEAD/pkgdown/favicon/apple-touch-icon.png -------------------------------------------------------------------------------- /inst/extdata/test_files/testFiles.Rdata: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rOpenGov/pxweb/HEAD/inst/extdata/test_files/testFiles.Rdata -------------------------------------------------------------------------------- /tests/testthat/test_data/pxm1_test.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rOpenGov/pxweb/HEAD/tests/testthat/test_data/pxm1_test.rda -------------------------------------------------------------------------------- /inst/extdata/test_files/responseTest.Rdata: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rOpenGov/pxweb/HEAD/inst/extdata/test_files/responseTest.Rdata -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rOpenGov/pxweb/HEAD/pkgdown/favicon/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rOpenGov/pxweb/HEAD/pkgdown/favicon/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rOpenGov/pxweb/HEAD/pkgdown/favicon/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rOpenGov/pxweb/HEAD/pkgdown/favicon/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rOpenGov/pxweb/HEAD/pkgdown/favicon/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /tests_bash/pxweb.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Need to be in Project root 3 | 4 | git log -n 1 5 | R --version 6 | Rscript --vanilla tests_bash/pxweb.R 7 | -------------------------------------------------------------------------------- /R/onAttach.R: -------------------------------------------------------------------------------- 1 | .onAttach <- function(lib, pkg) { 2 | packageStartupMessage(paste0("pxweb ", utils::packageVersion("pxweb"), ": R Interface to PXWEB APIs.\nhttps://github.com/ropengov/pxweb\n")) 3 | } 4 | -------------------------------------------------------------------------------- /inst/examples/ex_statfi_getdata.R: -------------------------------------------------------------------------------- 1 | library(pxweb) 2 | Sys.setlocale(locale="UTF-8") 3 | print(api_parameters()) 4 | baseURL <- base_url("statfi", version = "v1", lang = "fi") 5 | # d <- interactive_pxweb(baseURL) 6 | 7 | -------------------------------------------------------------------------------- /R/utils_tests.R: -------------------------------------------------------------------------------- 1 | # Functions only used for testing 2 | 3 | on_github_actions <- function() identical(Sys.getenv("GITHUB_ACTIONS"), "true") 4 | 5 | get_root_path <- function() { 6 | x <- getwd() 7 | if (on_github_actions()) x <- Sys.getenv("GITHUB_WORKSPACE") 8 | x 9 | } 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | tests/testthat/log* 2 | inst/extras/*.tar.gz 3 | inst/extras/*.RData 4 | inst/extras/*~ 5 | *~ 6 | *.Rcheck 7 | *.Rout 8 | .Rproj.user 9 | .Rhistory 10 | *.Rproj 11 | sandbox/* 12 | todo.txt 13 | TODO.tdl 14 | vignettes/pxweb.R 15 | .DS_Store 16 | .RData 17 | doc 18 | Meta 19 | docs 20 | -------------------------------------------------------------------------------- /inst/extras/build.cran.sh: -------------------------------------------------------------------------------- 1 | # !/bin/sh 2 | #/home/lemila/bin/R CMD BATCH document.R 3 | #/home/lemila/bin/R CMD build ../../ --no-build-vignettes 4 | /home/lemila/bin/R-3.6.2/bin/R CMD build ../../ 5 | /home/lemila/bin/R-3.6.2/bin/R CMD check --as-cran pxweb_0.9.14.tar.gz 6 | /home/lemila/bin/R-3.6.2/bin/R CMD INSTALL pxweb_0.9.14.tar.gz 7 | 8 | -------------------------------------------------------------------------------- /inst/extras/document.R: -------------------------------------------------------------------------------- 1 | library(devtools) 2 | document("../../") 3 | 4 | #library(knitr) 5 | #knit("../../vignettes/pxweb_tutorial.Rmd", "../../vignettes/pxweb_tutorial.md") 6 | 7 | library(knitr) 8 | knit("../../README.Rmd", "../../README.md") 9 | 10 | library(pkgdown) 11 | setwd("../../"); build_site() 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /inst/examples/ex_time_tracking_graphs.R: -------------------------------------------------------------------------------- 1 | require(ggthemes) 2 | 3 | # Time series graph 4 | tsgraph <- ggplot(timeSeries,aes(x=obs,y=time,color=as.factor(level))) + 5 | geom_line() + 6 | geom_smooth() + 7 | ggtitle("Data query time series") + 8 | scale_color_discrete(name="Node level") + 9 | scale_y_continuous(minor_breaks = seq(0,4,0.25)) 10 | tsgraph -------------------------------------------------------------------------------- /man/pxweb_fix_url.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb.R 3 | \name{pxweb_fix_url} 4 | \alias{pxweb_fix_url} 5 | \title{Fix url characters} 6 | \usage{ 7 | pxweb_fix_url(x) 8 | } 9 | \arguments{ 10 | \item{x}{a string to fix} 11 | } 12 | \description{ 13 | Fix url characters 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /man/pxweb_c.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_c.R 3 | \name{pxweb_c} 4 | \alias{pxweb_c} 5 | \title{Combine pxweb objects} 6 | \usage{ 7 | pxweb_c(x) 8 | } 9 | \arguments{ 10 | \item{x}{a list with \code{pxweb} objects.} 11 | } 12 | \description{ 13 | Combine pxweb objects 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /man/pxweb_data_c.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_c.R 3 | \name{pxweb_data_c} 4 | \alias{pxweb_data_c} 5 | \title{Combine pxweb objects} 6 | \usage{ 7 | pxweb_data_c(x) 8 | } 9 | \arguments{ 10 | \item{x}{a list with \code{pxweb} objects.} 11 | } 12 | \description{ 13 | Combine pxweb objects 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /man/pxe_data_url.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_interactive.R 3 | \name{pxe_data_url} 4 | \alias{pxe_data_url} 5 | \title{Get the url to a table} 6 | \usage{ 7 | pxe_data_url(x) 8 | } 9 | \arguments{ 10 | \item{x}{a \code{pxweb_explorer} object} 11 | } 12 | \description{ 13 | Get the url to a table 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /tests/testthat/test-README.R: -------------------------------------------------------------------------------- 1 | context("repo README") 2 | 3 | test_that("README works as expected", { 4 | skip_if_not(on_github_actions()) 5 | 6 | root_path <- get_root_path() 7 | fp <- file.path(root_path, "README.Rmd") 8 | 9 | expect_message(output <- capture.output(krm <- knitr::knit(fp, output = "tmp.md")), 10 | regexp = "output file: tmp.md" 11 | ) 12 | file.remove("tmp.md") 13 | }) 14 | -------------------------------------------------------------------------------- /man/add_pxe_defaults.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_interactive.R 3 | \name{add_pxe_defaults} 4 | \alias{add_pxe_defaults} 5 | \title{Add default values to pxe} 6 | \usage{ 7 | add_pxe_defaults(pxe) 8 | } 9 | \arguments{ 10 | \item{pxe}{a \code{pxweb_explorer} object} 11 | } 12 | \description{ 13 | Add default values to pxe 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /man/pxweb_query_dim.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_query.R 3 | \name{pxweb_query_dim} 4 | \alias{pxweb_query_dim} 5 | \title{Compue the dimension of the query} 6 | \usage{ 7 | pxweb_query_dim(pxq) 8 | } 9 | \arguments{ 10 | \item{pxq}{a \code{pxweb_query} object.} 11 | } 12 | \description{ 13 | Compue the dimension of the query 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /man/assert_pxweb.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_assert.R 3 | \name{assert_pxweb} 4 | \alias{assert_pxweb} 5 | \title{Assert that the url structure is correct} 6 | \usage{ 7 | assert_pxweb(x) 8 | } 9 | \arguments{ 10 | \item{x}{a object to assert} 11 | } 12 | \description{ 13 | Assert that the \code{url} slot in the \code{pxweb} object is correct. 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /man/pxweb_tempdir.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb.R 3 | \name{pxweb_tempdir} 4 | \alias{pxweb_tempdir} 5 | \title{Setup temorary directory for the pxweb} 6 | \usage{ 7 | pxweb_tempdir(to = "apis") 8 | } 9 | \arguments{ 10 | \item{to}{to what part of the temp folder (apis or logs)} 11 | } 12 | \description{ 13 | Setup temorary directory for the pxweb 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /man/assert_pxweb_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_data.R 3 | \name{assert_pxweb_data} 4 | \alias{assert_pxweb_data} 5 | \title{Assert that x is a correct \code{pxweb_data} object.} 6 | \usage{ 7 | assert_pxweb_data(x) 8 | } 9 | \arguments{ 10 | \item{x}{an object to check.} 11 | } 12 | \description{ 13 | Assert that x is a correct \code{pxweb_data} object. 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /man/pxweb_get_api_test_data_frame.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_test_api_endpoint.R 3 | \name{pxweb_get_api_test_data_frame} 4 | \alias{pxweb_get_api_test_data_frame} 5 | \title{Build api test data.frame} 6 | \usage{ 7 | pxweb_get_api_test_data_frame(x) 8 | } 9 | \arguments{ 10 | \item{x}{a pxweb object} 11 | } 12 | \description{ 13 | Build api test data.frame 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /man/assert_pxweb_url.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_assert.R 3 | \name{assert_pxweb_url} 4 | \alias{assert_pxweb_url} 5 | \title{Assert that the url structure is correct} 6 | \usage{ 7 | assert_pxweb_url(x) 8 | } 9 | \arguments{ 10 | \item{x}{a object to assert} 11 | } 12 | \description{ 13 | Assert that the \code{url} slot in the \code{pxweb} object is correct. 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /man/pxe_position_title.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_interactive.R 3 | \name{pxe_position_title} 4 | \alias{pxe_position_title} 5 | \title{Get the table title for the current position} 6 | \usage{ 7 | pxe_position_title(x) 8 | } 9 | \arguments{ 10 | \item{x}{a \code{pxweb_explorer} object.} 11 | } 12 | \description{ 13 | Get the table title for the current position 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /man/pxweb_metadata_dim.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_metadata.R 3 | \name{pxweb_metadata_dim} 4 | \alias{pxweb_metadata_dim} 5 | \title{Compue the dimension of a metadata object} 6 | \usage{ 7 | pxweb_metadata_dim(pxmd) 8 | } 9 | \arguments{ 10 | \item{pxmd}{a \code{pxweb_metadata} object.} 11 | } 12 | \description{ 13 | Compue the dimension of a metadata object 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /man/assert_pxweb_config.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_assert.R 3 | \name{assert_pxweb_config} 4 | \alias{assert_pxweb_config} 5 | \title{Assert that the config slot is correct} 6 | \usage{ 7 | assert_pxweb_config(x) 8 | } 9 | \arguments{ 10 | \item{x}{a object to assert} 11 | } 12 | \description{ 13 | Assert that the \code{config} slot in the \code{pxweb} object is correct. 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /man/assert_pxweb_levels.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_levels.R 3 | \name{assert_pxweb_levels} 4 | \alias{assert_pxweb_levels} 5 | \title{Assert that x is a correct \code{pxweb_levels} object.} 6 | \usage{ 7 | assert_pxweb_levels(x) 8 | } 9 | \arguments{ 10 | \item{x}{an object to check.} 11 | } 12 | \description{ 13 | Assert that x is a correct \code{pxweb_levels} object. 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /man/pxweb_data_dim.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_data.R 3 | \name{pxweb_data_dim} 4 | \alias{pxweb_data_dim} 5 | \title{Compute the dimension of the query \code{pxweb_data} object} 6 | \usage{ 7 | pxweb_data_dim(pxd) 8 | } 9 | \arguments{ 10 | \item{pxd}{a \code{pxweb_data} object.} 11 | } 12 | \description{ 13 | Compute the dimension of the query \code{pxweb_data} object 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /man/as_pxweb_levels.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_database_list.R 3 | \name{as_pxweb_levels} 4 | \alias{as_pxweb_levels} 5 | \title{Assert that x is a correct \code{pxweb_database_list} object.} 6 | \usage{ 7 | as_pxweb_levels(x) 8 | } 9 | \arguments{ 10 | \item{x}{an object to check.} 11 | } 12 | \description{ 13 | Assert that x is a correct \code{pxweb_database_list} object. 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /man/assert_pxweb_calls.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_assert.R 3 | \name{assert_pxweb_calls} 4 | \alias{assert_pxweb_calls} 5 | \title{Assert that the rda_file_path is correct} 6 | \usage{ 7 | assert_pxweb_calls(x) 8 | } 9 | \arguments{ 10 | \item{x}{a object to assert} 11 | } 12 | \description{ 13 | Assert that the \code{rda_file_path} slot in the \code{pxweb} object is correct. 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /man/is_pxweb_config_response.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_add_config.R 3 | \name{is_pxweb_config_response} 4 | \alias{is_pxweb_config_response} 5 | \title{Check if a response is a pxweb config response} 6 | \usage{ 7 | is_pxweb_config_response(x) 8 | } 9 | \arguments{ 10 | \item{x}{a response object} 11 | } 12 | \description{ 13 | Check if a response is a pxweb config response 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /man/parse_url_or_fail.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_parse_url_or_fail.R 3 | \name{parse_url_or_fail} 4 | \alias{parse_url_or_fail} 5 | \title{Parse a character string or throws error if it fails} 6 | \usage{ 7 | parse_url_or_fail(x) 8 | } 9 | \arguments{ 10 | \item{x}{a character element to parse} 11 | } 12 | \description{ 13 | Parse a character string or throws error if it fails 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /man/pxweb_as_json.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_as_json.R 3 | \name{pxweb_as_json} 4 | \alias{pxweb_as_json} 5 | \alias{pxweb_as_json.pxweb_query} 6 | \title{Convert object to json} 7 | \usage{ 8 | pxweb_as_json(x) 9 | 10 | \method{pxweb_as_json}{pxweb_query}(x) 11 | } 12 | \arguments{ 13 | \item{x}{an object to convert.} 14 | } 15 | \description{ 16 | Convert object to json 17 | } 18 | \keyword{internal} 19 | -------------------------------------------------------------------------------- /man/pxweb_data_colnames.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_data.R 3 | \name{pxweb_data_colnames} 4 | \alias{pxweb_data_colnames} 5 | \title{Get query filter} 6 | \usage{ 7 | pxweb_data_colnames(pxd, type = "text") 8 | } 9 | \arguments{ 10 | \item{pxd}{a \code{pxweb_data} object.} 11 | } 12 | \value{ 13 | character vector with column names. 14 | } 15 | \description{ 16 | Get query filter 17 | } 18 | \keyword{internal} 19 | -------------------------------------------------------------------------------- /man/assert_pxweb_metadata.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_metadata.R 3 | \name{assert_pxweb_metadata} 4 | \alias{assert_pxweb_metadata} 5 | \title{Assert that x is a correct \code{pxweb_metadata} object.} 6 | \usage{ 7 | assert_pxweb_metadata(x) 8 | } 9 | \arguments{ 10 | \item{x}{an object to check.} 11 | } 12 | \description{ 13 | Assert that x is a correct \code{pxweb_metadata} object. 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /R/pxweb_as_json.R: -------------------------------------------------------------------------------- 1 | #' Convert object to json 2 | #' 3 | #' @param x an object to convert. 4 | #' 5 | #' @keywords internal 6 | pxweb_as_json <- function(x) { 7 | UseMethod("pxweb_as_json") 8 | } 9 | 10 | #' @rdname pxweb_as_json 11 | #' @keywords internal 12 | pxweb_as_json.pxweb_query <- function(x) { 13 | for (i in seq_along(x$query)) { 14 | x$query[[i]]$selection$values <- as.list(x$query[[i]]$selection$values) 15 | } 16 | jsonlite::toJSON(x, auto_unbox = TRUE) 17 | } 18 | -------------------------------------------------------------------------------- /man/assert_pxweb_query.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_query.R 3 | \name{assert_pxweb_query} 4 | \alias{assert_pxweb_query} 5 | \title{Assert a pxweb_query object} 6 | \usage{ 7 | assert_pxweb_query(x, check_response_format = TRUE) 8 | } 9 | \arguments{ 10 | \item{x}{an object to assert conferms to the structure of an pxweb_query object.} 11 | } 12 | \description{ 13 | Assert a pxweb_query object 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /man/pxe_position_is_metadata.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_interactive.R 3 | \name{pxe_position_is_metadata} 4 | \alias{pxe_position_is_metadata} 5 | \title{Is the current position a metadata object?} 6 | \usage{ 7 | pxe_position_is_metadata(x) 8 | } 9 | \arguments{ 10 | \item{x}{a \code{pxweb_explorer} object to check.} 11 | } 12 | \description{ 13 | Is the current position a metadata object? 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /man/pxweb_query_filter.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_query.R 3 | \name{pxweb_query_filter} 4 | \alias{pxweb_query_filter} 5 | \title{Get query values} 6 | \usage{ 7 | pxweb_query_filter(pxq) 8 | } 9 | \arguments{ 10 | \item{pxq}{a \code{pxweb_query} object.} 11 | } 12 | \value{ 13 | query variable selection filters as a named character vector. 14 | } 15 | \description{ 16 | Get query values 17 | } 18 | \keyword{internal} 19 | -------------------------------------------------------------------------------- /man/pxweb_metadata_time.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_metadata.R 3 | \name{pxweb_metadata_time} 4 | \alias{pxweb_metadata_time} 5 | \title{Get boolean vector} 6 | \usage{ 7 | pxweb_metadata_time(pxmd) 8 | } 9 | \arguments{ 10 | \item{pxmd}{a \code{pxweb_metadata} object.} 11 | } 12 | \value{ 13 | pxweb_metadata eliminations as a named boolean vector. 14 | } 15 | \description{ 16 | Get boolean vector 17 | } 18 | \keyword{internal} 19 | -------------------------------------------------------------------------------- /man/pxweb_query_values.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_query.R 3 | \name{pxweb_query_values} 4 | \alias{pxweb_query_values} 5 | \title{Get query filter} 6 | \usage{ 7 | pxweb_query_values(pxq) 8 | } 9 | \arguments{ 10 | \item{pxq}{a \code{pxweb_query} object.} 11 | } 12 | \value{ 13 | query variable selection values as a named list of character vectors. 14 | } 15 | \description{ 16 | Get query filter 17 | } 18 | \keyword{internal} 19 | -------------------------------------------------------------------------------- /man/pxe_print_download_code.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_interactive.R 3 | \name{pxe_print_download_code} 4 | \alias{pxe_print_download_code} 5 | \title{Print code to download query} 6 | \usage{ 7 | pxe_print_download_code(pxe, as) 8 | } 9 | \arguments{ 10 | \item{pxe}{a \code{pxweb_query} object.} 11 | 12 | \item{as}{\code{json} or \code{r}.} 13 | } 14 | \description{ 15 | Print code to download query 16 | } 17 | \keyword{internal} 18 | -------------------------------------------------------------------------------- /man/assert_pxweb_rda_file_path.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_assert.R 3 | \name{assert_pxweb_rda_file_path} 4 | \alias{assert_pxweb_rda_file_path} 5 | \title{Assert that the rda_file_path is correct} 6 | \usage{ 7 | assert_pxweb_rda_file_path(x) 8 | } 9 | \arguments{ 10 | \item{x}{a object to assert} 11 | } 12 | \description{ 13 | Assert that the \code{rda_file_path} slot in the \code{pxweb} object is correct. 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /man/pxe_position_multiple_choice_allowed.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_interactive.R 3 | \name{pxe_position_multiple_choice_allowed} 4 | \alias{pxe_position_multiple_choice_allowed} 5 | \title{Are multiple choices allowed?} 6 | \usage{ 7 | pxe_position_multiple_choice_allowed(x) 8 | } 9 | \arguments{ 10 | \item{x}{a \code{pxweb_explorer} object to check.} 11 | } 12 | \description{ 13 | Are multiple choices allowed? 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /man/assert_pxweb_api_catalogue.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_api_catalogue.R 3 | \name{assert_pxweb_api_catalogue} 4 | \alias{assert_pxweb_api_catalogue} 5 | \title{Assert a \code{pxweb_api_catalogue} object} 6 | \usage{ 7 | assert_pxweb_api_catalogue(x) 8 | } 9 | \arguments{ 10 | \item{x}{an object to assert is a \code{pxweb_api_catalogue_entry}.} 11 | } 12 | \description{ 13 | Assert a \code{pxweb_api_catalogue} object 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /man/assert_pxweb_data_comments.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_data_comments.R 3 | \name{assert_pxweb_data_comments} 4 | \alias{assert_pxweb_data_comments} 5 | \title{Assert that x is a correct \code{pxweb_data_comments} object.} 6 | \usage{ 7 | assert_pxweb_data_comments(x) 8 | } 9 | \arguments{ 10 | \item{x}{an object to check.} 11 | } 12 | \description{ 13 | Assert that x is a correct \code{pxweb_data_comments} object. 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /man/assert_pxweb_database_list.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_database_list.R 3 | \name{assert_pxweb_database_list} 4 | \alias{assert_pxweb_database_list} 5 | \title{Assert that x is a correct \code{pxweb_database_list} object.} 6 | \usage{ 7 | assert_pxweb_database_list(x) 8 | } 9 | \arguments{ 10 | \item{x}{an object to check.} 11 | } 12 | \description{ 13 | Assert that x is a correct \code{pxweb_database_list} object. 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /man/pxweb_cite.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_cite.R 3 | \name{pxweb_cite} 4 | \alias{pxweb_cite} 5 | \title{Cite a PXWEB data object} 6 | \usage{ 7 | pxweb_cite(x, style = "citation") 8 | } 9 | \arguments{ 10 | \item{x}{a \code{pxweb_data} object to cite.} 11 | 12 | \item{style}{see \code{\link[utils]{bibentry}}.} 13 | } 14 | \description{ 15 | Cite a PXWEB data object 16 | } 17 | \details{ 18 | Functionality to automatic cite PXWEB data objects. 19 | } 20 | -------------------------------------------------------------------------------- /man/pxe_position_is_api_catalogue.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_interactive.R 3 | \name{pxe_position_is_api_catalogue} 4 | \alias{pxe_position_is_api_catalogue} 5 | \title{Is the current position an api_catalogue position?} 6 | \usage{ 7 | pxe_position_is_api_catalogue(x) 8 | } 9 | \arguments{ 10 | \item{x}{a \code{pxweb_explorer} object to check.} 11 | } 12 | \description{ 13 | Is the current position an api_catalogue position? 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /man/pxweb_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_data.R 3 | \name{pxweb_data} 4 | \alias{pxweb_data} 5 | \title{Construct a \code{pxweb_data} object.} 6 | \usage{ 7 | pxweb_data(x) 8 | } 9 | \arguments{ 10 | \item{x}{a list returned from a PXWEB API to convert to a \code{pxweb_data} object.} 11 | } 12 | \value{ 13 | a \code{pxweb_data} object 14 | } 15 | \description{ 16 | An object that contain the data for a given PXWEB table. 17 | } 18 | \keyword{internal} 19 | -------------------------------------------------------------------------------- /man/pxweb_metadata_elimination.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_metadata.R 3 | \name{pxweb_metadata_elimination} 4 | \alias{pxweb_metadata_elimination} 5 | \title{Get boolean vector} 6 | \usage{ 7 | pxweb_metadata_elimination(pxmd) 8 | } 9 | \arguments{ 10 | \item{pxmd}{a \code{pxweb_metadata} object.} 11 | } 12 | \value{ 13 | pxweb_metadata eliminations as a named boolean vector. 14 | } 15 | \description{ 16 | Get boolean vector 17 | } 18 | \keyword{internal} 19 | -------------------------------------------------------------------------------- /man/pxweb_query_as_rcode.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_query.R 3 | \name{pxweb_query_as_rcode} 4 | \alias{pxweb_query_as_rcode} 5 | \title{Print a \code{pxweb_query} object as R code} 6 | \usage{ 7 | pxweb_query_as_rcode(pxq) 8 | } 9 | \arguments{ 10 | \item{pxq}{a \code{pxweb_query} object.} 11 | } 12 | \description{ 13 | Print a \code{pxweb_query} object as R code 14 | } 15 | \seealso{ 16 | \code{\link{pxweb_query_as_json}}, \code{\link{pxweb_query}} 17 | } 18 | -------------------------------------------------------------------------------- /man/str_pad.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_interactive.R 3 | \name{str_pad} 4 | \alias{str_pad} 5 | \title{Pad a string to a fixed size} 6 | \usage{ 7 | str_pad(txt, n = 5, pad = " ", type = "left") 8 | } 9 | \arguments{ 10 | \item{txt}{a character vector to pad} 11 | 12 | \item{n}{final char width} 13 | 14 | \item{pad}{pad symbol} 15 | 16 | \item{type}{pad from 'left' or 'right'.} 17 | } 18 | \description{ 19 | Pad a string to a fixed size 20 | } 21 | \keyword{internal} 22 | -------------------------------------------------------------------------------- /man/pxe_metadata_variable_names.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_interactive.R 3 | \name{pxe_metadata_variable_names} 4 | \alias{pxe_metadata_variable_names} 5 | \title{Get the meta data variable names from a \code{pxweb_explorer} object.} 6 | \usage{ 7 | pxe_metadata_variable_names(x) 8 | } 9 | \arguments{ 10 | \item{x}{a \code{pxweb_explorer} object} 11 | } 12 | \description{ 13 | Get the meta data variable names from a \code{pxweb_explorer} object. 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /man/pxweb_interactive_input.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_interactive.R 3 | \name{pxweb_interactive_input} 4 | \alias{pxweb_interactive_input} 5 | \title{Get input from user} 6 | \usage{ 7 | pxweb_interactive_input(pxe, test_input = NULL) 8 | } 9 | \arguments{ 10 | \item{pxe}{a \code{pxweb_explorer} object to get user input for.} 11 | 12 | \item{test_input}{supplying a test input (for testing only).} 13 | } 14 | \description{ 15 | Get input from user 16 | } 17 | \keyword{internal} 18 | -------------------------------------------------------------------------------- /man/pxweb_levels.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_levels.R 3 | \name{pxweb_levels} 4 | \alias{pxweb_levels} 5 | \title{Construct a \code{pxweb_levels} object.} 6 | \usage{ 7 | pxweb_levels(x) 8 | } 9 | \arguments{ 10 | \item{x}{a list returned from a PXWEB API to convert to a \code{pxweb_levels} object.} 11 | } 12 | \value{ 13 | a \code{pxweb_levels} object 14 | } 15 | \description{ 16 | An object that contain the levels for a given PXWEB api position. 17 | } 18 | \keyword{internal} 19 | -------------------------------------------------------------------------------- /man/pxweb_test_create_api_paths.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_test_api_endpoint.R 3 | \name{pxweb_test_create_api_paths} 4 | \alias{pxweb_test_create_api_paths} 5 | \title{Create all paths from a list of pxweb_api_catalogue entries} 6 | \usage{ 7 | pxweb_test_create_api_paths(apis) 8 | } 9 | \arguments{ 10 | \item{apis}{a list of pxweb_api_catalogue_entry elements} 11 | } 12 | \description{ 13 | Create all paths from a list of pxweb_api_catalogue entries 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /man/pxe_pxobj_at_position.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_interactive.R 3 | \name{pxe_pxobj_at_position} 4 | \alias{pxe_pxobj_at_position} 5 | \alias{pxe_pxobj_at_position<-} 6 | \title{Return the pxweb object at the current position} 7 | \usage{ 8 | pxe_pxobj_at_position(x) 9 | 10 | pxe_pxobj_at_position(x) <- value 11 | } 12 | \arguments{ 13 | \item{x}{a \code{pxweb_explorer} object.} 14 | } 15 | \description{ 16 | Return the pxweb object at the current position 17 | } 18 | \keyword{internal} 19 | -------------------------------------------------------------------------------- /man/pxweb_add_api_subpath.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_add_api_subpath.R 3 | \name{pxweb_add_api_subpath} 4 | \alias{pxweb_add_api_subpath} 5 | \title{Add the subpath slot to a pxweb path slot} 6 | \usage{ 7 | pxweb_add_api_subpath(obj) 8 | } 9 | \arguments{ 10 | \item{obj}{an object to add subpath to} 11 | } 12 | \description{ 13 | Add the subpath slot to a pxweb path slot 14 | } 15 | \details{ 16 | Queries the path from pos 1 and up until a config is returned. 17 | } 18 | \keyword{internal} 19 | -------------------------------------------------------------------------------- /man/pxweb_metadata.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_metadata.R 3 | \name{pxweb_metadata} 4 | \alias{pxweb_metadata} 5 | \title{Construct a \code{pxweb_metadata} object.} 6 | \usage{ 7 | pxweb_metadata(x) 8 | } 9 | \arguments{ 10 | \item{x}{a list returned from a PXWEB API to convert to a \code{pxweb_metadata} object.} 11 | } 12 | \value{ 13 | a \code{pxweb_metadata} object 14 | } 15 | \description{ 16 | An object that contain the metadata for a given PXWEB table. 17 | } 18 | \keyword{internal} 19 | -------------------------------------------------------------------------------- /man/print.pxweb_api_catalogue_entry.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_api_catalogue.R 3 | \name{print.pxweb_api_catalogue_entry} 4 | \alias{print.pxweb_api_catalogue_entry} 5 | \title{Print a catalogue entry} 6 | \usage{ 7 | \method{print}{pxweb_api_catalogue_entry}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{an object used to select a method.} 11 | 12 | \item{...}{further arguments passed to or from other methods.} 13 | } 14 | \description{ 15 | Print a catalogue entry 16 | } 17 | \keyword{internal} 18 | -------------------------------------------------------------------------------- /man/pxe_position_choice_size.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_interactive.R 3 | \name{pxe_position_choice_size} 4 | \alias{pxe_position_choice_size} 5 | \alias{pxe_position_print_size} 6 | \title{How many choices has the current position?} 7 | \usage{ 8 | pxe_position_choice_size(x) 9 | 10 | pxe_position_print_size(x) 11 | } 12 | \arguments{ 13 | \item{x}{a \code{pxweb_explorer} object to check.} 14 | } 15 | \description{ 16 | How many choices has the current position? 17 | } 18 | \keyword{internal} 19 | -------------------------------------------------------------------------------- /inst/examples/ex_get_data.R: -------------------------------------------------------------------------------- 1 | # Build url 2 | varname <- "BefProgFoddaMedel10" 3 | 4 | # Get metadata 5 | metadata <- get_pxweb_metadata(varname) 6 | 7 | # Get dimensions (names of dimensions are printed in the terminal) 8 | dims <- get_pxweb_dims(metadata) 9 | 10 | # Get data 11 | test <- get_pxweb(metadata$URL, dims=list( 12 | Fodelseland = "010", 13 | Alder="*", 14 | ContentsCode = "*", 15 | Tid="*" 16 | )) 17 | 18 | # Examine data 19 | View(test) 20 | 21 | # Plot the data 22 | ggplot(testClean,aes(x=ålder,y=Födda.2010,fill=födelseland)) + geom_histogram() 23 | -------------------------------------------------------------------------------- /man/assert_pxweb_input_allowed.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_interactive.R 3 | \name{assert_pxweb_input_allowed} 4 | \alias{assert_pxweb_input_allowed} 5 | \alias{print.pxweb_input_allowed} 6 | \title{Assert a \code{pxweb_input_allowed} object} 7 | \usage{ 8 | assert_pxweb_input_allowed(x) 9 | 10 | \method{print}{pxweb_input_allowed}(x, ...) 11 | } 12 | \arguments{ 13 | \item{x}{an object to assert.} 14 | } 15 | \description{ 16 | Assert a \code{pxweb_input_allowed} object 17 | } 18 | \keyword{internal} 19 | -------------------------------------------------------------------------------- /man/pxe_position_is_full_query.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_interactive.R 3 | \name{pxe_position_is_full_query} 4 | \alias{pxe_position_is_full_query} 5 | \title{Is the current position a full query (i.e. choices for all metadata variables)?} 6 | \usage{ 7 | pxe_position_is_full_query(x) 8 | } 9 | \arguments{ 10 | \item{x}{a \code{pxweb_explorer} object to check.} 11 | } 12 | \description{ 13 | Is the current position a full query (i.e. choices for all metadata variables)? 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /man/pxe_position_variable_can_be_eliminated.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_interactive.R 3 | \name{pxe_position_variable_can_be_eliminated} 4 | \alias{pxe_position_variable_can_be_eliminated} 5 | \title{Can the variable at the current position be eliminated?} 6 | \usage{ 7 | pxe_position_variable_can_be_eliminated(x) 8 | } 9 | \arguments{ 10 | \item{x}{a \code{pxweb_explorer} object to check.} 11 | } 12 | \description{ 13 | Can the variable at the current position be eliminated? 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /inst/extdata/examples/json_query_example.json: -------------------------------------------------------------------------------- 1 | { 2 | "query": [ 3 | { 4 | "code": "ContentsCode", 5 | "selection": { 6 | "filter": "item", 7 | "values": [ 8 | "BE0101N1", 9 | "BE0101N2" 10 | ] 11 | } 12 | }, 13 | { 14 | "code": "Tid", 15 | "selection": { 16 | "filter": "item", 17 | "values": [ 18 | "2010", 19 | "2011", 20 | "2012" 21 | ] 22 | } 23 | } 24 | ], 25 | "response": { 26 | "format": "json" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /inst/extras/old/StatfiTests.R: -------------------------------------------------------------------------------- 1 | library(pxweb) 2 | 3 | # List available database options 4 | api_parameters() 5 | 6 | # Standard query that asks for options 7 | url <- base_url("statfi", "v1", "fi") 8 | d <- interactive_pxweb(url) 9 | 10 | # Custom query: 11 | dims <- list() 12 | data.url <- "http://pxwebapi2.stat.fi/PXWeb/api/v1/fi/StatFin/asu/asas/010_asas_tau_101.px" 13 | dims[["Alue"]] <- c("*") 14 | dims[["Asuntokunnan koko"]] <- c("*") 15 | dims[["Talotyyppi"]] <- c("S") 16 | dims[["Vuosi"]] <- c("*") 17 | d <- get_pxweb_data(url = data.url, dims = dims, clean = TRUE) 18 | 19 | -------------------------------------------------------------------------------- /man/pxe_metadata_choices.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_interactive.R 3 | \name{pxe_metadata_choices} 4 | \alias{pxe_metadata_choices} 5 | \alias{pxe_metadata_choices<-} 6 | \title{Get and set pxe_metadata_coices} 7 | \usage{ 8 | pxe_metadata_choices(x) 9 | 10 | pxe_metadata_choices(x) <- value 11 | } 12 | \arguments{ 13 | \item{x}{a \code{pxweb_explorer} object} 14 | 15 | \item{value}{an object to set as pxe_metadata_choice} 16 | } 17 | \description{ 18 | Get and set pxe_metadata_coices 19 | } 20 | \keyword{internal} 21 | -------------------------------------------------------------------------------- /tests/testthat/test_data/filter_query.json: -------------------------------------------------------------------------------- 1 | { 2 | "query": [ 3 | { 4 | "code": "Region", 5 | "selection": { 6 | "filter": "all", 7 | "values": ["039*"] 8 | } 9 | }, 10 | { 11 | "code": "ContentsCode", 12 | "selection": { 13 | "filter": "all", 14 | "values": ["*"] 15 | } 16 | }, 17 | { 18 | "code": "Tid", 19 | "selection": { 20 | "filter": "top", 21 | "values": ["4"] 22 | } 23 | } 24 | ], 25 | "response": { 26 | "format": "json-stat" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /inst/extdata/examples/json-stat_query_example.json: -------------------------------------------------------------------------------- 1 | { 2 | "query": [ 3 | { 4 | "code": "ContentsCode", 5 | "selection": { 6 | "filter": "item", 7 | "values": [ 8 | "BE0101N1", 9 | "BE0101N2" 10 | ] 11 | } 12 | }, 13 | { 14 | "code": "Tid", 15 | "selection": { 16 | "filter": "item", 17 | "values": [ 18 | "2010", 19 | "2011", 20 | "2012" 21 | ] 22 | } 23 | } 24 | ], 25 | "response": { 26 | "format": "json-stat" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /man/pxweb_add_config.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_add_config.R 3 | \name{pxweb_add_config} 4 | \alias{pxweb_add_config} 5 | \title{Add the config slot to a pxweb object} 6 | \usage{ 7 | pxweb_add_config(obj) 8 | } 9 | \arguments{ 10 | \item{obj}{an object to add config to} 11 | } 12 | \description{ 13 | Add the config slot to a pxweb object 14 | } 15 | \details{ 16 | Checks if there exist a config object in the object. 17 | Otherwise it query the api to get it and add that call to the call stack. 18 | } 19 | \keyword{internal} 20 | -------------------------------------------------------------------------------- /man/pxweb_data_jsonstat.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_data_jsonstat.R 3 | \name{pxweb_data_jsonstat} 4 | \alias{pxweb_data_jsonstat} 5 | \title{Construct a \code{pxweb_data_jsonstat} object.} 6 | \usage{ 7 | pxweb_data_jsonstat(x) 8 | } 9 | \arguments{ 10 | \item{x}{a list returned from a PXWEB API to convert to a \code{pxweb_data_jsonstat} object.} 11 | } 12 | \value{ 13 | a \code{pxweb_data_jsonstat} object. 14 | } 15 | \description{ 16 | An object that contain the data for a given PXWEB table. 17 | } 18 | \keyword{internal} 19 | -------------------------------------------------------------------------------- /man/str_trim.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_interactive.R 3 | \name{str_trim} 4 | \alias{str_trim} 5 | \title{Taken from \code{trimws} for reasons of compatibility with previous R versios.} 6 | \usage{ 7 | str_trim(x, which = c("both", "left", "right")) 8 | } 9 | \arguments{ 10 | \item{x}{a string to trim.} 11 | 12 | \item{which}{how to trim the string.} 13 | } 14 | \description{ 15 | Taken from \code{trimws} for reasons of compatibility with previous R versios. 16 | } 17 | \seealso{ 18 | trimws 19 | } 20 | \keyword{internal} 21 | -------------------------------------------------------------------------------- /man/pxweb_clear_cache.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_clear_cache.R 3 | \name{pxweb_clear_cache} 4 | \alias{pxweb_clear_cache} 5 | \title{Clear cache of all (or one) \code{pxweb} object} 6 | \usage{ 7 | pxweb_clear_cache(x = NULL) 8 | } 9 | \arguments{ 10 | \item{x}{a \code{pxweb} object to clear cache for. Default is NULL (clear everything).} 11 | } 12 | \description{ 13 | Clear cache of all (or one) \code{pxweb} object 14 | } 15 | \details{ 16 | Clean the cache and sleep to restore api timing limit. 17 | } 18 | \keyword{internal} 19 | -------------------------------------------------------------------------------- /paper/RJwrapper.tex: -------------------------------------------------------------------------------- 1 | \documentclass[a4paper]{report} 2 | \usepackage[utf8]{inputenc} 3 | \usepackage[T1]{fontenc} 4 | \usepackage{RJournal} 5 | \usepackage{amsmath,amssymb,array} 6 | \usepackage{booktabs} 7 | 8 | %% load any required packages here 9 | 10 | \begin{document} 11 | 12 | %% do not edit, for illustration only 13 | \sectionhead{Contributed research article} 14 | \volume{XX} 15 | \volnumber{YY} 16 | \year{20ZZ} 17 | \month{AAAA} 18 | 19 | %% replace RJtemplate with your article 20 | \begin{article} 21 | \input{magnusson-kainu-lahti} 22 | \end{article} 23 | 24 | \end{document} 25 | -------------------------------------------------------------------------------- /inst/extdata/examples/json_query_last_names.json: -------------------------------------------------------------------------------- 1 | { 2 | "query": [ 3 | { 4 | "code": "Efternamn", 5 | "selection": { 6 | "filter": "all", 7 | "values": ["*"] 8 | } 9 | }, 10 | { 11 | "code": "ContentsCode", 12 | "selection": { 13 | "filter": "item", 14 | "values": ["BE0001AK"] 15 | } 16 | }, 17 | { 18 | "code": "Tid", 19 | "selection": { 20 | "filter": "item", 21 | "values": ["1999"] 22 | } 23 | } 24 | ], 25 | "response": { 26 | "format": "json" 27 | } 28 | } -------------------------------------------------------------------------------- /man/pxweb_database_list.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_database_list.R 3 | \name{pxweb_database_list} 4 | \alias{pxweb_database_list} 5 | \title{Construct a \code{pxweb_database_list} object.} 6 | \usage{ 7 | pxweb_database_list(x) 8 | } 9 | \arguments{ 10 | \item{x}{a list returned from a PXWEB API to convert to a \code{pxweb_database_list} object.} 11 | } 12 | \value{ 13 | a \code{pxweb_database_list} object 14 | } 15 | \description{ 16 | An object that contain the list of databases for a given PXWEB api. 17 | } 18 | \keyword{internal} 19 | -------------------------------------------------------------------------------- /man/assert_query_can_be_split_to_batches.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_split_query.R 3 | \name{assert_query_can_be_split_to_batches} 4 | \alias{assert_query_can_be_split_to_batches} 5 | \title{Assert that a given pxweb query can be split} 6 | \usage{ 7 | assert_query_can_be_split_to_batches(pxq, pxmd, mxv) 8 | } 9 | \arguments{ 10 | \item{pxq}{a [pxweb_query] object} 11 | 12 | \item{pxmd}{a [pxweb_metadata] object} 13 | 14 | \item{mxv}{maximum batch size} 15 | } 16 | \description{ 17 | Assert that a given pxweb query can be split 18 | } 19 | -------------------------------------------------------------------------------- /man/pxweb_test_time_limit.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_test_api_endpoint.R 3 | \name{pxweb_test_time_limit} 4 | \alias{pxweb_test_time_limit} 5 | \alias{is_test_time_limit_reached} 6 | \title{Test time limit object} 7 | \usage{ 8 | pxweb_test_time_limit(time_limit) 9 | 10 | is_test_time_limit_reached(x) 11 | } 12 | \arguments{ 13 | \item{time_limit}{the number of seconds the API will be tested.} 14 | } 15 | \description{ 16 | Test time limit object 17 | } 18 | \details{ 19 | Used to limit testing of API:s. 20 | } 21 | \keyword{internal} 22 | -------------------------------------------------------------------------------- /paper/main.R: -------------------------------------------------------------------------------- 1 | # To reproduce the manuscript PDF do the following: 2 | 3 | # Generate the examples, figures and tables 4 | #library(knitr) 5 | #knit("magnusson-kainu-lahti.Rmd") 6 | 7 | #library(rmarkdown) 8 | #render("magnusson-kainu-lahti.Rmd") 9 | 10 | # Convert tex to PDF 11 | tools::texi2pdf("RJwrapper.tex") 12 | tools::texi2pdf("RJwrapper.tex") 13 | 14 | # Show PDF 15 | system("evince RJwrapper.pdf &") 16 | 17 | 18 | # OLD: Generate tex file 19 | #Sweave("lahti-huovari-kainu-biecek.Rnw") 20 | #library(rmarkdown) 21 | #render("lahti-huovari-kainu-biecek.Rmd", output_format = "pdf_document") 22 | 23 | -------------------------------------------------------------------------------- /man/assert_pxweb_data_jsonstat.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_data_jsonstat.R 3 | \name{assert_pxweb_data_jsonstat} 4 | \alias{assert_pxweb_data_jsonstat} 5 | \title{Assert that x is a correct \code{pxweb_data_jsonstat} object. 6 | Assert a json-stat version 1.0 or later object} 7 | \usage{ 8 | assert_pxweb_data_jsonstat(x) 9 | } 10 | \arguments{ 11 | \item{x}{an object to check.} 12 | } 13 | \description{ 14 | Assert that x is a correct \code{pxweb_data_jsonstat} object. 15 | Assert a json-stat version 1.0 or later object 16 | } 17 | \keyword{internal} 18 | -------------------------------------------------------------------------------- /man/split_dimensions_left_right.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_split_query.R 3 | \name{split_dimensions_left_right} 4 | \alias{split_dimensions_left_right} 5 | \title{Split variables into chunks} 6 | \usage{ 7 | split_dimensions_left_right(x, bool, max_size) 8 | } 9 | \value{ 10 | a \code{pxweb_split_dimensions} 11 | } 12 | \description{ 13 | Split variables into chunks 14 | } 15 | \details{ 16 | Splitable variables are variables that can be split. Content variables cannot be split, 17 | not variables with filter == "top" 18 | } 19 | \keyword{internal} 20 | -------------------------------------------------------------------------------- /man/pxe_interactive_get_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_interactive.R 3 | \name{pxe_interactive_get_data} 4 | \alias{pxe_interactive_get_data} 5 | \title{Ask to download and download data} 6 | \usage{ 7 | pxe_interactive_get_data(pxe, test_input = NULL) 8 | } 9 | \arguments{ 10 | \item{pxe}{a \code{pxweb_explorer} object with full query} 11 | 12 | \item{test_input}{a test input for testing the function. 13 | Since two question, supply a vector of length two.} 14 | } 15 | \description{ 16 | Ask to download and download data 17 | } 18 | \keyword{internal} 19 | -------------------------------------------------------------------------------- /man/generate_permutations.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_split_query.R 3 | \name{generate_permutations} 4 | \alias{generate_permutations} 5 | \title{Generate batch permutations} 6 | \usage{ 7 | generate_permutations(x) 8 | } 9 | \arguments{ 10 | \item{x}{a vector with elements to permute} 11 | } 12 | \description{ 13 | Generate batch permutations 14 | } 15 | \details{ 16 | Generates permutations of dim. If more than 6 dim (highly unlikely) a sample of 1000 combinations 17 | is drawn. Otherwise all possible permutations are returned. 18 | } 19 | \keyword{internal} 20 | -------------------------------------------------------------------------------- /R/pxweb-package.R: -------------------------------------------------------------------------------- 1 | #' @title Interface to PX-WEB APIs from R 2 | #' 3 | #' @description 4 | #' PXWEB is a common web API used by many European Statistical agencies to disseminate official statistics. 5 | #' The pxweb package facilitates connections and usage of these APIs. 6 | #' 7 | #' @references 8 | #' The decription of the PXWEB API here: 9 | #' \url{https://www.scb.se/en/About-us/about-the-website-and-terms-of-use/open-data-api/} 10 | #' The official home page of PXWEB can be found here: 11 | #' \url{https://www.scb.se/en/services/statistical-programs-for-px-files/px-web/} 12 | #' 13 | #' @name pxweb-package 14 | "_PACKAGE" 15 | -------------------------------------------------------------------------------- /inst/extdata/examples/json_query_variables_example.json: -------------------------------------------------------------------------------- 1 | { 2 | "query": [ 3 | { 4 | "code": "Civilstand", 5 | "selection": { 6 | "filter": "item", 7 | "values": ["OG", "G", "SK", "ÄNKL"] 8 | } 9 | }, 10 | { 11 | "code": "ContentsCode", 12 | "selection": { 13 | "filter": "item", 14 | "values": ["BE0101N1"] 15 | } 16 | }, 17 | { 18 | "code": "Tid", 19 | "selection": { 20 | "filter": "item", 21 | "values": ["2015", "2016", "2017"] 22 | } 23 | } 24 | ], 25 | "response": { 26 | "format": "json" 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /man/pxweb_add_call.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_add_call.R 3 | \name{pxweb_add_call} 4 | \alias{pxweb_add_call} 5 | \title{Add an api call to a pxweb_api_s3 object} 6 | \usage{ 7 | pxweb_add_call(obj, time_stamp = Sys.time()) 8 | } 9 | \arguments{ 10 | \item{obj}{a \code{pxweb_api_s3} object} 11 | } 12 | \description{ 13 | The pxweb_add_call function add a call the the api in the call stack, then compute 14 | 15 | Promise: 16 | The stored rda api object will always have the latest calls 17 | This is not thread safe so only one session at a time should call the api. 18 | } 19 | \keyword{internal} 20 | -------------------------------------------------------------------------------- /man/pxweb_add_mandatory_variables.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_get.R 3 | \name{pxweb_add_mandatory_variables} 4 | \alias{pxweb_add_mandatory_variables} 5 | \title{Add mandatory variables to query} 6 | \usage{ 7 | pxweb_add_mandatory_variables(pxq, pxmd) 8 | } 9 | \arguments{ 10 | \item{pxq}{a \code{pxweb_query} object.} 11 | 12 | \item{pxmd}{a \code{pxweb_metadata} object.} 13 | } 14 | \description{ 15 | Add mandatory variables to query 16 | } 17 | \details{ 18 | Complement queries that lack explicit requests for variables with requests for every value of these variables. 19 | } 20 | \keyword{internal} 21 | -------------------------------------------------------------------------------- /man/pxweb_parse_response.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_parse_response.R 3 | \name{pxweb_parse_response} 4 | \alias{pxweb_parse_response} 5 | \alias{is_pxweb_response} 6 | \title{Parse the response from a PXWEB API (advanced)} 7 | \usage{ 8 | pxweb_parse_response(x) 9 | 10 | is_pxweb_response(x) 11 | } 12 | \arguments{ 13 | \item{x}{a \code{httr} response object from a PXWEB call.} 14 | } 15 | \description{ 16 | The function parses the response from a call made to a PXWEB API 17 | using the \code{httr} R package. In this way it is possible to parse the 18 | content of calls made outside the pxweb R package. 19 | } 20 | -------------------------------------------------------------------------------- /man/save_pxweb.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_load_save.R 3 | \name{save_pxweb} 4 | \alias{save_pxweb} 5 | \alias{load_pxweb} 6 | \alias{load_pxweb_calls} 7 | \alias{load_pxweb_config} 8 | \alias{load_pxweb_api_subpath} 9 | \title{Save and load \code{pxweb} objects from R temp folder} 10 | \usage{ 11 | save_pxweb(obj) 12 | 13 | load_pxweb(obj) 14 | 15 | load_pxweb_calls(obj) 16 | 17 | load_pxweb_config(obj) 18 | 19 | load_pxweb_api_subpath(obj) 20 | } 21 | \arguments{ 22 | \item{obj}{a \code{pxweb} object} 23 | } 24 | \description{ 25 | Save and load \code{pxweb} objects from R temp folder 26 | } 27 | \keyword{internal} 28 | -------------------------------------------------------------------------------- /inst/extdata/test_files/json_queries/json_single_query_test.json: -------------------------------------------------------------------------------- 1 | { 2 | "query": [ 3 | { 4 | "code": "Kon", 5 | "selection": { 6 | "filter": "item", 7 | "values": [ 8 | "1" 9 | ] 10 | } 11 | }, 12 | { 13 | "code": "ContentsCode", 14 | "selection": { 15 | "filter": "item", 16 | "values": [ 17 | "BE0101N1" 18 | ] 19 | } 20 | }, 21 | { 22 | "code": "Tid", 23 | "selection": { 24 | "filter": "item", 25 | "values": [ 26 | "2017" 27 | ] 28 | } 29 | } 30 | ], 31 | "response": { 32 | "format": "json" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /man/pxd_values_to_valuetexts.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_data.R 3 | \name{pxd_values_to_valuetexts} 4 | \alias{pxd_values_to_valuetexts} 5 | \title{Convert a pxweb data objects values to valuetext} 6 | \usage{ 7 | pxd_values_to_valuetexts(x, variable_code, variable_vector) 8 | } 9 | \arguments{ 10 | \item{x}{a \code{pxweb_data} object} 11 | 12 | \item{variable_code}{the variable name of the variable to convert. NOTE! Need to be the variable code.} 13 | 14 | \item{variable_vector}{the vector with the variables to convert.} 15 | } 16 | \description{ 17 | Convert a pxweb data objects values to valuetext 18 | } 19 | \keyword{internal} 20 | -------------------------------------------------------------------------------- /man/build_pxweb_url.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_build_pxweb_urls.R 3 | \name{build_pxweb_url} 4 | \alias{build_pxweb_url} 5 | \alias{build_pxweb_url.list} 6 | \alias{build_pxweb_url.character} 7 | \alias{build_pxweb_url.pxweb} 8 | \alias{build_pxweb_url.pxweb_api_catalogue_entry} 9 | \title{Build the url to a PXWEB api} 10 | \usage{ 11 | build_pxweb_url(x) 12 | 13 | \method{build_pxweb_url}{list}(x) 14 | 15 | \method{build_pxweb_url}{character}(x) 16 | 17 | \method{build_pxweb_url}{pxweb}(x) 18 | 19 | \method{build_pxweb_url}{pxweb_api_catalogue_entry}(x) 20 | } 21 | \description{ 22 | Build the url to a PXWEB api 23 | } 24 | \keyword{internal} 25 | -------------------------------------------------------------------------------- /man/pxweb_api_catalogue_entry.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_api_catalogue.R 3 | \name{pxweb_api_catalogue_entry} 4 | \alias{pxweb_api_catalogue_entry} 5 | \alias{pxweb_api_catalogue_entry.list} 6 | \alias{assert_pxweb_api_catalogue_entry} 7 | \title{Constructor for \code{pxweb_api_catalogue_entry}.} 8 | \usage{ 9 | pxweb_api_catalogue_entry(x) 10 | 11 | \method{pxweb_api_catalogue_entry}{list}(x) 12 | 13 | assert_pxweb_api_catalogue_entry(x) 14 | } 15 | \arguments{ 16 | \item{x}{an object to assert is a \code{pxweb_api_catalogue_entry}.} 17 | } 18 | \description{ 19 | Constructor for \code{pxweb_api_catalogue_entry}. 20 | } 21 | \keyword{internal} 22 | -------------------------------------------------------------------------------- /R/pxweb_parse_url_or_fail.R: -------------------------------------------------------------------------------- 1 | #' Parse a character string or throws error if it fails 2 | #' 3 | #' @param x a character element to parse 4 | #' 5 | #' @keywords internal 6 | parse_url_or_fail <- function(x) { 7 | pu <- parse_url(x) 8 | if (!parsed_url_has_hostname(x)) { 9 | stop("Cannot parse url (hostname). Please check url for potential errors (?parse_url): '", x, "'", call. = FALSE) 10 | } 11 | pu 12 | } 13 | 14 | parse_url <- function(x) { 15 | checkmate::assert_string(x) 16 | x <- pxweb_fix_url(x) 17 | httr::parse_url(x) 18 | } 19 | 20 | parsed_url_has_hostname <- function(x){ 21 | if(!checkmate::test_class(x, "url")){ 22 | x <- parse_url(x) 23 | } 24 | !is.null(x$hostname) 25 | } 26 | -------------------------------------------------------------------------------- /man/pxe_back_position.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_interactive.R 3 | \name{pxe_back_position} 4 | \alias{pxe_back_position} 5 | \alias{pxe_add_position} 6 | \title{Move in the \code{pxweb_explorer} position} 7 | \usage{ 8 | pxe_back_position(pxe) 9 | 10 | pxe_add_position(pxe, new_pos) 11 | } 12 | \arguments{ 13 | \item{pxe}{a \code{pxweb_explorer} object.} 14 | 15 | \item{new_pos}{add a new position.} 16 | } 17 | \description{ 18 | Move in the \code{pxweb_explorer} position 19 | } 20 | \details{ 21 | \code{pxe_back_position} moves back one position and 22 | \code{pxe_add_position} moves forward, based on user choice. 23 | } 24 | \keyword{internal} 25 | -------------------------------------------------------------------------------- /man/pxweb_add_metadata_to_query.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_query.R 3 | \name{pxweb_add_metadata_to_query} 4 | \alias{pxweb_add_metadata_to_query} 5 | \alias{pxweb_remove_metadata_from_query} 6 | \title{Add and remove metadata to query} 7 | \usage{ 8 | pxweb_add_metadata_to_query(pxq, pxmd) 9 | 10 | pxweb_remove_metadata_from_query(pxq, pxmd) 11 | } 12 | \arguments{ 13 | \item{pxq}{a \code{pxweb_query} object.} 14 | 15 | \item{pxmd}{a \code{pxweb_metadata} object.} 16 | } 17 | \description{ 18 | Add and remove metadata to query 19 | } 20 | \details{ 21 | Add metadata values to variables with a query with filter "all". 22 | } 23 | \keyword{internal} 24 | -------------------------------------------------------------------------------- /man/pxweb_api_catalogue.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_api_catalogue.R 3 | \name{pxweb_api_catalogue} 4 | \alias{pxweb_api_catalogue} 5 | \alias{pxweb_api_catalogue_from_json} 6 | \alias{pxweb_api_catalogue_from_github} 7 | \alias{pxweb_api_catalogue_path} 8 | \title{Get the PXWEB API catalogue} 9 | \usage{ 10 | pxweb_api_catalogue() 11 | 12 | pxweb_api_catalogue_from_json(json) 13 | 14 | pxweb_api_catalogue_from_github(branch = "master") 15 | 16 | pxweb_api_catalogue_path() 17 | } 18 | \description{ 19 | Get the PXWEB API catalogue 20 | } 21 | \details{ 22 | A list with implemented API:s. 23 | } 24 | \examples{ 25 | pxweb_api_catalogue() 26 | 27 | } 28 | \keyword{internal} 29 | -------------------------------------------------------------------------------- /pkgdown/_pkgdown.yml: -------------------------------------------------------------------------------- 1 | reference: 2 | - title: All functions 3 | desc: | 4 | Listing of functions in the pxweb package 5 | contents: 6 | - pxweb-package 7 | - pxweb_advanced_get 8 | - pxweb_cite 9 | - pxweb_get 10 | - pxweb_get_data 11 | - pxweb_parse_response 12 | - pxweb_query_as_json 13 | - pxweb_test_api 14 | - pxweb_validate_query_with_metadata 15 | - api_catalogue 16 | - assert_query_can_be_split_to_batches 17 | - pxweb_query_as_rcode 18 | - title: Interactive functions 19 | desc: | 20 | Listing of interactive functions 21 | contents: pxweb_interactive 22 | url: https://ropengov.github.io/pxweb/ 23 | template: 24 | package: rogtemplate 25 | opengraph: 26 | twitter: 27 | site: '@rOpenGov' 28 | -------------------------------------------------------------------------------- /man/build_pxweb_config_url.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_build_pxweb_urls.R 3 | \name{build_pxweb_url.url} 4 | \alias{build_pxweb_url.url} 5 | \alias{build_pxweb_config_url} 6 | \alias{build_pxweb_config_url.list} 7 | \alias{build_pxweb_config_url.pxweb} 8 | \alias{build_pxweb_config_url.url} 9 | \title{Build the url to get the config from a PXWEB api} 10 | \usage{ 11 | \method{build_pxweb_url}{url}(x) 12 | 13 | build_pxweb_config_url(x) 14 | 15 | \method{build_pxweb_config_url}{list}(x) 16 | 17 | \method{build_pxweb_config_url}{pxweb}(x) 18 | 19 | \method{build_pxweb_config_url}{url}(x) 20 | } 21 | \description{ 22 | Build the url to get the config from a PXWEB api 23 | } 24 | \keyword{internal} 25 | -------------------------------------------------------------------------------- /man/pxweb_metadata_add_null_values.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_get.R 3 | \name{pxweb_metadata_add_null_values} 4 | \alias{pxweb_metadata_add_null_values} 5 | \title{Add values to NULL value variables in PXWEB metadata objects} 6 | \usage{ 7 | pxweb_metadata_add_null_values(x, px) 8 | } 9 | \arguments{ 10 | \item{x}{an object to check if is a \code{pxweb_metadata} object to which we should add values.} 11 | 12 | \item{px}{a \code{pxweb} object} 13 | } 14 | \description{ 15 | Add values to NULL value variables in PXWEB metadata objects 16 | } 17 | \details{ 18 | Some metadata objects may have NULL values. In these cases the values are downloaded and added 19 | to the metadata object. 20 | } 21 | \keyword{internal} 22 | -------------------------------------------------------------------------------- /man/http_was_redirected.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_add_config.R 3 | \name{http_was_redirected} 4 | \alias{http_was_redirected} 5 | \title{http_was_redirected} 6 | \usage{ 7 | http_was_redirected(r) 8 | } 9 | \arguments{ 10 | \item{r}{an httr response object, e.g. from a call to httr::GET()} 11 | } 12 | \value{ 13 | list with slots \code{was_redirected}, \code{redirected_from} and \code{redirected_to} 14 | } 15 | \description{ 16 | http_was_redirected 17 | } 18 | \examples{ 19 | \dontrun{ 20 | r <- httr::GET("http://httpbin.org/redirect/2") 21 | pxweb:::http_was_redirected(r) 22 | } 23 | } 24 | \references{ 25 | Function in large parts taken from \url{https://petermeissner.de/blog/2018/11/07/using-httr-to-detect-redirects/}. 26 | } 27 | \keyword{internal} 28 | -------------------------------------------------------------------------------- /man/pxe_handle_input.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_interactive.R 3 | \name{pxe_handle_input} 4 | \alias{pxe_handle_input} 5 | \alias{pxe_handle_input.numeric} 6 | \alias{pxe_handle_input.character} 7 | \title{Handle a user input for a \code{pxweb_explorer} object.} 8 | \usage{ 9 | pxe_handle_input(user_input, pxe) 10 | 11 | \method{pxe_handle_input}{numeric}(user_input, pxe) 12 | 13 | \method{pxe_handle_input}{character}(user_input, pxe) 14 | } 15 | \arguments{ 16 | \item{user_input}{an (allowed) user input to handle.} 17 | 18 | \item{pxe}{a \code{pxweb_explorer} object to get user input for.} 19 | } 20 | \description{ 21 | Handle a user input for a \code{pxweb_explorer} object. 22 | } 23 | \seealso{ 24 | pxe_allowed_input() 25 | } 26 | \keyword{internal} 27 | -------------------------------------------------------------------------------- /man/pxe_input.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_interactive.R 3 | \name{pxe_input} 4 | \alias{pxe_input} 5 | \alias{pxe_parse_input} 6 | \title{Get (allowed) inputs for a \code{pxweb_input_allowed} object.} 7 | \usage{ 8 | pxe_input(allowed_input, title = NULL, test_input = NULL) 9 | 10 | pxe_parse_input(user_input, allowed_input) 11 | } 12 | \arguments{ 13 | \item{allowed_input}{a \code{pxweb_input_allowed}.} 14 | 15 | \item{title}{Print (using cat()) before ask for the allowed choices.} 16 | 17 | \item{test_input}{supplying a test input (for testing only)} 18 | } 19 | \description{ 20 | Get (allowed) inputs for a \code{pxweb_input_allowed} object. 21 | } 22 | \details{ 23 | It handles input and checks if the input is allowed. 24 | } 25 | \keyword{internal} 26 | -------------------------------------------------------------------------------- /inst/extdata/examples/sq-api_table_statfin_eot_pxt_132a.px.json: -------------------------------------------------------------------------------- 1 | {"queryObj":{ 2 | "query": [ 3 | { 4 | "code": "Kotitalouden elinvaihe", 5 | "selection": { 6 | "filter": "item", 7 | "values": [ 8 | "SS" 9 | ] 10 | } 11 | }, 12 | { 13 | "code": "Vuosi", 14 | "selection": { 15 | "filter": "item", 16 | "values": [ 17 | "2022", 18 | "2023", 19 | "2024" 20 | ] 21 | } 22 | }, 23 | { 24 | "code": "Tiedot", 25 | "selection": { 26 | "filter": "item", 27 | "values": [ 28 | "kotital" 29 | ] 30 | } 31 | } 32 | ], 33 | "response": { 34 | "format": "json-stat2" 35 | } 36 | },"tableIdForQuery":"statfin_eot_pxt_132a.px"} -------------------------------------------------------------------------------- /man/pxweb_query_dim_splittable.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_split_query.R 3 | \name{pxweb_query_dim_splittable} 4 | \alias{pxweb_query_dim_splittable} 5 | \title{Get vector indicating splittable variables} 6 | \usage{ 7 | pxweb_query_dim_splittable(pxq, pxmd) 8 | } 9 | \arguments{ 10 | \item{pxq}{a \code{pxweb_query} object.} 11 | } 12 | \value{ 13 | a named logical vector. 14 | } 15 | \description{ 16 | Get vector indicating splittable variables 17 | } 18 | \details{ 19 | Splitable variables are variables that can be split. Content variables cannot be split, 20 | nor variables with filter == "top". 21 | 22 | Currently, we can only be sure that time variables and eliminated variables can be split. 23 | Hopefully the next API makes this more clear. 24 | } 25 | \keyword{internal} 26 | -------------------------------------------------------------------------------- /man/pxe_allowed_input.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_interactive.R 3 | \name{pxe_allowed_input} 4 | \alias{pxe_allowed_input} 5 | \alias{pxe_allowed_input_df} 6 | \alias{pxe_allowed_input.pxweb_explorer} 7 | \alias{pxe_allowed_input.character} 8 | \title{Defines allowed input for a position in a \code{pxweb_explorer} or character object.} 9 | \usage{ 10 | pxe_allowed_input(x) 11 | 12 | pxe_allowed_input_df() 13 | 14 | \method{pxe_allowed_input}{pxweb_explorer}(x) 15 | 16 | \method{pxe_allowed_input}{character}(x) 17 | 18 | \method{pxe_allowed_input}{pxweb_explorer}(x) 19 | } 20 | \arguments{ 21 | \item{x}{a object to get allowed input for.} 22 | } 23 | \description{ 24 | Defines allowed input for a position in a \code{pxweb_explorer} or character object. 25 | } 26 | \keyword{internal} 27 | -------------------------------------------------------------------------------- /man/pxweb_query_as_json.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_query.R 3 | \name{pxweb_query_as_json} 4 | \alias{pxweb_query_as_json} 5 | \title{Convert a \code{pxweb_query} object to a \code{json} string} 6 | \usage{ 7 | pxweb_query_as_json(pxq, ...) 8 | } 9 | \arguments{ 10 | \item{pxq}{a \code{pxweb_query} object.} 11 | 12 | \item{...}{further argument to \code{jsonlite::toJSON()}.} 13 | } 14 | \description{ 15 | Convert a \code{pxweb_query} object to a \code{json} string 16 | } 17 | \examples{ 18 | json_query <- file.path( 19 | system.file(package = "pxweb"), 20 | "extdata", "examples", "json_query_example.json" 21 | ) 22 | pxq <- pxweb_query(json_query) 23 | json <- pxweb_query_as_json(pxq, pretty = TRUE) 24 | 25 | } 26 | \seealso{ 27 | \code{\link{pxweb_query}}, \code{\link{pxweb_query_as_rcode}} 28 | } 29 | -------------------------------------------------------------------------------- /man/permutations.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_split_query.R 3 | \name{permutations} 4 | \alias{permutations} 5 | \title{Generate permutations of dimensions to find optimal no of batches} 6 | \usage{ 7 | permutations(n, r, v = 1:n, set = TRUE, repeats.allowed = FALSE) 8 | } 9 | \arguments{ 10 | \item{n}{See \code{gtools::permutations}.} 11 | 12 | \item{r}{See \code{gtools::permutations}.} 13 | 14 | \item{v}{See \code{gtools::permutations}.} 15 | 16 | \item{set}{See \code{gtools::permutations}.} 17 | 18 | \item{repeats.allowed}{See \code{gtools::permutations}.} 19 | } 20 | \description{ 21 | Generate permutations of dimensions to find optimal no of batches 22 | } 23 | \details{ 24 | Taken from gtools to minimize dependencies. See permutations 25 | of the gtools packages for details 26 | } 27 | \keyword{internal} 28 | -------------------------------------------------------------------------------- /man/pxweb_data_column_comment.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_data_comments.R 3 | \name{pxweb_data_column_comment} 4 | \alias{pxweb_data_column_comment} 5 | \alias{pxweb_data_value_comment} 6 | \alias{pxweb_data_obs_comment} 7 | \title{Construct a \code{pxweb_data_comment} object} 8 | \usage{ 9 | pxweb_data_column_comment(x, column_idx) 10 | 11 | pxweb_data_value_comment(x, comment_idx) 12 | 13 | pxweb_data_obs_comment(x, obs_idx) 14 | } 15 | \arguments{ 16 | \item{x}{an \code{pxweb_data} to extract a \code{pxweb_data_comment} object from.} 17 | 18 | \item{column_idx}{the index of the column to extract.} 19 | 20 | \item{comment_idx}{the index of the comment to extract.} 21 | 22 | \item{obs_idx}{the index of the comment to extract.} 23 | } 24 | \description{ 25 | Construct a \code{pxweb_data_comment} object 26 | } 27 | \keyword{internal} 28 | -------------------------------------------------------------------------------- /tests/testthat/test_data/test_query_px.json: -------------------------------------------------------------------------------- 1 | { 2 | "query": [ 3 | { 4 | "code": "Region", 5 | "selection": { 6 | "filter": "item", 7 | "values": ["00"] 8 | } 9 | }, 10 | { 11 | "code": "Alder", 12 | "selection": { 13 | "filter": "item", 14 | "values": ["tot"] 15 | } 16 | }, 17 | { 18 | "code": "Kon", 19 | "selection": { 20 | "filter": "item", 21 | "values": ["1", "2"] 22 | } 23 | }, 24 | { 25 | "code": "ContentsCode", 26 | "selection": { 27 | "filter": "item", 28 | "values": ["BE0101N1", "BE0101N2"] 29 | } 30 | }, 31 | { 32 | "code": "Tid", 33 | "selection": { 34 | "filter": "item", 35 | "values": ["2019", "2020", "2021"] 36 | } 37 | } 38 | ], 39 | "response": { 40 | "format": "px" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tests/testthat/test_data/test_query_sdmx.json: -------------------------------------------------------------------------------- 1 | { 2 | "query": [ 3 | { 4 | "code": "Region", 5 | "selection": { 6 | "filter": "item", 7 | "values": ["00"] 8 | } 9 | }, 10 | { 11 | "code": "Alder", 12 | "selection": { 13 | "filter": "item", 14 | "values": ["tot"] 15 | } 16 | }, 17 | { 18 | "code": "Kon", 19 | "selection": { 20 | "filter": "item", 21 | "values": ["1", "2"] 22 | } 23 | }, 24 | { 25 | "code": "ContentsCode", 26 | "selection": { 27 | "filter": "item", 28 | "values": ["BE0101N1", "BE0101N2"] 29 | } 30 | }, 31 | { 32 | "code": "Tid", 33 | "selection": { 34 | "filter": "item", 35 | "values": ["2019", "2020", "2021"] 36 | } 37 | } 38 | ], 39 | "response": { 40 | "format": "sdmx" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /inst/CITATION: -------------------------------------------------------------------------------- 1 | year <- sub("-.*", "", meta$Date) 2 | version_note <- paste("R package version", meta$Version) 3 | pkg <- meta$Package 4 | title <- gsub("'", "", meta$Title) 5 | doi <- paste0("10.32614/CRAN.package.", pkg) 6 | 7 | citHeader("Kindly cite the pxweb R package as follows:") 8 | 9 | bibentry(bibtype="Manual", 10 | header = sprintf("Kindly cite the '%s' R package as follows:", pkg), 11 | title = sprintf("{%s: %s}", pkg, title), 12 | doi = "10.32614/CRAN.package.pxweb", 13 | author = c( 14 | person(given = "Mans", family= "Magnusson", email = "mons.magnusson@gmail.com"), 15 | person(given = "Markus", family= "Kainu"), 16 | person(given = "Janne", family= "Huovari"), 17 | person(given = "Leo", family= "Lahti") 18 | ), 19 | year = year, 20 | version = meta$Version, 21 | note = version_note, 22 | url = "https://github.com/rOpenGov/pxweb", 23 | key = paste0("R-", pkg) 24 | ) 25 | 26 | 27 | -------------------------------------------------------------------------------- /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^docs$ 2 | ^_pkgdown\.yml$ 3 | ^DESIGN_PRINCIPLES\.md$ 4 | # Extra material related but not to be included in the package 5 | ./inst/extras/eurostat.Rcheck/* 6 | ./inst/extras/..Rcheck/* 7 | ./inst/extras/...Rcheck/* 8 | ./inst/extras/* 9 | ./inst/extras/.* 10 | ./inst/extras/*.Rmd 11 | ./inst/extras/.RData 12 | ./inst/extras/*.RData 13 | inst/extras/*.RData 14 | inst/extras/.RData 15 | sandbox/*.R 16 | sandbox 17 | tests_bash/*.R 18 | tests_bash/*.sh 19 | tests_bash 20 | todo.txt 21 | 22 | README.md 23 | README.Rmd 24 | # Git related 25 | ./.git* 26 | # Travis yml 27 | .travis.yml 28 | # Appveyor yml 29 | appveyor.yml 30 | # Extra Vignette materials 31 | vignettes/pxweb.md 32 | # Misc 33 | ./.*~ 34 | ./*~ 35 | ^.*\.Rproj$ 36 | ^\.Rproj\.user$ 37 | paper 38 | CODE_OF_CONDUCT.md 39 | CONTRIBUTING.md 40 | TROUBLESHOOTING.md 41 | ^\.github$ 42 | ^doc$ 43 | ^Meta$ 44 | ^pkgdown$ 45 | ^\._pkgdown\.yml$ 46 | TODO.tdl 47 | 48 | -------------------------------------------------------------------------------- /R/pxweb_load_save.R: -------------------------------------------------------------------------------- 1 | #' Save and load \code{pxweb} objects from R temp folder 2 | #' 3 | #' @param obj a \code{pxweb} object 4 | #' @keywords internal 5 | save_pxweb <- function(obj) { 6 | checkmate::assert_class(obj, "pxweb") 7 | save(obj, file = obj$paths$rda_file_path, compress = FALSE) 8 | } 9 | 10 | #' @keywords internal 11 | #' @rdname save_pxweb 12 | load_pxweb <- function(obj) { 13 | assert_pxweb_rda_file_path(obj) 14 | load_path <- obj$paths$rda_file_path 15 | rm(obj) 16 | load(load_path) 17 | obj 18 | } 19 | 20 | #' @keywords internal 21 | #' @rdname save_pxweb 22 | load_pxweb_calls <- function(obj) { 23 | load_pxweb(obj)$calls 24 | } 25 | 26 | #' @keywords internal 27 | #' @rdname save_pxweb 28 | load_pxweb_config <- function(obj) { 29 | load_pxweb(obj)$config 30 | } 31 | 32 | #' @keywords internal 33 | #' @rdname save_pxweb 34 | load_pxweb_api_subpath <- function(obj) { 35 | load_pxweb(obj)$paths$api_subpath 36 | } 37 | -------------------------------------------------------------------------------- /tests/testthat/test-defunct.R: -------------------------------------------------------------------------------- 1 | # Test suits for the examples in the documentation 2 | 3 | context("defunct") 4 | 5 | test_that(desc = "Assert defunct errors", { 6 | # Skip tests before 3.6 since defuncterrors came with 3.6 7 | rvma <- R.version$major 8 | rvmi <- as.numeric(R.version$minor) 9 | skip_if(rvma == "3" & rvmi < 6.0) 10 | 11 | expect_error(api_catalogue(), class = "defunctError") 12 | expect_error(update_pxweb_apis(), class = "defunctError") 13 | expect_error(api_parameters(), class = "defunctError") 14 | expect_error(base_url(), class = "defunctError") 15 | expect_error(get_pxweb_data(), class = "defunctError") 16 | expect_error(get_pxweb_dims(), class = "defunctError") 17 | expect_error(get_pxweb_levels(), class = "defunctError") 18 | expect_error(get_pxweb_metadata(), class = "defunctError") 19 | expect_error(pxweb_api$new(), class = "defunctError") 20 | expect_error(checkForLevels(), class = "defunctError") 21 | 22 | }) 23 | -------------------------------------------------------------------------------- /inst/extdata/examples/json_query_agg_example.json: -------------------------------------------------------------------------------- 1 | { 2 | "query": [ 3 | { 4 | "code": "Region", 5 | "selection": { 6 | "filter": "agg:RegionA-region_2", 7 | "values": [ 8 | "A-04" 9 | ] 10 | } 11 | }, 12 | { 13 | "code": "Alder", 14 | "selection": { 15 | "filter": "agg:Ålder5år", 16 | "values": [ 17 | "-4", 18 | "5-9", 19 | "10-14", 20 | "15-19" 21 | ] 22 | } 23 | }, 24 | { 25 | "code": "Kon", 26 | "selection": { 27 | "filter": "item", 28 | "values": [ 29 | "1", 30 | "2" 31 | ] 32 | } 33 | }, 34 | { 35 | "code": "Tid", 36 | "selection": { 37 | "filter": "item", 38 | "values": [ 39 | "2015", 40 | "2016" 41 | ] 42 | } 43 | } 44 | ], 45 | "response": { 46 | "format": "px" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /R/pxweb_data_jsonstat.R: -------------------------------------------------------------------------------- 1 | #' Construct a \code{pxweb_data_jsonstat} object. 2 | #' 3 | #' @description 4 | #' An object that contain the data for a given PXWEB table. 5 | #' 6 | #' @param x a list returned from a PXWEB API to convert to a \code{pxweb_data_jsonstat} object. 7 | #' 8 | #' @return 9 | #' a \code{pxweb_data_jsonstat} object. 10 | #' 11 | #' @keywords internal 12 | pxweb_data_jsonstat <- function(x) { 13 | checkmate::assert_class(x, "list") 14 | assert_pxweb_data_jsonstat(x) 15 | jsonlite::toJSON(x, pretty = TRUE) 16 | } 17 | 18 | #' Assert that x is a correct \code{pxweb_data_jsonstat} object. 19 | #' Assert a json-stat version 1.0 or later object 20 | #' @param x an object to check. 21 | #' @keywords internal 22 | assert_pxweb_data_jsonstat <- function(x) { 23 | checkmate::assert_class(x, c("list")) 24 | checkmate::assert_names(names(x), identical.to = c("dataset")) 25 | checkmate::assert_names(names(x$dataset), must.include = c("dimension", "value")) 26 | } 27 | -------------------------------------------------------------------------------- /R/pxweb_cite.R: -------------------------------------------------------------------------------- 1 | #' Cite a PXWEB data object 2 | #' 3 | #' @details 4 | #' Functionality to automatic cite PXWEB data objects. 5 | #' 6 | #' @param x a \code{pxweb_data} object to cite. 7 | #' @param style see \code{\link[utils]{bibentry}}. 8 | #' @export 9 | pxweb_cite <- function(x, style = "citation") { 10 | checkmate::assert_class(x, "pxweb_data") 11 | 12 | api_info <- pxweb_api_catalogue()[[pxweb_api_name(pxweb(x$url))]] 13 | 14 | rref <- utils::bibentry( 15 | bibtype = "Misc", 16 | title = x$pxweb_metadata$title, 17 | author = utils::person(api_info$citation$organization), 18 | organization = api_info$citation$organization, 19 | address = api_info$citation$address, 20 | year = as.POSIXlt(x$time_stamp)$year + 1900L, 21 | url = x$url, 22 | note = paste0("[Data accessed ", x$time_stamp, " using pxweb R package ", utils::packageVersion("pxweb"), "]") 23 | ) 24 | 25 | print(rref, style = style) 26 | 27 | print(utils::citation("pxweb")) 28 | } 29 | -------------------------------------------------------------------------------- /tests/testthat/test-pxweb_api_catalogue.R: -------------------------------------------------------------------------------- 1 | # Test suits for the examples in the documentation 2 | 3 | context("pxweb_api_catalogue") 4 | 5 | test_that(desc = "pxweb_api_catalogue", { 6 | # Problems with testing ISO8859 on CRAN 7 | # https://www.r-project.org/nosvn/R.check/r-devel-linux-x86_64-debian-clang/pxweb-00check.html 8 | # Waiting to add test suites for different charsets: 9 | # https://github.com/r-lib/actions/issues/609 10 | skip_on_cran() 11 | 12 | # Recapture calls (in interactive mode) 13 | capture_calls <- FALSE 14 | 15 | with_mock_api({ 16 | if(capture_calls) start_capturing() 17 | expect_silent(pxac <- pxweb_api_catalogue()) 18 | expect_output(print(pxac), regexp = "Api:") 19 | expect_silent(pxacgh <- suppressMessages( 20 | pxweb:::pxweb_api_catalogue_from_github("master"))) 21 | expect_output(print(pxac), regexp = "Api:") 22 | 23 | expect_equal(pxac[[2]], pxacgh[[2]]) 24 | if(capture_calls) stop_capturing() 25 | }) 26 | }) 27 | -------------------------------------------------------------------------------- /man/build_pxweb_rda_file_path.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_build_pxweb_rda_file_path.R 3 | \name{build_pxweb_rda_file_path} 4 | \alias{build_pxweb_rda_file_path} 5 | \alias{build_pxweb_rda_file_path.character} 6 | \alias{build_pxweb_rda_file_path.url} 7 | \alias{build_pxweb_rda_file_path.pxweb} 8 | \alias{build_pxweb_rda_file_path.list} 9 | \title{Build or get the tmp_rda_file_path from an url or pxweb_api_s3 object} 10 | \usage{ 11 | build_pxweb_rda_file_path(x) 12 | 13 | \method{build_pxweb_rda_file_path}{character}(x) 14 | 15 | \method{build_pxweb_rda_file_path}{url}(x) 16 | 17 | \method{build_pxweb_rda_file_path}{pxweb}(x) 18 | 19 | \method{build_pxweb_rda_file_path}{list}(x) 20 | } 21 | \arguments{ 22 | \item{x}{object to create tmp_file_path for.} 23 | } 24 | \description{ 25 | Build or get the tmp_rda_file_path from an url or pxweb_api_s3 object 26 | } 27 | \details{ 28 | The hostname is used to 29 | } 30 | \keyword{internal} 31 | -------------------------------------------------------------------------------- /man/pxweb_split_query.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_split_query.R 3 | \name{pxweb_split_query} 4 | \alias{pxweb_split_query} 5 | \title{Split query in optimal sub-queries} 6 | \usage{ 7 | pxweb_split_query(pxq, px, pxmd) 8 | } 9 | \arguments{ 10 | \item{pxq}{a \code{pxweb_query} object.} 11 | 12 | \item{px}{a \code{pxweb} object.} 13 | 14 | \item{pxmd}{a \code{pxweb_metadata} object.} 15 | } 16 | \value{ 17 | a list with \code{pxweb_query} objects. 18 | } 19 | \description{ 20 | Split query in optimal sub-queries 21 | } 22 | \details{ 23 | Computes (brute-force) the optimal split of a query to 24 | match the api maximum value limit. It also take into account 25 | that time variables and content variables should not be split. 26 | Also variables with filter "top" should not be split, since 27 | the top filter does not supply the individual levels, just a 28 | number. This can probably be improved further. 29 | } 30 | \keyword{internal} 31 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to pxweb R packge 2 | 3 | You are welcome to contact us: 4 | 5 | * [Submit suggestions and bug reports](https://github.com/ropengov/pxweb/issues) (provide the output of `sessionInfo()` and `packageVersion("pxweb")`) 6 | * [Send a pull request](https://github.com/ropengov/pxweb/) 7 | * [Star us on the Github page](https://github.com/ropengov/pxweb) 8 | * [Join the discussion in Gitter](https://gitter.im/rOpenGov/pxweb) 9 | 10 | ### Acknowledgements 11 | 12 | **Kindly cite this work** as follows: [Måns Magnusson](https://github.com/mansmeg), Markus Kainu, Janne Huovari, and [Leo Lahti](https://github.com/antagomir). Retrieval and analysis of PC Axis data with the pxweb package. R package version `r sessionInfo()$otherPkgs$pxweb$Version`. URL: [http://ropengov.github.io/pxweb](http://ropengov.github.io/pxweb) 13 | 14 | We are grateful to all [contributors](https://github.com/rOpenGov/pxweb/graphs/contributors)! This project is part of [rOpenGov](http://ropengov.org). 15 | -------------------------------------------------------------------------------- /man/pxweb_data_comments.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_data_comments.R 3 | \name{pxweb_data_comments} 4 | \alias{pxweb_data_comments} 5 | \alias{pxweb_data_comments.pxweb_data} 6 | \title{Construct a \code{pxweb_data_comments} object.} 7 | \usage{ 8 | pxweb_data_comments(x) 9 | 10 | \method{pxweb_data_comments}{pxweb_data}(x) 11 | } 12 | \arguments{ 13 | \item{x}{a \code{pxweb_data} object.} 14 | } 15 | \value{ 16 | a \code{pxweb_data_comments} object 17 | } 18 | \description{ 19 | An object that contain the comments for a given PXWEB table. 20 | } 21 | \examples{ 22 | \dontrun{ 23 | url <- "https://api.scb.se/OV0104/v1/doris/en/ssd/BE/BE0101/BE0101A/BefolkningNy" 24 | json_query <- 25 | file.path(system.file(package = "pxweb"), "extdata", "examples", "json_query_example.json") 26 | pxd <- pxweb_get(url = url, query = json_query) 27 | pxdcs <- pxweb_data_comments(x = pxd) 28 | pxdc_df <- as.data.frame(pxdcs, stringsAsFactors = TRUE) 29 | } 30 | } 31 | \keyword{internal} 32 | -------------------------------------------------------------------------------- /man/pxweb_validate_query_with_metadata.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_query.R 3 | \name{pxweb_validate_query_with_metadata} 4 | \alias{pxweb_validate_query_with_metadata} 5 | \title{Validate a \code{pxweb_query} with a \code{pxweb_metadata} object} 6 | \usage{ 7 | pxweb_validate_query_with_metadata(pxq, pxmd) 8 | } 9 | \arguments{ 10 | \item{pxq}{a \code{pxweb_query} object.} 11 | 12 | \item{pxmd}{a \code{pxweb_metadata} object.} 13 | } 14 | \description{ 15 | Validate a \code{pxweb_query} with a \code{pxweb_metadata} object 16 | } 17 | \details{ 18 | Validate a query with a metadata object to asses that the query can be used to 19 | query the table. 20 | } 21 | \examples{ 22 | \dontrun{ 23 | url <- "https://api.scb.se/OV0104/v1/doris/sv/ssd/BE/BE0101/BE0101A/BefolkningNy" 24 | json_query <- file.path( 25 | system.file(package = "pxweb"), 26 | "extdata", "examples", "json_query_example.json" 27 | ) 28 | pxq <- pxweb_query(json_query) 29 | pxweb_validate_query_with_metadata(pxq, pxweb_get(url)) 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /.github/workflows/check-release.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 | paths-ignore: 6 | - 'paper/**' 7 | branches: 8 | - main 9 | - master 10 | - development 11 | - dev 12 | pull_request: 13 | paths-ignore: 14 | - 'paper/**' 15 | branches: 16 | - main 17 | - master 18 | - development 19 | - dev 20 | 21 | name: R-CMD-check (release) 22 | 23 | jobs: 24 | R-CMD-check: 25 | runs-on: ubuntu-latest 26 | env: 27 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 28 | R_KEEP_PKG_SOURCE: yes 29 | steps: 30 | - uses: actions/checkout@v3 31 | 32 | - uses: r-lib/actions/setup-r@v2 33 | with: 34 | use-public-rspm: true 35 | 36 | - uses: r-lib/actions/setup-r-dependencies@v2 37 | with: 38 | extra-packages: any::rcmdcheck 39 | needs: check 40 | 41 | - uses: r-lib/actions/check-r-package@v2 42 | -------------------------------------------------------------------------------- /.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, development, dev] 6 | paths-ignore: 7 | - 'paper/**' 8 | pull_request: 9 | branches: [main, master] 10 | paths-ignore: 11 | - 'paper/**' 12 | 13 | name: test-coverage 14 | 15 | jobs: 16 | test-coverage: 17 | runs-on: ubuntu-latest 18 | env: 19 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 20 | CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} 21 | 22 | steps: 23 | - uses: actions/checkout@v2 24 | 25 | - uses: r-lib/actions/setup-r@v2 26 | with: 27 | use-public-rspm: true 28 | 29 | - uses: r-lib/actions/setup-r-dependencies@v2 30 | with: 31 | extra-packages: any::covr 32 | needs: coverage 33 | 34 | - name: Test coverage 35 | run: covr::codecov(token = Sys.getenv("CODECOV_TOKEN"), quiet = FALSE) 36 | shell: Rscript {0} 37 | -------------------------------------------------------------------------------- /tests/testthat/test-pxweb_test_api.R: -------------------------------------------------------------------------------- 1 | # Test suits for the examples in the documentation 2 | 3 | context("pxweb_test_api") 4 | 5 | test_that(desc = "Mixed node levels object", { 6 | # CRAN seem to run tests in parallel, hence API tests cannot be run on CRAN. 7 | skip_on_cran() 8 | skip_if_offline() 9 | 10 | url <- "https://api.scb.se/OV0104/v1/doris/sv/ssd/START/AM/AM0301/" 11 | expect_output(res <- suppressWarnings(pxweb_test_api(url)), regexp = "4 node.+and 14 table") 12 | expect_true(all(res$checked)) 13 | # expect_true(all(!res$error)) # FIXME this also fails 14 | 15 | url <- "https://bank.stat.gl/api/v1/en/Greenland/BE/BE01" 16 | tryr <- try(httr::GET(url), silent = TRUE) 17 | if (!inherits(tryr, "try-error")) { 18 | expect_output(res <- suppressWarnings(pxweb_test_api(url, test_type = "touch")), regexp = "Table touched") 19 | } 20 | 21 | expect_silent(api_paths <- pxweb:::pxweb_test_create_api_paths(apis = pxweb_api_catalogue())) 22 | expect_true(all(c( 23 | "https://api.scb.se/OV0104/v1/doris/en", 24 | "https://api.scb.se/OV0104/v1/doris/sv" 25 | ) %in% api_paths$paths)) 26 | }) 27 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | # Version 0.16.2 2 | 3 | - Return better error messages when using as.data.frame() for pxweb metadata objects. 4 | - Fix Statistics Swedens new https API. 5 | 6 | 7 | # Version 0.16.1 8 | 9 | - Remove tests that are failing on CRAN. 10 | 11 | 12 | # Version 0.16.0 13 | 14 | - exposed pxweb_parse_response() and is_pxweb_response() to the package API for more advanced users that want to make their own `httr` calls to a PXWEB API. 15 | 16 | # Version 0.15.0 17 | 18 | - Added possibility to download px and sdmx response formats as files 19 | - Added StatSI API 20 | - Added codecov code coverage stats 21 | - Fixed some minor API configs 22 | 23 | # Version 0.14.0 24 | 25 | - Added feature to print pxweb_query objects to R code 26 | 27 | # Version 0.10.4 28 | 29 | - Bug fixes 30 | - More informative error messages 31 | 32 | # Version 0.9.2 33 | 34 | - Added API link to Visit Finland (Rudolf) 35 | 36 | # Version 0.8 37 | 38 | - Package rewritten in order to enhance the efficiency and design 39 | 40 | 41 | # Version 0.6.37 42 | 43 | ## New features 44 | 45 | - Added data.ssb.no in the API list in inst/extdata/api.json 46 | - Added NEWS.md file 47 | -------------------------------------------------------------------------------- /man/pxweb_http_log_on.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_logs.R 3 | \name{pxweb_http_log_on} 4 | \alias{pxweb_http_log_on} 5 | \alias{pxweb_http_log_off} 6 | \alias{pxweb_log_paths_path} 7 | \alias{pxweb_http_log_is_on} 8 | \alias{pxweb_http_log_response} 9 | \alias{pxweb_response_to_log_as_json} 10 | \title{Setup a structure to log all API calls} 11 | \usage{ 12 | pxweb_http_log_on(fn = "log_pxweb_api_http_calls.txt") 13 | 14 | pxweb_http_log_off() 15 | 16 | pxweb_log_paths_path() 17 | 18 | pxweb_http_log_is_on() 19 | 20 | pxweb_http_log_response(r) 21 | 22 | pxweb_response_to_log_as_json(r) 23 | } 24 | \arguments{ 25 | \item{fn}{The file name of the log file.} 26 | } 27 | \description{ 28 | Setup a structure to log all API calls 29 | } 30 | \details{ 31 | Set up internal structure to handle http PXWEB API calls. http calls are stored in a log file. 32 | To access the path to this log file, the path is stored in the pxweb folder in the tempdir(). 33 | The path is given by \code{pxweb_log_paths_path()}. 34 | If the file exists, the http calls should be logged (appended) to the log file where the object contains the path. 35 | } 36 | \keyword{internal} 37 | -------------------------------------------------------------------------------- /R/pxweb_build_pxweb_rda_file_path.R: -------------------------------------------------------------------------------- 1 | #' Build or get the tmp_rda_file_path from an url or pxweb_api_s3 object 2 | #' 3 | #' @details 4 | #' The hostname is used to 5 | #' 6 | #' @param x object to create tmp_file_path for. 7 | #' 8 | #' @keywords internal 9 | build_pxweb_rda_file_path <- function(x) { 10 | UseMethod("build_pxweb_rda_file_path") 11 | } 12 | 13 | #' @rdname build_pxweb_rda_file_path 14 | #' @keywords internal 15 | build_pxweb_rda_file_path.character <- function(x) { 16 | checkmate::assert_string(x) 17 | parsed_url <- parse_url_or_fail(x) 18 | build_pxweb_rda_file_path(parsed_url) 19 | } 20 | 21 | #' @rdname build_pxweb_rda_file_path 22 | #' @keywords internal 23 | build_pxweb_rda_file_path.url <- function(x) { 24 | checkmate::assert_class(x, "url") 25 | tmp_dir <- pxweb_tempdir() 26 | file.path(tmp_dir, paste0(make.names(pxweb_api_name(x)), ".rda")) 27 | } 28 | 29 | #' @rdname build_pxweb_rda_file_path 30 | #' @keywords internal 31 | build_pxweb_rda_file_path.pxweb <- function(x) { 32 | checkmate::assert_class(x, "pxweb") 33 | x$paths$rda_file_path 34 | } 35 | 36 | #' @rdname build_pxweb_rda_file_path 37 | #' @keywords internal 38 | build_pxweb_rda_file_path.list <- function(x) { 39 | assert_pxweb_url(x) 40 | build_pxweb_rda_file_path(x$url) 41 | } 42 | -------------------------------------------------------------------------------- /man/pxweb_interactive.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_interactive.R 3 | \name{pxweb_interactive} 4 | \alias{pxweb_interactive} 5 | \alias{interactive_pxweb} 6 | \title{Find and download data interactively from a PXWEB API} 7 | \usage{ 8 | pxweb_interactive(x = NULL) 9 | 10 | interactive_pxweb(x = NULL) 11 | } 12 | \arguments{ 13 | \item{x}{The name or alias of the pxweb api to connect to, a \code{pxweb} object or an url.} 14 | } 15 | \value{ 16 | The function returns a list with three slots: 17 | \code{url}: The URL to the data 18 | \code{query}: The query to access the data 19 | \code{data}: The downloaded data (if chosen to download data) 20 | } 21 | \description{ 22 | Wrapper function (for \link{pxweb_get}) to simply find and download data to the current R session. 23 | } 24 | \examples{ 25 | pxweb_api_catalogue() # List apis 26 | 27 | ## The examples below can only be run in interactive mode 28 | ## x <- pxweb_interactive() 29 | ## x <- pxweb_interactive(x = "api.scb.se") 30 | ## x <- pxweb_interactive(x = "https://api.scb.se/OV0104/v1/doris/en/ssd/BE/BE0101/") 31 | ## x <- pxweb_interactive(x = "https://api.scb.se/OV0104/v1/doris/en/ssd/BE/BE0101/BE0101A/") 32 | 33 | } 34 | \seealso{ 35 | \code{\link{pxweb_get}} 36 | } 37 | -------------------------------------------------------------------------------- /R/pxweb_clear_cache.R: -------------------------------------------------------------------------------- 1 | #' Clear cache of all (or one) \code{pxweb} object 2 | #' 3 | #' @details 4 | #' Clean the cache and sleep to restore api timing limit. 5 | #' 6 | #' @param x a \code{pxweb} object to clear cache for. Default is NULL (clear everything). 7 | #' 8 | #' @keywords internal 9 | pxweb_clear_cache <- function(x = NULL) { 10 | if (is.null(x)) { 11 | files <- dir(pxweb_tempdir(), full.names = TRUE) 12 | if (length(files) == 0) { 13 | return(FALSE) 14 | } 15 | sleep_s <- numeric(length(files)) 16 | for (f in seq_along(files)) { 17 | obj <- NULL # To capture a builde NOTE and safeguard for global variable handling 18 | load(files[f]) 19 | time_diff_s <- as.numeric(Sys.time()) - as.numeric(obj$calls$time_stamps[[1]]) 20 | sleep_s[f] <- max(obj$config$period_in_seconds - time_diff_s, 0) 21 | } 22 | Sys.sleep(max(sleep_s)) 23 | file.remove(files) 24 | return(TRUE) 25 | } else { 26 | checkmate::assert_class(x, "pxweb") 27 | time_diff_s <- as.numeric(Sys.time()) - as.numeric(x$calls$time_stamps[[1]]) 28 | sleep_s <- max(x$config$period_in_seconds - time_diff_s, 0) 29 | Sys.sleep(sleep_s) 30 | if (file.exists(x$paths$rda_file_path)) file.remove(x$paths$rda_file_path) 31 | return(TRUE) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /R/pxweb_add_api_subpath.R: -------------------------------------------------------------------------------- 1 | #' Add the subpath slot to a pxweb path slot 2 | #' 3 | #' @details 4 | #' Queries the path from pos 1 and up until a config is returned. 5 | #' 6 | #' @param obj an object to add subpath to 7 | #' 8 | #' @keywords internal 9 | pxweb_add_api_subpath <- function(obj) { 10 | assert_pxweb_url(obj) 11 | 12 | if (inherits(obj, "pxweb")) { 13 | return(obj) 14 | } 15 | 16 | path_splt <- strsplit(obj$url$path, "/")[[1]] 17 | 18 | if (file.exists(obj$paths$rda_file_path)) { 19 | old_api_subpath <- load_pxweb_api_subpath(obj) 20 | tmp_vec <- path_splt[1:length(old_api_subpath$vector)] 21 | tmp_path <- paste(tmp_vec, collapse = "/") 22 | obj$paths$api_subpath <- list(path = tmp_path, vector = tmp_vec) 23 | return(obj) 24 | } 25 | 26 | tmp_url <- obj$url 27 | 28 | # Split up url to api parts 29 | for (p in 1:length(path_splt)) { 30 | obj <- pxweb_add_call(obj) 31 | tmp_url$path <- paste(path_splt[1:p], collapse = "/") 32 | tmp_cfg_url <- build_pxweb_config_url(tmp_url) 33 | tmp_r <- httr::GET(tmp_cfg_url) 34 | pxweb_http_log_response(tmp_r) 35 | if (is_pxweb_config_response(tmp_r)) break() 36 | } 37 | 38 | # Add the subpath 39 | obj$paths$api_subpath <- list(path = tmp_url$path, vector = path_splt[1:p]) 40 | 41 | obj 42 | } 43 | -------------------------------------------------------------------------------- /inst/extdata/test_files/json_queries/json_full_test_query.json: -------------------------------------------------------------------------------- 1 | { 2 | "query": [ 3 | { 4 | "code": "Region", 5 | "selection": { 6 | "filter": "vs:RegionKommun07", 7 | "values": [ 8 | "0114", 9 | "2584" 10 | ] 11 | } 12 | }, 13 | { 14 | "code": "Civilstand", 15 | "selection": { 16 | "filter": "item", 17 | "values": [ 18 | "OG", 19 | "G", 20 | "ÄNKL" 21 | ] 22 | } 23 | }, 24 | { 25 | "code": "Alder", 26 | "selection": { 27 | "filter": "agg:Ålder5år", 28 | "values": [ 29 | "-4", 30 | "10-14", 31 | "95-99" 32 | ] 33 | } 34 | }, 35 | { 36 | "code": "Kon", 37 | "selection": { 38 | "filter": "item", 39 | "values": [ 40 | "1", 41 | "2" 42 | ] 43 | } 44 | }, 45 | { 46 | "code": "ContentsCode", 47 | "selection": { 48 | "filter": "item", 49 | "values": [ 50 | "BE0101N1" 51 | ] 52 | } 53 | }, 54 | { 55 | "code": "Tid", 56 | "selection": { 57 | "filter": "top", 58 | "values": ["11"] 59 | } 60 | } 61 | ], 62 | "response": { 63 | "format": "json" 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /tests/testthat/test-pxweb_api_paths.R: -------------------------------------------------------------------------------- 1 | # Test suits for the examples in the documentation 2 | 3 | context("pxweb_api_paths") 4 | 5 | test_that(desc = "Access api paths", { 6 | # CRAN seem to run tests in parallel, hence API tests cannot be run on CRAN. 7 | skip_on_cran() 8 | skip_if_offline() 9 | 10 | url <- "https://api.scb.se/OV0104/v1/doris/sv/ssd/START/AM/AM0301/" 11 | expect_silent(scb <- pxweb(url)) 12 | 13 | expect_equal(pxweb_api_name(scb), "api.scb.se") 14 | 15 | expect_equal(pxweb_api_subpath(scb, init_slash = FALSE), "OV0104/v1/doris/sv") 16 | expect_equal(pxweb_api_subpath(scb, init_slash = TRUE), "/OV0104/v1/doris/sv") 17 | expect_equal(pxweb_api_subpath(scb, as_vector = TRUE), c("OV0104", "v1", "doris", "sv")) 18 | 19 | expect_equal(pxweb_api_path(scb, init_slash = FALSE), "OV0104/v1/doris/sv/ssd/START/AM/AM0301") 20 | expect_equal(pxweb_api_path(scb, init_slash = TRUE), "/OV0104/v1/doris/sv/ssd/START/AM/AM0301") 21 | expect_equal(pxweb_api_path(scb, as_vector = TRUE), c("OV0104", "v1", "doris", "sv", "ssd", "START", "AM", "AM0301")) 22 | 23 | expect_equal(pxweb_api_dbpath(scb, init_slash = FALSE), "ssd/START/AM/AM0301") 24 | expect_equal(pxweb_api_dbpath(scb, init_slash = TRUE), "/ssd/START/AM/AM0301") 25 | expect_equal(pxweb_api_dbpath(scb, as_vector = TRUE), c("ssd", "START", "AM", "AM0301")) 26 | }) 27 | -------------------------------------------------------------------------------- /inst/examples/ex_data_mining.R: -------------------------------------------------------------------------------- 1 | ## EXAMPLE: USING sweSCB TO MINE DATA FROM THE SCB API 2 | 3 | ## 1. Get metadata from the base node 4 | a <- get_pxweb_metadata() 5 | 6 | # View the data. We will recycle the values in the "id" column to delve deeper into the API node structure. 7 | View(a) 8 | 9 | # Go down one level into the node tree. 10 | b <- get_pxweb_metadata(a$id[1]) 11 | 12 | # Do this for consecutive steps... 13 | cc <- get_pxweb_metadata(b$id[5]) 14 | 15 | # ...until we reach a node with no nodes below it, only data 16 | d <- get_pxweb_metadata(cc$id[3]) 17 | 18 | datanode <- get_pxweb_metadata(d$id[1]) 19 | 20 | # We receive a message that this is a bottom node. We can now use d$URL to get dimensions of the data: 21 | dims <- get_pxweb_dims(datanode) 22 | 23 | # View dimension names 24 | for(i in 1:length(dims)) { 25 | print(dims[[i]]$code) 26 | } 27 | 28 | # View dimension value space 29 | for(i in 1:length(dims)) { 30 | print(dims[[i]]$code) 31 | print(dims[[i]]$values) 32 | } 33 | 34 | # Submit a query containing one or several values for each of the named dimensions 35 | sdata <- get_pxweb(datanode$URL, list(ContentsCode = "AM0110D1", Utbildningsgrupp = "*", Kon = "*", Tid = "2012")) 36 | 37 | # Create a simple bar plot with the resulting data 38 | ggplot(sdata,aes(x=utbildningsgrupp.SUN.2000,y=Grundlön.2012,fill=kön)) + geom_bar(position=position_dodge()) + coord_flip() 39 | -------------------------------------------------------------------------------- /man/pxweb_query.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_query.R 3 | \name{pxweb_query} 4 | \alias{pxweb_query} 5 | \alias{pxweb_query.character} 6 | \alias{pxweb_query.json} 7 | \alias{pxweb_query.pxweb_query} 8 | \alias{pxweb_query.list} 9 | \alias{pxweb_query.response} 10 | \alias{pxweb_query.pxweb_explorer} 11 | \title{Create a PXWEB query} 12 | \usage{ 13 | pxweb_query(x) 14 | 15 | \method{pxweb_query}{character}(x) 16 | 17 | \method{pxweb_query}{json}(x) 18 | 19 | \method{pxweb_query}{pxweb_query}(x) 20 | 21 | \method{pxweb_query}{list}(x) 22 | 23 | \method{pxweb_query}{response}(x) 24 | 25 | \method{pxweb_query}{pxweb_explorer}(x) 26 | } 27 | \arguments{ 28 | \item{x}{an object to cast as a pxweb_query object.} 29 | } 30 | \description{ 31 | Creates a pxweb query object from either a list with named values, 32 | a json query file or json query string. See examples below. 33 | } 34 | \examples{ 35 | dims <- list( 36 | Alue = c("*"), 37 | "Asuntokunnan koko" = c("*"), 38 | Talotyyppi = c("S"), 39 | Vuosi = c("*") 40 | ) 41 | pxq1 <- pxweb_query(dims) 42 | 43 | json_query <- file.path( 44 | system.file(package = "pxweb"), 45 | "extdata", "examples", "json_query_example.json" 46 | ) 47 | pxq2 <- pxweb_query(json_query) 48 | 49 | } 50 | \seealso{ 51 | \code{\link{pxweb_query_as_json}}, \code{\link{pxweb_query_as_rcode}} 52 | } 53 | \keyword{internal} 54 | -------------------------------------------------------------------------------- /man/pxweb.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb.R 3 | \name{pxweb} 4 | \alias{pxweb} 5 | \alias{is.pxweb} 6 | \alias{print.pxweb} 7 | \title{S3 constructor for \code{pxweb} api object.} 8 | \usage{ 9 | pxweb(url) 10 | 11 | is.pxweb(x) 12 | 13 | \method{print}{pxweb}(x, ...) 14 | } 15 | \arguments{ 16 | \item{url}{an url to a pxweb api including language and version of the api. See examples.} 17 | 18 | \item{x}{an an object to test if it is a \code{pxweb} object.} 19 | 20 | \item{...}{further arguments supplied to \code{print()}.} 21 | } 22 | \value{ 23 | A \code{pxweb} object. 24 | } 25 | \description{ 26 | The pxwebapi object contain all information to do calls to the pxweb api and keep count 27 | of the number of calls. The object is constructed 28 | The object will also be cached in R temp folder to minimize calls to api. 29 | All urls should be passed through the constructor to set up the pxweb api config. 30 | 31 | \emph{Garantuees}: 32 | The base_url has been pinged 33 | The sub_path has been checked 34 | The config has been captured from the API 35 | The url has been checked to be a pxweb api (through config) 36 | } 37 | \examples{ 38 | \dontrun{ 39 | pxapi_1 <- 40 | pxweb("https://api.scb.se/OV0104/v1/doris/sv/ssd/START/ME/ME0104/ME0104C/ME0104T24") 41 | pxapi_2 <- 42 | pxweb(url = "https://api.scb.se/OV0104/v1/doris/sv") 43 | } 44 | 45 | } 46 | \keyword{internal} 47 | -------------------------------------------------------------------------------- /paper/softwarereview.tex: -------------------------------------------------------------------------------- 1 | \documentclass[softwarereview]{jss} 2 | 3 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4 | %% declarations for jss.cls %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6 | 7 | %% reviewer 8 | \Reviewer{Antony Unwin\\University of Augsburg} 9 | \Plainreviewer{Antony Unwin} 10 | 11 | %% about the software 12 | \Softwaretitle{\pkg{Aabel} 1.5.7} 13 | \Plaintitle{Aabel 1.5.7} 14 | %% if different from \Softwaretitle also set 15 | %% \Shorttitle{Aabel 1.5.7} 16 | \Publisher{Gigawiz Ltd.\ Co.} 17 | \Pubaddress{Tulsa, OK} 18 | \Price{USD~349 (standard), USD~249 (academic)} 19 | \URL{http://www.gigawiz.com/} 20 | 21 | %% publication information 22 | %% NOTE: Typically, this can be left commented and will be filled out by the technical editor 23 | %% \Volume{50} 24 | %% \Issue{1} 25 | %% \Month{June} 26 | %% \Year{2012} 27 | %% \Submitdate{2012-06-04} 28 | 29 | %% address of reviewer 30 | \Address{ 31 | Antony Unwin\\ 32 | University of Augsburg\\ 33 | Department of Computer Oriented Statistics and Data Analysis\\ 34 | 86135 Augsburg, Germany\\ 35 | E-mail: \email{Antony.Unwin@math.uni-augsburg.de}\\ 36 | URL: \url{http://www1.math.uni-augsburg.de/~unwin/} 37 | } 38 | 39 | %% end of declarations %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 40 | 41 | 42 | \begin{document} 43 | 44 | %% include the review as usual 45 | %% Note that you should use the \pkg{}, \proglang{} and \code{} commands. 46 | 47 | \end{document} -------------------------------------------------------------------------------- /paper/bookreview.tex: -------------------------------------------------------------------------------- 1 | \documentclass[bookreview]{jss} 2 | 3 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4 | %% declarations for jss.cls %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6 | 7 | %% reviewer 8 | \Reviewer{Frederic Udina\\Pompeu Fabra University} 9 | \Plainreviewer{Frederic Udina} 10 | 11 | %% about the book 12 | \Booktitle{Visualizing Categorical Data} 13 | \Bookauthor{Michael Friendly} 14 | \Publisher{SAS Institute Inc.} 15 | \Pubaddress{Carey, NC} 16 | \Pubyear{2000} 17 | \ISBN{1-58025-660-0} 18 | \Pages{456} 19 | \Price{USD 69.95 (P)} 20 | \URL{http://www.math.yorku.ca/SCS/vcd/} 21 | %% if different from \Booktitle also set 22 | %% \Plaintitle{Visualizing Categorical Data} 23 | %% \Shorttitle{Visualizing Categorical Data} 24 | 25 | %% publication information 26 | %% NOTE: Typically, this can be left commented and will be filled out by the technical editor 27 | %% \Volume{50} 28 | %% \Issue{7} 29 | %% \Month{June} 30 | %% \Year{2012} 31 | %% \Submitdate{2012-06-04} 32 | 33 | %% address of (at least one) author 34 | \Address{ 35 | Frederic Udina\\ 36 | Pompeu Fabra University\\ 37 | Department of Economics and Business\\ 38 | Barcelona, Spain 08005\\ 39 | E-mail: \email{udina@upf.es}\\ 40 | URL: \url{http://libiya.upf.es/} 41 | } 42 | 43 | %% end of declarations %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 44 | 45 | 46 | \begin{document} 47 | 48 | %% include the review as usual 49 | %% Note that you should use the \pkg{}, \proglang{} and \code{} commands. 50 | 51 | \end{document} -------------------------------------------------------------------------------- /.github/workflows/check-standard.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 | workflow_dispatch: 5 | schedule: 6 | - cron: '0 0 * * 0' 7 | 8 | name: R-CMD-check (standard) 9 | 10 | jobs: 11 | R-CMD-check: 12 | runs-on: ${{ matrix.config.os }} 13 | 14 | name: ${{ matrix.config.os }} (${{ matrix.config.r }}) 15 | 16 | strategy: 17 | fail-fast: false 18 | matrix: 19 | config: 20 | - {os: macos-latest, r: 'release'} 21 | - {os: windows-latest, r: 'release'} 22 | - {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'} 23 | - {os: ubuntu-latest, r: 'release'} 24 | - {os: ubuntu-latest, r: 'oldrel-1'} 25 | 26 | env: 27 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 28 | R_KEEP_PKG_SOURCE: yes 29 | 30 | steps: 31 | - uses: actions/checkout@v3 32 | 33 | - uses: r-lib/actions/setup-pandoc@v2 34 | 35 | - uses: r-lib/actions/setup-r@v2 36 | with: 37 | r-version: ${{ matrix.config.r }} 38 | http-user-agent: ${{ matrix.config.http-user-agent }} 39 | use-public-rspm: true 40 | 41 | - uses: r-lib/actions/setup-r-dependencies@v2 42 | with: 43 | extra-packages: any::rcmdcheck 44 | needs: check 45 | 46 | - uses: r-lib/actions/check-r-package@v2 47 | with: 48 | upload-snapshots: true 49 | -------------------------------------------------------------------------------- /.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 | 31 | steps: 32 | - uses: actions/checkout@v3 33 | 34 | - uses: r-lib/actions/setup-pandoc@v2 35 | 36 | - uses: r-lib/actions/setup-r@v2 37 | with: 38 | r-version: ${{ matrix.config.r }} 39 | http-user-agent: ${{ matrix.config.http-user-agent }} 40 | use-public-rspm: true 41 | 42 | - uses: r-lib/actions/setup-r-dependencies@v2 43 | with: 44 | extra-packages: any::rcmdcheck 45 | needs: check 46 | 47 | - uses: r-lib/actions/check-r-package@v2 48 | with: 49 | upload-snapshots: true 50 | -------------------------------------------------------------------------------- /man/pxweb_advanced_get.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_get.R 3 | \name{pxweb_advanced_get} 4 | \alias{pxweb_advanced_get} 5 | \title{Do a GET call to PXWEB API for advanced users} 6 | \usage{ 7 | pxweb_advanced_get( 8 | url, 9 | query = NULL, 10 | verbose = TRUE, 11 | log_http_calls = FALSE, 12 | pxmdo = NULL, 13 | ... 14 | ) 15 | } 16 | \arguments{ 17 | \item{url}{a \code{pxweb} object or url that can be coherced to a \code{pxweb} object.} 18 | 19 | \item{query}{a json string, json file or list object that can be coherced to a \code{pxweb_query} object.} 20 | 21 | \item{verbose}{should large queries print out progress.} 22 | 23 | \item{log_http_calls}{Should the http calls to the API be logged (for debugging reasons). 24 | If TRUE, all calls and responses are logged and written to "log_pxweb_api_http_calls.txt" in the working directory.} 25 | 26 | \item{pxmdo}{A \code{pxweb_metadata} object to use for query.} 27 | 28 | \item{...}{Further arguments sent to \code{httr::POST} (for queries) or \code{httr::GET} (for query = \code{NULL}). 29 | If used with query, also supply a \code{pxweb_metadata} object. Otherwise the same parameters are sent to 30 | both \code{httr::POST} and \code{httr::GET}.} 31 | } 32 | \description{ 33 | Do a GET call to PXWEB API for advanced users 34 | } 35 | \details{ 36 | This function is intended for more advanced users that want to supply specific arguments in 37 | \code{httr} calls or what to debug \code{httr} calls. 38 | 39 | \code{pxweb_get()} is a wrapper for standard use. 40 | } 41 | -------------------------------------------------------------------------------- /man/pxweb_get_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_get.R 3 | \name{pxweb_get_data} 4 | \alias{pxweb_get_data} 5 | \title{Do a GET call to PXWEB API and return a data.frame} 6 | \usage{ 7 | pxweb_get_data( 8 | url, 9 | query, 10 | verbose = TRUE, 11 | column.name.type = "text", 12 | variable.value.type = "text" 13 | ) 14 | } 15 | \arguments{ 16 | \item{url}{a \code{pxweb} object or url that can be coherced to a \code{pxweb} object.} 17 | 18 | \item{query}{a json string, json file or list object that can be coherced to a \code{pxweb_query} object.} 19 | 20 | \item{verbose}{should large queries print out progress.} 21 | 22 | \item{column.name.type}{character: should \code{code} or \code{text} be used as column names?} 23 | 24 | \item{variable.value.type}{character: should \code{code} or \code{text} be used as values in columns?} 25 | } 26 | \description{ 27 | Do a GET call to PXWEB API and return a data.frame 28 | } 29 | \details{ 30 | The functions use will do a \code{pxweb_query} to a PXWEB \code{url} and return a \code{data.frame}. 31 | This is a wrapper for the \code{pxweb_get} function. 32 | } 33 | \examples{ 34 | \dontrun{ 35 | url <- "https://api.scb.se/OV0104/v1/doris/sv/ssd/BE/BE0101/BE0101A/BefolkningNy" 36 | query <- file.path( 37 | system.file(package = "pxweb"), 38 | "extdata", "examples", "json_query_example.json" 39 | ) 40 | df <- pxweb_get_data(url = url, query = query) 41 | } 42 | 43 | } 44 | \seealso{ 45 | See \code{\link{pxweb_get}} for mor general usage and \code{\link{pxweb_query}} for details on PXWEB queries. 46 | } 47 | -------------------------------------------------------------------------------- /man/pxweb_test_api.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_test_api_endpoint.R 3 | \name{pxweb_test_api} 4 | \alias{pxweb_test_api} 5 | \title{Test a full or a part of a PXWEB api.} 6 | \usage{ 7 | pxweb_test_api( 8 | url, 9 | test_type = "first", 10 | n = 1, 11 | verbose = TRUE, 12 | time_limit = Inf 13 | ) 14 | } 15 | \arguments{ 16 | \item{url}{The base url to the pxweb api (or a branch of the metadata tree)} 17 | 18 | \item{test_type}{What type of test should be done. 19 | The \code{first} observation of each table. 20 | A random \code{sample} of size \code{n}. 21 | Download all \code{full} tables. 22 | \code{touch} the api by only downloading the first table metadata. 23 | This is minimal testing of the API.} 24 | 25 | \item{n}{sample size if \code{test_type} is \code{sample}.} 26 | 27 | \item{verbose}{The function will print information.} 28 | 29 | \item{time_limit}{Time limit in second the API is allowed to be tested.} 30 | } 31 | \value{ 32 | Function returns a data.frame with information on each node 33 | Two variables are added: 34 | \code{checked} : The node has been checked 35 | \code{error} : Whether there were errors encountered with the call 36 | \code{download_error} : Whether there were errors encountered during download 37 | } 38 | \description{ 39 | The function can be used to test a whole pxweb api by using the api base url. 40 | By using a branch in a tree the api is tested below this branch. 41 | } 42 | \examples{ 43 | \dontrun{ 44 | url <- "https://bank.stat.gl/api/v1/en/Greenland/BE/BE01" 45 | res <- pxweb_test_api(url) 46 | res <- pxweb_test_api(url, test_type = "touch") 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /R/pxweb_add_call.R: -------------------------------------------------------------------------------- 1 | #' Add an api call to a pxweb_api_s3 object 2 | #' 3 | #' @description 4 | #' The pxweb_add_call function add a call the the api in the call stack, then compute 5 | #' 6 | #' Promise: 7 | #' The stored rda api object will always have the latest calls 8 | #' This is not thread safe so only one session at a time should call the api. 9 | #' 10 | #' @param obj a \code{pxweb_api_s3} object 11 | #' 12 | #' @keywords internal 13 | pxweb_add_call <- function(obj, time_stamp = Sys.time()) { 14 | assert_pxweb_calls(obj) 15 | assert_pxweb_config(obj) 16 | checkmate::assert_class(time_stamp, "POSIXct") 17 | checkmate::assert_number(as.numeric(time_stamp)) 18 | 19 | if (file.exists(obj$paths$rda_file_path)) { 20 | obj$calls <- load_pxweb_calls(obj) 21 | } 22 | 23 | # Add call to stack 24 | obj$calls$time_stamps <- c(list(time_stamp), obj$calls$time_stamps) 25 | 26 | # This compute 27 | if (length(obj$calls$time_stamps) >= obj$config$calls_per_period) { 28 | second_between_first_and_last_call <- as.numeric(obj$calls$time_stamps[[1]], units = "secs") - as.numeric(obj$calls$time_stamps[[length(obj$calls$time_stamps)]], units = "secs") 29 | obj$calls$time_stamps[[length(obj$calls$time_stamps)]] <- NULL 30 | if (is.pxweb(obj)) save_pxweb(obj) 31 | # cat(second_between_first_and_last_call, ":", obj$config$calls_per_period, ": Sleep:", max(obj$config$calls_per_period - second_between_first_and_last_call,0)) 32 | # print(obj$calls$time_stamps[c(1,length(obj$calls$time_stamps))]) 33 | Sys.sleep(time = max(obj$config$calls_per_period - second_between_first_and_last_call, 0)) 34 | } else { 35 | if (is.pxweb(obj)) save_pxweb(obj) 36 | } 37 | obj 38 | } 39 | -------------------------------------------------------------------------------- /man/pxweb-package.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb-package.R 3 | \docType{package} 4 | \name{pxweb-package} 5 | \alias{pxweb-package} 6 | \title{Interface to PX-WEB APIs from R} 7 | \description{ 8 | PXWEB is a common web API used by many European Statistical agencies to disseminate official statistics. 9 | The pxweb package facilitates connections and usage of these APIs. 10 | } 11 | \references{ 12 | The decription of the PXWEB API here: 13 | \url{https://www.scb.se/en/About-us/about-the-website-and-terms-of-use/open-data-api/} 14 | The official home page of PXWEB can be found here: 15 | \url{https://www.scb.se/en/services/statistical-programs-for-px-files/px-web/} 16 | } 17 | \seealso{ 18 | Useful links: 19 | \itemize{ 20 | \item \url{https://github.com/rOpenGov/pxweb/} 21 | \item \url{https://ropengov.github.io/pxweb/} 22 | \item \url{https://github.com/rOpenGov/pxweb} 23 | \item Report bugs at \url{https://github.com/rOpenGov/pxweb/issues} 24 | } 25 | 26 | } 27 | \author{ 28 | \strong{Maintainer}: Mans Magnusson \email{mons.magnusson@gmail.com} (\href{https://orcid.org/0000-0002-0296-2719}{ORCID}) 29 | 30 | Authors: 31 | \itemize{ 32 | \item Markus Kainu 33 | \item Janne Huovari 34 | \item Leo Lahti (\href{https://orcid.org/0000-0001-5537-637X}{ORCID}) 35 | } 36 | 37 | Other contributors: 38 | \itemize{ 39 | \item Love Hansson [contributor] 40 | \item Eydun Nielsen [contributor] 41 | \item Bo Werth [contributor] 42 | \item Thomas Runarsson [contributor] 43 | \item Torbjörn Lindquist [contributor] 44 | \item Palmar Thorsteinsson [contributor] 45 | \item Pyry Kantanen [contributor] 46 | \item Sebastian Ankargren [contributor] 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /R/pxweb_levels.R: -------------------------------------------------------------------------------- 1 | #' Construct a \code{pxweb_levels} object. 2 | #' 3 | #' @description 4 | #' An object that contain the levels for a given PXWEB api position. 5 | #' 6 | #' @param x a list returned from a PXWEB API to convert to a \code{pxweb_levels} object. 7 | #' 8 | #' @return 9 | #' a \code{pxweb_levels} object 10 | #' 11 | #' @keywords internal 12 | pxweb_levels <- function(x) { 13 | checkmate::assert_class(x, "list") 14 | class(x) <- c("pxweb_levels", "list") 15 | assert_pxweb_levels(x) 16 | x 17 | } 18 | 19 | 20 | #' Assert that x is a correct \code{pxweb_levels} object. 21 | #' @param x an object to check. 22 | #' @keywords internal 23 | assert_pxweb_levels <- function(x) { 24 | checkmate::assert_class(x, c("pxweb_levels", "list")) 25 | for (i in seq_along(x)) { 26 | checkmate::assert_names(names(x[[i]]), must.include = c("id", "type", "text"), .var.name = paste0("names(x[[", i, "]])")) 27 | checkmate::assert_string(x[[i]]$id, .var.name = paste0("x[[", i, "]]$id")) 28 | checkmate::assert_choice(x[[i]]$type, choices = c("l", "t", "h"), .var.name = paste0("x[[", i, "]]$type")) 29 | checkmate::assert_string(x[[i]]$text, .var.name = paste0("x[[", i, "]]$id")) 30 | } 31 | } 32 | 33 | 34 | #' @export 35 | print.pxweb_levels <- function(x, ...) { 36 | cat("PXWEB LEVELS\n") 37 | for (i in seq_along(x)) { 38 | cat(" ", x[[i]]$id, " (", x[[i]]$type, "): ", x[[i]]$text, "\n", sep = "") 39 | } 40 | } 41 | 42 | #' @keywords internal 43 | pxweb_levels_choices_df <- function(x) { 44 | checkmate::assert_class(x, "pxweb_levels") 45 | df <- pxweb_as_data_frame.pxweb_levels(x) 46 | df$is_choice <- ifelse(df$type %in% c("t", "l"), yes = TRUE, no = FALSE) 47 | df$choice_idx <- cumsum(df$is_choice) 48 | df$choice_idx[!df$is_choice] <- NA 49 | df 50 | } 51 | -------------------------------------------------------------------------------- /R/pxweb_database_list.R: -------------------------------------------------------------------------------- 1 | #' Construct a \code{pxweb_database_list} object. 2 | #' 3 | #' @description 4 | #' An object that contain the list of databases for a given PXWEB api. 5 | #' 6 | #' @param x a list returned from a PXWEB API to convert to a \code{pxweb_database_list} object. 7 | #' 8 | #' @return 9 | #' a \code{pxweb_database_list} object 10 | #' 11 | #' @keywords internal 12 | pxweb_database_list <- function(x) { 13 | checkmate::assert_class(x, "list") 14 | class(x) <- c("pxweb_database_list", "list") 15 | assert_pxweb_database_list(x) 16 | x 17 | } 18 | 19 | #' Assert that x is a correct \code{pxweb_database_list} object. 20 | #' @param x an object to check. 21 | #' @keywords internal 22 | assert_pxweb_database_list <- function(x) { 23 | checkmate::assert_class(x, c("pxweb_database_list", "list")) 24 | for (i in seq_along(x)) { 25 | checkmate::assert_names(names(x[[i]]), must.include = c("dbid", "text"), .var.name = paste0("names(x[[", i, "]])")) 26 | checkmate::assert_string(x[[i]]$dbid, .var.name = paste0("x[[", i, "]]$dbid")) 27 | checkmate::assert_string(x[[i]]$text, .var.name = paste0("x[[", i, "]]$text")) 28 | } 29 | } 30 | 31 | #' Assert that x is a correct \code{pxweb_database_list} object. 32 | #' @param x an object to check. 33 | #' @keywords internal 34 | as_pxweb_levels <- function(x) { 35 | checkmate::assert_class(x, "pxweb_database_list") 36 | for (i in seq_along(x)) { 37 | x[[i]]$id <- x[[i]]$dbid 38 | x[[i]]$type <- "l" 39 | x[[i]] <- x[[i]][c("id", "type", "text")] 40 | } 41 | class(x) <- c("pxweb_levels", "list") 42 | assert_pxweb_levels(x) 43 | x 44 | } 45 | 46 | #' @export 47 | print.pxweb_database_list <- function(x, ...) { 48 | cat("PXWEB DATABASE LIST\n") 49 | for (i in seq_along(x)) { 50 | cat(" ", x[[i]]$dbid, ": ", x[[i]]$text, "\n") 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /.github/workflows/rogtemplate-gh-pages.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/master/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 | tags: ['*'] 7 | paths-ignore: 8 | - 'paper/**' 9 | workflow_dispatch: 10 | 11 | name: rogtemplate-gh-pages 12 | 13 | jobs: 14 | rogtemplate-gh-pages: 15 | runs-on: ubuntu-latest 16 | env: 17 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 18 | steps: 19 | - uses: actions/checkout@v2 20 | 21 | - uses: r-lib/actions/setup-pandoc@v2 22 | 23 | - uses: r-lib/actions/setup-r@v2 24 | with: 25 | use-public-rspm: true 26 | 27 | - uses: r-lib/actions/setup-r-dependencies@v2 28 | with: 29 | needs: website 30 | extra-packages: 31 | local::. 32 | any::pkgdown 33 | ropengov/rogtemplate 34 | any::magick 35 | any::remotes 36 | 37 | - name: Build logo if not present and prepare template 38 | run: | 39 | # Check that logo is not present 40 | if (isFALSE(file.exists(file.path("man", "figures", "logo.png")) || 41 | file.exists(file.path("man", "figures", "logo.png")))) { 42 | rogtemplate::rog_logo() 43 | } else { 44 | 45 | message("The package already has a logo") 46 | } 47 | 48 | rogtemplate::rog_add_template_pkgdown() 49 | 50 | shell: Rscript {0} 51 | 52 | - name: Deploy package 53 | run: | 54 | git config --local user.name "$GITHUB_ACTOR" 55 | git config --local user.email "$GITHUB_ACTOR@users.noreply.github.com" 56 | Rscript -e 'pkgdown::deploy_to_branch(new_process = FALSE)' 57 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | S3method(as.data.frame,pxweb_data) 4 | S3method(as.data.frame,pxweb_data_comments) 5 | S3method(as.data.frame,pxweb_levels) 6 | S3method(as.data.frame,pxweb_metadata) 7 | S3method(as.matrix,pxweb_data) 8 | S3method(print,pxweb) 9 | S3method(print,pxweb_api_catalogue_entry) 10 | S3method(print,pxweb_data) 11 | S3method(print,pxweb_data_comment) 12 | S3method(print,pxweb_data_comments) 13 | S3method(print,pxweb_database_list) 14 | S3method(print,pxweb_levels) 15 | S3method(print,pxweb_metadata) 16 | S3method(print,pxweb_query) 17 | S3method(pxweb_api_catalogue_entry,list) 18 | S3method(pxweb_as_data_frame,pxweb_data) 19 | S3method(pxweb_as_data_frame,pxweb_data_comment) 20 | S3method(pxweb_as_data_frame,pxweb_data_comments) 21 | S3method(pxweb_as_data_frame,pxweb_levels) 22 | S3method(pxweb_data_comments,pxweb_data) 23 | S3method(pxweb_query,character) 24 | S3method(pxweb_query,json) 25 | S3method(pxweb_query,list) 26 | S3method(pxweb_query,pxweb_explorer) 27 | S3method(pxweb_query,pxweb_query) 28 | S3method(pxweb_query,response) 29 | export(api_catalogue) 30 | export(api_parameters) 31 | export(base_url) 32 | export(checkForLevels) 33 | export(get_pxweb_data) 34 | export(get_pxweb_dims) 35 | export(get_pxweb_levels) 36 | export(get_pxweb_metadata) 37 | export(interactive_pxweb) 38 | export(is.pxweb) 39 | export(is_pxweb_response) 40 | export(pxweb) 41 | export(pxweb_advanced_get) 42 | export(pxweb_api) 43 | export(pxweb_api_catalogue) 44 | export(pxweb_api_catalogue_path) 45 | export(pxweb_as_data_frame) 46 | export(pxweb_cite) 47 | export(pxweb_data_comments) 48 | export(pxweb_get) 49 | export(pxweb_get_data) 50 | export(pxweb_interactive) 51 | export(pxweb_parse_response) 52 | export(pxweb_query) 53 | export(pxweb_query_as_json) 54 | export(pxweb_query_as_rcode) 55 | export(pxweb_test_api) 56 | export(pxweb_validate_query_with_metadata) 57 | export(update_pxweb_apis) 58 | -------------------------------------------------------------------------------- /man/api_catalogue.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/defunct_functions.R 3 | \docType{data} 4 | \name{api_catalogue} 5 | \alias{api_catalogue} 6 | \alias{update_pxweb_apis} 7 | \alias{api_parameters} 8 | \alias{base_url} 9 | \alias{get_pxweb_data} 10 | \alias{get_pxweb_dims} 11 | \alias{get_pxweb_levels} 12 | \alias{get_pxweb_metadata} 13 | \alias{pxweb_api} 14 | \alias{checkForLevels} 15 | \title{Defunct functions} 16 | \format{ 17 | An object of class \code{list} of length 1. 18 | } 19 | \usage{ 20 | api_catalogue() 21 | 22 | update_pxweb_apis() 23 | 24 | api_parameters(url = NULL) 25 | 26 | base_url(api, version = NULL, language = NULL) 27 | 28 | get_pxweb_data(url, dims, clean = FALSE, encoding = NULL) 29 | 30 | get_pxweb_dims(node, verbose = TRUE) 31 | 32 | get_pxweb_levels(baseURL, descriptions = FALSE, quiet = FALSE, ...) 33 | 34 | get_pxweb_metadata( 35 | path = NULL, 36 | node = NULL, 37 | topnodes = NULL, 38 | quiet = TRUE, 39 | baseURL = NULL, 40 | ... 41 | ) 42 | 43 | pxweb_api 44 | 45 | checkForLevels(url) 46 | } 47 | \arguments{ 48 | \item{url}{Defunct argument.} 49 | 50 | \item{api}{Defunct argument.} 51 | 52 | \item{version}{Defunct argument.} 53 | 54 | \item{language}{Defunct argument.} 55 | 56 | \item{dims}{Defunct argument.} 57 | 58 | \item{clean}{Defunct argument.} 59 | 60 | \item{encoding}{Defunct argument.} 61 | 62 | \item{node}{Defunct argument.} 63 | 64 | \item{verbose}{Defunct argument.} 65 | 66 | \item{baseURL}{Defunct argument.} 67 | 68 | \item{descriptions}{Defunct argument.} 69 | 70 | \item{quiet}{Defunct argument.} 71 | 72 | \item{...}{Defunct argument.} 73 | 74 | \item{path}{Defunct argument.} 75 | 76 | \item{topnodes}{Defunct argument.} 77 | } 78 | \description{ 79 | These function has as from version 0.10.0 become defunct. 80 | Call the functions to get information on new functions to use. 81 | } 82 | \keyword{datasets} 83 | -------------------------------------------------------------------------------- /man/pxweb_explorer.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_interactive.R 3 | \name{pxweb_explorer} 4 | \alias{pxweb_explorer} 5 | \alias{pxweb_explorer.NULL} 6 | \alias{pxweb_explorer.character} 7 | \alias{pxweb_explorer.pxweb} 8 | \alias{pxweb_explorer.pxweb_api_catalogue_entry} 9 | \alias{assert_pxweb_explorer} 10 | \alias{print.pxweb_explorer} 11 | \alias{print_bar} 12 | \alias{pxe_print_choices} 13 | \title{Create a \code{pxweb_explorer} object.} 14 | \usage{ 15 | pxweb_explorer(x = NULL) 16 | 17 | \method{pxweb_explorer}{`NULL`}(x) 18 | 19 | \method{pxweb_explorer}{character}(x) 20 | 21 | \method{pxweb_explorer}{pxweb}(x) 22 | 23 | \method{pxweb_explorer}{pxweb_api_catalogue_entry}(x) 24 | 25 | assert_pxweb_explorer(x) 26 | 27 | \method{print}{pxweb_explorer}(x, ...) 28 | 29 | print_bar() 30 | 31 | pxe_print_choices(x) 32 | } 33 | \arguments{ 34 | \item{x}{a \code{pxweb} object, a PXWEB url, \code{NULL} or an api in the api catalogue.} 35 | } 36 | \description{ 37 | \code{position} the current position in the api, as a character vector from the root. 38 | Note position is not alway a correct url. Metadata and other choices are part of position 39 | 40 | \code{root} is the bottom path (as position) that the user can go. If length 0, user can essentially go to hostname. 41 | 42 | paste(root_path + position, collapse = "/") is used to construct the path to the position 43 | in case of url. 44 | 45 | print out a bar for separation purposes 46 | } 47 | \examples{ 48 | ## The functions below are internal generic functions 49 | ## x <- pxweb_explorer() 50 | ## url <- "api.scb.se" 51 | ## x <- pxweb_explorer(x = url) 52 | ## url <- "https://api.scb.se/OV0104/v1/doris/en/ssd/BE/BE0101/BE0101A/" 53 | ## x <- pxweb_explorer(x = url) 54 | ## url <- "https://api.scb.se/OV0104/v1/doris/en/ssd/BE/BE0101/BE0101A/BefolkningNy" 55 | ## x <- pxweb_explorer(x = url) 56 | 57 | } 58 | \keyword{internal} 59 | -------------------------------------------------------------------------------- /R/pxweb_parse_response.R: -------------------------------------------------------------------------------- 1 | #' Parse the response from a PXWEB API (advanced) 2 | #' 3 | #' @description 4 | #' The function parses the response from a call made to a PXWEB API 5 | #' using the \code{httr} R package. In this way it is possible to parse the 6 | #' content of calls made outside the pxweb R package. 7 | #' 8 | #' @param x a \code{httr} response object from a PXWEB call. 9 | #' 10 | #' @export 11 | pxweb_parse_response <- function(x) { 12 | checkmate::assert_class(x, "response") 13 | 14 | pxq <- pxweb_query(x) 15 | if (is.null(pxq) || pxq$response %in% c("json", "json-stat")) { 16 | obj <- suppressWarnings(httr::content(x, as = "parsed")) 17 | } else if (pxq$response %in% pxweb_file_response_formats()) { 18 | obj <- suppressWarnings(httr::content(x, as = "raw")) 19 | obj_path <- file.path(tempdir(), paste0(digest::sha1(obj), ".", pxq$response)) 20 | writeBin(con = obj_path, object = obj) 21 | return(obj_path) 22 | } 23 | 24 | try_obj <- try(pxweb_database_list(obj), silent = TRUE) 25 | if (!inherits(try_obj, "try-error")) { 26 | try_obj <- as_pxweb_levels(try_obj) 27 | return(try_obj) 28 | } 29 | 30 | try_obj <- try(pxweb_levels(obj), silent = TRUE) 31 | if (!inherits(try_obj, "try-error")) { 32 | return(try_obj) 33 | } 34 | 35 | try_obj <- try(pxweb_metadata(obj), silent = TRUE) 36 | if (!inherits(try_obj, "try-error")) { 37 | return(try_obj) 38 | } 39 | 40 | try_obj <- try(pxweb_data(x = obj), silent = TRUE) 41 | if (!inherits(try_obj, "try-error")) { 42 | return(try_obj) 43 | } 44 | 45 | try_obj <- try(pxweb_data_jsonstat(x = obj), silent = TRUE) 46 | if (!inherits(try_obj, "try-error")) { 47 | return(try_obj) 48 | } 49 | 50 | stop("Incorrect return response from PXWEB API url: \n", x$url, call. = FALSE) 51 | } 52 | 53 | 54 | #' @rdname pxweb_parse_response 55 | #' @export 56 | is_pxweb_response <- function(x) { 57 | !inherits(try(pxweb_parse_response(x), silent = TRUE), "try-error") 58 | } 59 | -------------------------------------------------------------------------------- /tests/testthat/test-pxweb_data_comments.R: -------------------------------------------------------------------------------- 1 | # Test suits for the examples in the documentation 2 | 3 | context("pxweb_data_comments") 4 | 5 | test_that(desc = "test data comment structure", { 6 | # CRAN seem to run tests in parallel, hence API tests cannot be run on CRAN. 7 | skip_on_cran() 8 | skip_if_offline() 9 | 10 | url <- "https://api.scb.se/OV0104/v1/doris/sv/ssd/BE/BE0101/BE0101A/BefolkningNy" 11 | json_query <- file.path(system.file(package = "pxweb"), "extdata", "examples", "json_query_example.json") 12 | expect_silent(px_data1 <- pxweb_get(url = url, query = json_query)) 13 | expect_silent(pxdcs <- pxweb_data_comments(x = px_data1)) 14 | expect_output(print(pxdcs), regexp = "pxweb_data_comments\\[\\[1\\]\\]") 15 | expect_equal(length(pxdcs$pxweb_data_comments), 1) 16 | expect_silent(pxdc_df <- as.data.frame(pxdcs, stringsAsFactors = TRUE)) 17 | expect_equal(dim(pxdc_df), c(1, 4)) 18 | expect_equal(unname(unlist(lapply(pxdc_df, class))), c("integer", "integer", "factor", "factor")) 19 | expect_silent(pxdc_df <- as.data.frame(pxdcs, stringsAsFactors = FALSE)) 20 | expect_equal(dim(pxdc_df), c(1, 4)) 21 | expect_equal(unname(unlist(lapply(pxdc_df, class))), c("integer", "integer", "character", "character")) 22 | 23 | 24 | url <- "https://api.scb.se/OV0104/v1/doris/sv/ssd/BE/BE0101/BE0101A/BefolkningNy" 25 | json_query <- file.path(system.file(package = "pxweb"), "extdata", "examples", "json_query_variables_example.json") 26 | expect_silent(px_data2 <- suppressWarnings(pxweb_get(url = url, query = json_query))) 27 | expect_silent(pxdcs <- pxweb_data_comments(x = px_data2)) 28 | expect_output(print(pxdcs), regexp = "NO PXWEB DATA COMMENTS") 29 | expect_equal(length(pxdcs$pxweb_data_comments), 0) 30 | expect_silent(pxdc_df <- as.data.frame(pxdcs, stringsAsFactors = FALSE)) 31 | expect_equal(dim(pxdc_df), c(0, 4)) 32 | expect_equal(colnames(pxdc_df), colnames(as.data.frame(pxweb_data_comments(x = px_data1)))) 33 | expect_equal(unname(unlist(lapply(pxdc_df, class))), c("integer", "integer", "character", "character")) 34 | }) 35 | -------------------------------------------------------------------------------- /R/pxweb_build_pxweb_urls.R: -------------------------------------------------------------------------------- 1 | #' Build the url to a PXWEB api 2 | #' 3 | #' @keywords internal 4 | #' 5 | build_pxweb_url <- function(x) { 6 | UseMethod("build_pxweb_url") 7 | } 8 | 9 | #' @rdname build_pxweb_url 10 | #' @keywords internal 11 | build_pxweb_url.list <- function(x) { 12 | assert_pxweb_url(x) 13 | build_pxweb_url(x$url) 14 | } 15 | 16 | #' @rdname build_pxweb_url 17 | #' @keywords internal 18 | build_pxweb_url.character <- function(x) { 19 | build_pxweb_url(httr::parse_url(x)) 20 | } 21 | 22 | #' @rdname build_pxweb_url 23 | #' @keywords internal 24 | build_pxweb_url.pxweb <- function(x) { 25 | build_pxweb_url(x$url) 26 | } 27 | 28 | #' @rdname build_pxweb_url 29 | #' @keywords internal 30 | build_pxweb_url.pxweb_api_catalogue_entry <- function(x) { 31 | base_url <- x$url 32 | base_url <- gsub("\\[version\\]", base_url, replacement = x$version[1]) 33 | base_url <- gsub("\\[lang\\]", base_url, replacement = x$lang[1]) 34 | build_pxweb_url(base_url) 35 | } 36 | 37 | #' @rdname build_pxweb_config_url 38 | #' @keywords internal 39 | build_pxweb_url.url <- function(x) { 40 | scheme <- x$scheme 41 | hostname <- x$hostname 42 | if (!is.null(x$port)) { 43 | port <- paste0(":", x$port) 44 | } else { 45 | port <- NULL 46 | } 47 | path <- paste(gsub("^/", "", x$path), collapse = "/") 48 | paste0(scheme, "://", hostname, port, "/", path) 49 | } 50 | 51 | 52 | #' Build the url to get the config from a PXWEB api 53 | #' 54 | #' @keywords internal 55 | #' 56 | build_pxweb_config_url <- function(x) { 57 | UseMethod("build_pxweb_config_url") 58 | } 59 | 60 | #' @rdname build_pxweb_config_url 61 | #' @keywords internal 62 | build_pxweb_config_url.list <- function(x) { 63 | assert_pxweb_url(x) 64 | build_pxweb_config_url(x$url) 65 | } 66 | 67 | #' @rdname build_pxweb_config_url 68 | #' @keywords internal 69 | build_pxweb_config_url.pxweb <- function(x) { 70 | build_pxweb_config_url(x$url) 71 | } 72 | 73 | #' @rdname build_pxweb_config_url 74 | #' @keywords internal 75 | build_pxweb_config_url.url <- function(x) { 76 | paste0(build_pxweb_url(x), "?config") 77 | } 78 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Type: Package 2 | Package: pxweb 3 | Title: R Interface to PXWEB APIs 4 | Version: 0.17.1 5 | Date: 2025-04-01 6 | Authors@R: c( 7 | person("Mans", "Magnusson", , "mons.magnusson@gmail.com", role = c("aut", "cre"), 8 | comment = c(ORCID = "0000-0002-0296-2719")), 9 | person("Markus", "Kainu", role = "aut"), 10 | person("Janne", "Huovari", role = "aut"), 11 | person("Leo", "Lahti", role = "aut", 12 | comment = c(ORCID = "0000-0001-5537-637X")), 13 | person("Love", "Hansson", role = "ctb"), 14 | person("Eydun", "Nielsen", role = "ctb"), 15 | person("Bo", "Werth", role = "ctb"), 16 | person("Thomas", "Runarsson", role = "ctb"), 17 | person("Torbjörn", "Lindquist", role = "ctb"), 18 | person("Palmar", "Thorsteinsson", role = "ctb"), 19 | person("Pyry", "Kantanen", role = "ctb"), 20 | person("Sebastian", "Ankargren", role = "ctb") 21 | ) 22 | Description: Generic interface for the PX-Web/PC-Axis API. The 23 | PX-Web/PC-Axis API is used by organizations such as Statistics Sweden 24 | and Statistics Finland to disseminate data. The R package can interact 25 | with all PX-Web/PC-Axis APIs to fetch information about the data 26 | hierarchy, extract metadata and extract and parse statistics to R 27 | data.frame format. PX-Web is a solution to disseminate PC-Axis data 28 | files in dynamic tables on the web. Since 2013 PX-Web contains an API 29 | to disseminate PC-Axis files. 30 | License: BSD_2_clause + file LICENSE 31 | URL: https://github.com/rOpenGov/pxweb/, 32 | https://ropengov.github.io/pxweb/, https://github.com/rOpenGov/pxweb 33 | BugReports: https://github.com/rOpenGov/pxweb/issues 34 | Depends: 35 | R (>= 3.5.0) 36 | Imports: 37 | checkmate, 38 | curl, 39 | httr (>= 1.1), 40 | jsonlite 41 | Suggests: 42 | digest, 43 | httptest, 44 | knitr, 45 | remotes, 46 | rmarkdown, 47 | testthat (>= 0.11), 48 | xml2 49 | VignetteBuilder: 50 | knitr 51 | Encoding: UTF-8 52 | RoxygenNote: 7.3.2 53 | X-schema.org-isPartOf: http://ropengov.org/ 54 | X-schema.org-keywords: ropengov 55 | -------------------------------------------------------------------------------- /paper/codesnippet.tex: -------------------------------------------------------------------------------- 1 | \documentclass[codesnippet]{jss} 2 | 3 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4 | %% declarations for jss.cls %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6 | 7 | %% almost as usual 8 | \author{Achim Zeileis\\Universit\"at Innsbruck \And 9 | Second Author\\Plus Affiliation} 10 | \title{A Capitalized Title: Possibly Containing More Details} 11 | 12 | %% for pretty printing and a nice hypersummary also set: 13 | \Plainauthor{Achim Zeileis, Second Author} %% comma-separated 14 | \Plaintitle{A Capitalized Title: Possibly Containing More Details} %% without formatting 15 | \Shorttitle{A Capitalized Title} %% a short title (if necessary) 16 | 17 | %% an abstract and keywords 18 | \Abstract{ 19 | Here should be the abstract. 20 | } 21 | \Keywords{keywords, comma-separated, not capitalized, \proglang{Java}} 22 | \Plainkeywords{keywords, comma-separated, not capitalized, Java} %% without formatting 23 | %% at least one keyword must be supplied 24 | 25 | %% publication information 26 | %% NOTE: Typically, this can be left commented and will be filled out by the technical editor 27 | %% \Volume{50} 28 | %% \Issue{9} 29 | %% \Month{June} 30 | %% \Year{2012} 31 | %% \Submitdate{2012-06-04} 32 | %% \Acceptdate{2012-06-04} 33 | 34 | %% The address of (at least) one author should be given 35 | %% in the following format: 36 | \Address{ 37 | Achim Zeileis\\ 38 | Department of Statistics and Mathematics\\ 39 | Faculty of Economics and Statistics\\ 40 | Universit\"at Innsbruck\\ 41 | 6020 Innsbruck, Austria\\ 42 | E-mail: \email{Achim.Zeileis@uibk.ac.at}\\ 43 | URL: \url{http://eeecon.uibk.ac.at/~zeileis/} 44 | } 45 | %% It is also possible to add a telephone and fax number 46 | %% before the e-mail in the following format: 47 | %% Telephone: +43/512/507-7103 48 | %% Fax: +43/512/507-2851 49 | 50 | %% for those who use Sweave please include the following line (with % symbols): 51 | %% need no \usepackage{Sweave.sty} 52 | 53 | %% end of declarations %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 54 | 55 | 56 | \begin{document} 57 | 58 | %% include your article here, just as usual 59 | %% Note that you should use the \pkg{}, \proglang{} and \code{} commands. 60 | 61 | \section[About Java]{About \proglang{Java}} 62 | %% Note: If there is markup in \(sub)section, then it has to be escape as above. 63 | 64 | 65 | \end{document} -------------------------------------------------------------------------------- /man/pxweb_get.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_get.R 3 | \name{pxweb_get} 4 | \alias{pxweb_get} 5 | \title{Do a GET call to PXWEB API} 6 | \usage{ 7 | pxweb_get(url, query = NULL, verbose = TRUE) 8 | } 9 | \arguments{ 10 | \item{url}{a \code{pxweb} object or url that can be coherced to a \code{pxweb} object.} 11 | 12 | \item{query}{a json string, json file or list object that can be coherced to a \code{pxweb_query} object.} 13 | 14 | \item{verbose}{should large queries print out progress.} 15 | } 16 | \description{ 17 | Do a GET call to PXWEB API 18 | } 19 | \examples{ 20 | \dontrun{ 21 | url <- "https://api.scb.se/OV0104/v1/doris/sv/ssd/BE/BE0101/BE0101A/BefolkningNy" 22 | px_meta_data <- pxweb_get(url) 23 | 24 | url <- "https://api.scb.se/OV0104/v1/doris/sv/ssd/BE/BE0101" 25 | px_levels <- pxweb_get(url) 26 | 27 | url <- "https://api.scb.se/OV0104/v1/doris/sv" 28 | px_levels <- pxweb_get(url) 29 | 30 | url <- "https://api.scb.se/OV0104/v1/doris/sv/ssd/BE/BE0101/BE0101A/BefolkningNy" 31 | query <- file.path( 32 | system.file(package = "pxweb"), 33 | "extdata", "examples", "json_query_example.json" 34 | ) 35 | px_data <- pxweb_get(url = url, query = query) 36 | 37 | # Convert to data.frame 38 | as.data.frame(px_data, column.name.type = "text", variable.value.type = "text") 39 | 40 | # Get raw data 41 | as.matrix(px_data, column.name.type = "code", variable.value.type = "code") 42 | 43 | # Get data comments 44 | pxweb_data_comments(px_data) 45 | 46 | # Get jsonstat data 47 | jstat <- query <- file.path( 48 | system.file(package = "pxweb"), 49 | "extdata", "examples", "json-stat_query_example.json" 50 | ) 51 | jstat_data <- pxweb_get(url = url, query = query) 52 | 53 | # Get very large datasets (multiple downloads needed) 54 | big_query <- file.path( 55 | system.file(package = "pxweb"), 56 | "extdata", "examples", "json_big_query_example.json" 57 | ) 58 | px_data <- pxweb_get(url = url, query = big_query) 59 | 60 | # Get json-stat2 data from statfin using downloaded json query 61 | jstat2_url <- "https://pxdata.stat.fi:443/PxWeb/api/v1/fi/StatFin/eot/statfin_eot_pxt_132a.px" 62 | jstat2_query <- file.path( 63 | system.file(package = "pxweb"), 64 | "extdata", "examples", "sq-api_table_statfin_eot_pxt_132a.px.json" 65 | ) 66 | jstat2_data <- pxweb_get(url = jstat2_url, query = jstat2_query) 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /R/defunct_functions.R: -------------------------------------------------------------------------------- 1 | #' Defunct functions 2 | #' 3 | #' @description 4 | #' These function has as from version 0.10.0 become defunct. 5 | #' Call the functions to get information on new functions to use. 6 | #' 7 | #' @param url Defunct argument. 8 | #' @param ... Defunct argument. 9 | #' @param api Defunct argument. 10 | #' @param version Defunct argument. 11 | #' @param language Defunct argument. 12 | #' @param dims Defunct argument. 13 | #' @param clean Defunct argument. 14 | #' @param encoding Defunct argument. 15 | #' @param node Defunct argument. 16 | #' @param verbose Defunct argument. 17 | #' @param baseURL Defunct argument. 18 | #' @param descriptions Defunct argument. 19 | #' @param quiet Defunct argument. 20 | #' @param path Defunct argument. 21 | #' @param topnodes Defunct argument. 22 | #' 23 | #' @export 24 | api_catalogue <- function() { 25 | .Defunct("pxweb_api_catalogue") 26 | } 27 | 28 | #' @rdname api_catalogue 29 | #' @export 30 | update_pxweb_apis <- function() { 31 | .Defunct(msg = "update_pxweb_apis() is no longer allowed by CRAN. See vignette(\"pxweb\") on how to update your API catalogue.") 32 | } 33 | 34 | #' @rdname api_catalogue 35 | #' @export 36 | api_parameters <- function(url = NULL) { 37 | .Defunct(new = "pxweb_api_catalogue") 38 | } 39 | 40 | 41 | #' @rdname api_catalogue 42 | #' @export 43 | base_url <- function(api, version = NULL, language = NULL) { 44 | .Defunct("pxweb") 45 | } 46 | 47 | #' @rdname api_catalogue 48 | #' @export 49 | get_pxweb_data <- function(url, dims, clean = FALSE, encoding = NULL) { 50 | .Defunct("pxweb_get_data") 51 | } 52 | 53 | #' @rdname api_catalogue 54 | #' @export 55 | get_pxweb_dims <- function(node, verbose = TRUE) { 56 | .Defunct("pxweb_advanced_get") 57 | } 58 | 59 | #' @rdname api_catalogue 60 | #' @export 61 | get_pxweb_levels <- function(baseURL, descriptions = FALSE, quiet = FALSE, ...) { 62 | .Defunct("pxweb_get") 63 | } 64 | 65 | #' @rdname api_catalogue 66 | #' @export 67 | get_pxweb_metadata <- function(path = NULL, node = NULL, topnodes = NULL, quiet = TRUE, baseURL = NULL, ...) { 68 | .Defunct("pxweb_get") 69 | } 70 | 71 | #' @rdname api_catalogue 72 | #' @export pxweb_api 73 | pxweb_api <- list(new = function() { 74 | .Defunct(msg = "'pxweb_api' class is defunct. \nUse 'pxweb' instead.\nSee help(\"Defunct\") ") 75 | }) 76 | 77 | #' @rdname api_catalogue 78 | #' @export 79 | checkForLevels <- function(url) { 80 | .Defunct() 81 | } 82 | -------------------------------------------------------------------------------- /R/pxweb_c.R: -------------------------------------------------------------------------------- 1 | #' Combine pxweb objects 2 | #' 3 | #' @param x a list with \code{pxweb} objects. 4 | #' 5 | #' @keywords internal 6 | pxweb_c <- function(x) { 7 | checkmate::assert_class(x, "list") 8 | if (length(x) == 1) { 9 | return(x[[1]]) 10 | } 11 | 12 | if (inherits(x[[1]], "pxweb_data")) { 13 | return(pxweb_data_c(x)) 14 | } 15 | 16 | if (inherits(x[[1]], "json")) { 17 | return(x) 18 | } 19 | 20 | if (inherits(x[[1]], "character")) { 21 | fp <- unlist(x) 22 | fe <- file.exists(fp) 23 | if (all(fe)) { 24 | message("PXWEB API did not return JSON. Files has been stored locally (tempdir) and paths has been returned.") 25 | return(x) 26 | } else { 27 | stop("Files doesn't exist:\n", paste(fp[!fe], collapse = "\n"), call. = FALSE) 28 | } 29 | } 30 | 31 | stop("pxweb_c() not implemented for class '", class(x[[1]])[1], "'.", call. = FALSE) 32 | } 33 | 34 | 35 | #' Combine pxweb objects 36 | #' 37 | #' @param x a list with \code{pxweb} objects. 38 | #' 39 | #' @keywords internal 40 | pxweb_data_c <- function(x) { 41 | for (i in seq_along(x)) { 42 | checkmate::assert_class(x[[i]], "pxweb_data") 43 | } 44 | full_pxd <- x[[1]] 45 | 46 | # Assert equal columns 47 | for (i in 2:length(x)) { 48 | for (j in seq_along(full_pxd$columns)) { 49 | checkmate::assert_set_equal(full_pxd$columns[[j]]$code, x[[i]]$columns[[j]]$code) 50 | checkmate::assert_set_equal(full_pxd$columns[[j]]$text, x[[i]]$columns[[j]]$text) 51 | checkmate::assert_set_equal(full_pxd$columns[[j]]$type, x[[i]]$columns[[j]]$type) 52 | } 53 | } 54 | 55 | # Add comments if not duplicated 56 | json_comments <- character(length(full_pxd$comments)) 57 | for (i in seq_along(full_pxd$comments)) { 58 | json_comments[i] <- jsonlite::toJSON(full_pxd$comments[[i]]) 59 | } 60 | for (i in 2:length(x)) { 61 | for (j in seq_along(x[[i]]$comments)) { 62 | json_new_comment <- jsonlite::toJSON(x[[i]]$comments[[j]]) 63 | if (!(json_new_comment %in% json_comments)) json_comments <- c(json_comments, json_new_comment) 64 | } 65 | } 66 | full_pxd$comments <- list() 67 | for (i in seq_along(json_comments)) { 68 | full_pxd$comments[[i]] <- jsonlite::fromJSON(json_comments[i]) 69 | } 70 | 71 | # Combine data 72 | for (i in 2:length(x)) { 73 | full_pxd$data <- c(full_pxd$data, x[[i]]$data) 74 | } 75 | 76 | checkmate::assert_class(full_pxd, "pxweb_data") 77 | full_pxd 78 | } 79 | -------------------------------------------------------------------------------- /R/pxweb_logs.R: -------------------------------------------------------------------------------- 1 | #' Setup a structure to log all API calls 2 | #' @details 3 | #' Set up internal structure to handle http PXWEB API calls. http calls are stored in a log file. 4 | #' To access the path to this log file, the path is stored in the pxweb folder in the tempdir(). 5 | #' The path is given by \code{pxweb_log_paths_path()}. 6 | #' If the file exists, the http calls should be logged (appended) to the log file where the object contains the path. 7 | #' 8 | #' @param fn The file name of the log file. 9 | #' @keywords internal 10 | pxweb_http_log_on <- function(fn = "log_pxweb_api_http_calls.txt") { 11 | checkmate::assert_string(fn) 12 | log_file_path <- file.path(getwd(), fn) 13 | internal_path <- pxweb_log_paths_path() 14 | checkmate::assert_path_for_output(log_file_path, overwrite = TRUE) 15 | if (file.exists(log_file_path)) { 16 | file.remove(log_file_path) 17 | } 18 | write(paste0("PXWEB API HTTP LOG ", Sys.time(), ":"), file = log_file_path) 19 | if (file.exists(internal_path)) { 20 | file.remove(internal_path) 21 | } 22 | save(log_file_path, file = internal_path) 23 | } 24 | 25 | #' @keywords internal 26 | #' @rdname pxweb_http_log_on 27 | pxweb_http_log_off <- function() { 28 | lp <- pxweb_log_paths_path() 29 | if (file.exists(lp)) { 30 | file.remove(lp) 31 | } 32 | } 33 | 34 | #' @keywords internal 35 | #' @rdname pxweb_http_log_on 36 | pxweb_log_paths_path <- function() { 37 | file.path(pxweb_tempdir(to = "logs"), "log_http_calls.rda") 38 | } 39 | 40 | 41 | #' @keywords internal 42 | #' @rdname pxweb_http_log_on 43 | pxweb_http_log_is_on <- function() { 44 | lpp <- pxweb_log_paths_path() 45 | file.exists(lpp) 46 | } 47 | 48 | #' @keywords internal 49 | #' @rdname pxweb_http_log_on 50 | pxweb_http_log_response <- function(r) { 51 | checkmate::assert_class(r, "response") 52 | if (!pxweb_http_log_is_on()) { 53 | return(invisible(NULL)) 54 | } 55 | log_file_path <- NULL # Load the file path next 56 | load(pxweb_log_paths_path()) 57 | 58 | txt <- pxweb_response_to_log_as_json(r) 59 | write(c(paste0("\n\nCALL AND RESPONSE FROM PXWEB API ", Sys.time(), ": "), txt), append = TRUE, file = log_file_path) 60 | return(invisible(NULL)) 61 | } 62 | 63 | #' @keywords internal 64 | #' @rdname pxweb_http_log_on 65 | pxweb_response_to_log_as_json <- function(r) { 66 | checkmate::assert_class(r, "response") 67 | txt <- unclass(r) 68 | txt$content <- "The content is removed to limit log file size." 69 | txt$request <- unclass(txt$request) 70 | txt$request$output <- unclass(txt$request$output) 71 | txt$handle <- NULL 72 | jsonlite::toJSON(txt, pretty = TRUE, auto_unbox = TRUE) 73 | } 74 | -------------------------------------------------------------------------------- /R/pxweb_assert.R: -------------------------------------------------------------------------------- 1 | #' Assert that the url structure is correct 2 | #' 3 | #' @description 4 | #' Assert that the \code{url} slot in the \code{pxweb} object is correct. 5 | #' 6 | #' @param x a object to assert 7 | #' @keywords internal 8 | assert_pxweb <- function(x) { 9 | checkmate::assert_class(x, c("pxweb", "list")) 10 | assert_pxweb_url(x) 11 | assert_pxweb_rda_file_path(x) 12 | assert_pxweb_calls(x) 13 | assert_pxweb_config(x) 14 | } 15 | 16 | #' Assert that the url structure is correct 17 | #' 18 | #' @description 19 | #' Assert that the \code{url} slot in the \code{pxweb} object is correct. 20 | #' 21 | #' @param x a object to assert 22 | #' @keywords internal 23 | assert_pxweb_url <- function(x) { 24 | checkmate::assert_class(x, "list") 25 | checkmate::assert_names(names(x), must.include = "url") 26 | checkmate::assert_class(x$url, "url") 27 | checkmate::assert_false(is.null(x$url$hostname)) 28 | checkmate::assert_false(is.null(x$url$scheme)) 29 | checkmate::assert_false(is.null(x$url$path)) 30 | } 31 | 32 | 33 | #' Assert that the rda_file_path is correct 34 | #' 35 | #' @description 36 | #' Assert that the \code{rda_file_path} slot in the \code{pxweb} object is correct. 37 | #' 38 | #' @param x a object to assert 39 | #' @keywords internal 40 | assert_pxweb_rda_file_path <- function(x) { 41 | checkmate::assert_class(x, "list") 42 | checkmate::assert_names(names(x), must.include = "paths") 43 | checkmate::assert_false(is.null(x$paths$rda_file_path)) 44 | checkmate::assert_path_for_output(x$paths$rda_file_path, overwrite = TRUE) 45 | } 46 | 47 | 48 | #' Assert that the rda_file_path is correct 49 | #' 50 | #' @description 51 | #' Assert that the \code{rda_file_path} slot in the \code{pxweb} object is correct. 52 | #' 53 | #' @param x a object to assert 54 | #' @keywords internal 55 | assert_pxweb_calls <- function(x) { 56 | checkmate::assert_class(x, "list") 57 | checkmate::assert_names(names(x), must.include = "calls") 58 | checkmate::assert_false(is.null(x$calls$time_stamps)) 59 | checkmate::assert_class(x$calls$time_stamps, "list") 60 | if (length(x$calls$time_stamps) > 0) { 61 | for (i in seq_along(x$calls$time_stamps)) { 62 | checkmate::assert_class(x$calls$time_stamps[[i]], "POSIXct") 63 | } 64 | } 65 | } 66 | 67 | 68 | #' Assert that the config slot is correct 69 | #' 70 | #' @description 71 | #' Assert that the \code{config} slot in the \code{pxweb} object is correct. 72 | #' 73 | #' @param x a object to assert 74 | #' @keywords internal 75 | assert_pxweb_config <- function(x) { 76 | checkmate::assert_class(x, "list") 77 | checkmate::assert_names(names(x), must.include = "config") 78 | checkmate::assert_names(names(x$config), must.include = c("calls_per_period", "period_in_seconds", "max_values_to_download")) 79 | checkmate::assert_int(x$config$calls_per_period, lower = 1, null.ok = FALSE, na.ok = FALSE) 80 | checkmate::assert_int(x$config$period_in_seconds, lower = 1, null.ok = FALSE, na.ok = FALSE) 81 | checkmate::assert_int(x$config$max_values_to_download, lower = 1, null.ok = FALSE, na.ok = FALSE) 82 | } 83 | -------------------------------------------------------------------------------- /tests/testthat/test-pxweb_as_dataframe.R: -------------------------------------------------------------------------------- 1 | # Test suits for the examples in the documentation 2 | 3 | context("pxweb_as_dataframe") 4 | 5 | test_that(desc = "Converting pxweb data to matrices and data.frames", { 6 | # CRAN seem to run tests in parallel, hence API tests cannot be run on CRAN. 7 | skip_on_cran() 8 | skip_if_offline() 9 | 10 | # Move to 11 | url <- "https://api.scb.se/OV0104/v1/doris/sv/ssd/BE/BE0101/BE0101A/BefolkningNy" 12 | json_query <- file.path(system.file(package = "pxweb"), "extdata", "examples", "json_query_variables_example.json") 13 | # save(px_data, file = "px_data_example.rda") 14 | # load("px_data_example.rda") 15 | expect_silent(pxq <- pxweb_query(json_query)) 16 | expect_silent(px_data <- suppressWarnings(pxweb_get(url = url, query = json_query))) 17 | expect_silent(px_metadata <- suppressWarnings(pxweb_get(url = url))) 18 | 19 | expect_error(df <- as.data.frame(px_metadata), regexp = "pxweb_metadata") 20 | 21 | expect_silent(df <- as.data.frame(px_data, stringsAsFactors = TRUE, column.name.type = "text", variable.value.type = "text")) 22 | expect_s3_class(df, "data.frame") 23 | expect_equal(dim(df), expected = c(12, 3)) 24 | expect_true(any(unlist(lapply(df, class)) == "factor")) 25 | expect_equal(colnames(df), expected = c("civilstånd", "år", "Folkmängd")) 26 | 27 | expect_silent(df <- as.data.frame(px_data, stringsAsFactors = FALSE, column.name.type = "text", variable.value.type = "text")) 28 | expect_s3_class(df, "data.frame") 29 | expect_equal(dim(df), expected = c(12, 3)) 30 | expect_false(any(unlist(lapply(df, class)) == "factor")) 31 | expect_equal(colnames(df), expected = c("civilstånd", "år", "Folkmängd")) 32 | 33 | expect_silent(df <- as.data.frame(x = px_data, stringsAsFactors = FALSE, column.name.type = "code", variable.value.type = "text")) 34 | expect_s3_class(df, "data.frame") 35 | expect_equal(colnames(df), expected = c("Civilstand", "Tid", "BE0101N1")) 36 | expect_true(all(df$Civilstand %in% c("ogifta", "gifta", "skilda", "änkor/änklingar"))) 37 | 38 | expect_silent(df <- as.data.frame(px_data, stringsAsFactors = FALSE, column.name.type = "code", variable.value.type = "code", row.names = as.character(1001:1012))) 39 | expect_s3_class(df, "data.frame") 40 | expect_true(all(df$Civilstand %in% c("OG", "G", "SK", "ÄNKL"))) 41 | expect_equal(rownames(df), as.character(1001:1012)) 42 | 43 | # Test as.matrix 44 | expect_silent(mat <- as.matrix.pxweb_data(x = px_data, column.name.type = "text", variable.value.type = "text")) 45 | expect_true(is.matrix(mat)) 46 | expect_true(is.character(mat)) 47 | expect_equal(dim(mat), expected = c(12, 3)) 48 | expect_equal(colnames(mat), expected = c("civilstånd", "år", "Folkmängd")) 49 | expect_true(all(mat[, 1] %in% c("ogifta", "gifta", "skilda", "änkor/änklingar"))) 50 | 51 | expect_silent(mat <- as.matrix(px_data, column.name.type = "code", variable.value.type = "code")) 52 | expect_true(is.matrix(mat)) 53 | expect_true(is.character(mat)) 54 | expect_equal(dim(mat), expected = c(12, 3)) 55 | expect_equal(colnames(mat), expected = c("Civilstand", "Tid", "BE0101N1")) 56 | expect_true(all(mat[, 1] %in% c("OG", "G", "SK", "ÄNKL"))) 57 | }) 58 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at . All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /man/pxweb_as_data_frame.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_as_data_frame.R 3 | \name{pxweb_as_data_frame} 4 | \alias{pxweb_as_data_frame} 5 | \alias{pxweb_as_data_frame.pxweb_data} 6 | \alias{pxweb_as_data_frame.pxweb_data_comments} 7 | \alias{pxweb_as_data_frame.pxweb_data_comment} 8 | \alias{pxweb_as_data_frame.pxweb_levels} 9 | \alias{as.data.frame.pxweb_data} 10 | \alias{as.data.frame.pxweb_data_comments} 11 | \alias{as.data.frame.pxweb_levels} 12 | \alias{as.data.frame.pxweb_metadata} 13 | \alias{pxweb_as_matrix} 14 | \alias{pxweb_as_matrix.pxweb_data} 15 | \alias{as.matrix.pxweb_data} 16 | \alias{pxweb_pxd_slot_idx_pos} 17 | \title{Coerce a \code{pxweb_data} object to a \code{data.frame}} 18 | \usage{ 19 | pxweb_as_data_frame( 20 | x, 21 | row.names = NULL, 22 | optional = FALSE, 23 | ..., 24 | stringsAsFactors = FALSE, 25 | column.name.type = "text", 26 | variable.value.type = "text" 27 | ) 28 | 29 | \method{pxweb_as_data_frame}{pxweb_data}( 30 | x, 31 | row.names = NULL, 32 | optional = FALSE, 33 | ..., 34 | stringsAsFactors = FALSE, 35 | column.name.type = "text", 36 | variable.value.type = "text" 37 | ) 38 | 39 | \method{pxweb_as_data_frame}{pxweb_data_comments}( 40 | x, 41 | row.names = NULL, 42 | optional = FALSE, 43 | ..., 44 | stringsAsFactors = FALSE 45 | ) 46 | 47 | \method{pxweb_as_data_frame}{pxweb_data_comment}( 48 | x, 49 | row.names = NULL, 50 | optional = FALSE, 51 | ..., 52 | stringsAsFactors = FALSE 53 | ) 54 | 55 | \method{pxweb_as_data_frame}{pxweb_levels}( 56 | x, 57 | row.names = NULL, 58 | optional = FALSE, 59 | ..., 60 | stringsAsFactors = FALSE 61 | ) 62 | 63 | \method{as.data.frame}{pxweb_data}( 64 | x, 65 | row.names = NULL, 66 | optional = FALSE, 67 | ..., 68 | stringsAsFactors = FALSE, 69 | column.name.type = "text", 70 | variable.value.type = "text" 71 | ) 72 | 73 | \method{as.data.frame}{pxweb_data_comments}( 74 | x, 75 | row.names = NULL, 76 | optional = FALSE, 77 | ..., 78 | stringsAsFactors = FALSE 79 | ) 80 | 81 | \method{as.data.frame}{pxweb_levels}( 82 | x, 83 | row.names = NULL, 84 | optional = FALSE, 85 | ..., 86 | stringsAsFactors = FALSE 87 | ) 88 | 89 | \method{as.data.frame}{pxweb_metadata}( 90 | x, 91 | row.names = NULL, 92 | optional = FALSE, 93 | ..., 94 | stringsAsFactors = FALSE 95 | ) 96 | 97 | pxweb_as_matrix( 98 | x, 99 | row.names = NULL, 100 | column.name.type = "text", 101 | variable.value.type = "text" 102 | ) 103 | 104 | \method{pxweb_as_matrix}{pxweb_data}( 105 | x, 106 | row.names = NULL, 107 | column.name.type = "text", 108 | variable.value.type = "text" 109 | ) 110 | 111 | \method{as.matrix}{pxweb_data}( 112 | x, 113 | ..., 114 | row.names = NULL, 115 | column.name.type = "text", 116 | variable.value.type = "text" 117 | ) 118 | 119 | pxweb_pxd_slot_idx_pos(x) 120 | } 121 | \arguments{ 122 | \item{x}{an object to convert to \code{data.frame}.} 123 | 124 | \item{row.names}{See \code{\link[base]{as.data.frame}}.} 125 | 126 | \item{optional}{See \code{\link[base]{as.data.frame}}.} 127 | 128 | \item{...}{See \code{\link[base]{as.data.frame}}.} 129 | 130 | \item{stringsAsFactors}{See \code{\link[base]{as.data.frame}}.} 131 | 132 | \item{column.name.type}{character: should \code{code} or \code{text} be used as column names?} 133 | 134 | \item{variable.value.type}{character: should \code{code} or \code{text} be used as values in columns?} 135 | } 136 | \description{ 137 | Coerce a \code{pxweb_data} object to a \code{data.frame} 138 | } 139 | \seealso{ 140 | \code{\link[base]{as.data.frame}}. 141 | } 142 | \keyword{internal} 143 | -------------------------------------------------------------------------------- /man/pxweb_api_name.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pxweb_api_paths.R, R/pxweb_interactive.R 3 | \name{pxweb_api_name} 4 | \alias{pxweb_api_name} 5 | \alias{pxweb_api_name.url} 6 | \alias{pxweb_api_name.pxweb} 7 | \alias{pxweb_api_name.pxweb_api_catalogue_entry} 8 | \alias{pxweb_api_name.pxweb_explorer} 9 | \alias{pxweb_api_rootpath} 10 | \alias{pxweb_api_rootpath.url} 11 | \alias{pxweb_api_rootpath.pxweb} 12 | \alias{pxweb_api_rootpath.pxweb_explorer} 13 | \alias{pxweb_api_subpath} 14 | \alias{pxweb_api_subpath.pxweb} 15 | \alias{pxweb_api_subpath.pxweb_explorer} 16 | \alias{pxweb_api_path} 17 | \alias{pxweb_api_path.url} 18 | \alias{pxweb_api_path.pxweb} 19 | \alias{pxweb_api_path.pxweb_explorer} 20 | \alias{pxweb_api_dbpath} 21 | \alias{pxweb_api_dbpath.pxweb} 22 | \alias{assert_path} 23 | \alias{pxe_position_path} 24 | \alias{pxe_metadata_path} 25 | \title{Get the api name, rootpath, subpath, path or dbpath} 26 | \usage{ 27 | pxweb_api_name(x) 28 | 29 | \method{pxweb_api_name}{url}(x) 30 | 31 | \method{pxweb_api_name}{pxweb}(x) 32 | 33 | \method{pxweb_api_name}{pxweb_api_catalogue_entry}(x) 34 | 35 | \method{pxweb_api_name}{pxweb_explorer}(x) 36 | 37 | pxweb_api_rootpath(x) 38 | 39 | \method{pxweb_api_rootpath}{url}(x) 40 | 41 | \method{pxweb_api_rootpath}{pxweb}(x) 42 | 43 | \method{pxweb_api_rootpath}{pxweb_explorer}(x) 44 | 45 | pxweb_api_subpath(x, init_slash = TRUE, as_vector = FALSE) 46 | 47 | \method{pxweb_api_subpath}{pxweb}(x, init_slash = TRUE, as_vector = FALSE) 48 | 49 | \method{pxweb_api_subpath}{pxweb_explorer}(x, init_slash = TRUE, as_vector = FALSE) 50 | 51 | pxweb_api_path(x, init_slash = TRUE, as_vector = FALSE) 52 | 53 | \method{pxweb_api_path}{url}(x, init_slash = TRUE, as_vector = FALSE) 54 | 55 | \method{pxweb_api_path}{pxweb}(x, init_slash = TRUE, as_vector = FALSE) 56 | 57 | \method{pxweb_api_path}{pxweb_explorer}(x, init_slash = TRUE, as_vector = FALSE) 58 | 59 | pxweb_api_dbpath(x, init_slash = TRUE, as_vector = FALSE) 60 | 61 | \method{pxweb_api_dbpath}{pxweb}(x, init_slash = TRUE, as_vector = FALSE) 62 | 63 | \method{pxweb_api_path}{pxweb_explorer}(x, init_slash = TRUE, as_vector = FALSE) 64 | 65 | assert_path(x) 66 | 67 | pxe_position_path( 68 | x, 69 | init_slash = TRUE, 70 | as_vector = FALSE, 71 | include_rootpath = FALSE 72 | ) 73 | 74 | pxe_metadata_path(x, as_vector = FALSE) 75 | } 76 | \arguments{ 77 | \item{x}{object to get the name or path for} 78 | 79 | \item{init_slash}{should \code{subpath} and \code{path} start with a \code{/}. Default is \code{TRUE}.} 80 | 81 | \item{as_vector}{should \code{subpath} and \code{path} be a vector split by /. Default is \code{FALSE}.} 82 | 83 | \item{include_rootpath}{Should the rootpath be included? Default is FALSE} 84 | } 85 | \description{ 86 | Get the api name, rootpath, subpath, path or dbpath 87 | } 88 | \details{ 89 | The PXWEB API contain the following path: 90 | API-NAME/API-VERSION/LANGUAGE/DATABASE-ID//TABLE-ID 91 | 92 | The full url is made up by the \code{rootpath}, \code{subpath}, and \code{path}. 93 | The \code{rootpath} is made up of the protocol and the API-NAME / hostname and protocol (if any). 94 | 95 | The \code{subpath} contain the API-VERSION and LANGUAGE but can contain other parts as well. 96 | The subpath is the shortest the config can be called for. It can be seen as the base for the API. 97 | 98 | The \code{dbpath}, the data base path, contain DATABASE-ID//TABLE-ID. 99 | 100 | The \code{path}, is the standar path of an url, i.e. \code{subpath} + \code{dbpath}. 101 | 102 | No path ends with slash, but \code{subpath} and \code{dbpath} may begin with slash, 103 | see the parameters 104 | } 105 | \keyword{internal} 106 | -------------------------------------------------------------------------------- /inst/extras/old/TODO.md: -------------------------------------------------------------------------------- 1 | ## Advanced access (not tested yet - TODO) 2 | 3 | ### Exploring the top node of the API data tree 4 | Data in the SCB API is structured in a data tree. To explore the top node of the data tree, use `scbGetMetadata()`. Provided with no parameters, the function fetches metadata from the top node in the API: 5 | ```r 6 | topNode <- scbGetMetadata() 7 | View(topNode) 8 | ``` 9 | 10 | ### Traversing the node tree 11 | The node tree can be ascended by adding the id of the next subnode to the URL of the base URL. This id is stored in the "id" column of the topNode object created above. The example below goes down the node tree one level at the third position in the "id" column: 12 | 13 | ```r 14 | nextNode <- scbGetMetadata(topNode$id[3]) 15 | View(nextNode) 16 | ``` 17 | This can be repeated until we reach a node that references data instead of subnodes. Once you reach the bottom node, `scbGetMetadata` warns the user that the bottom node has been reached. 18 | 19 | Note that `scbGetMetadata` actually takes the name of a node as input parameter, so if you know the name of a subnode in the node tree or a bottom (data) node, you can supply this directly to the function instead of explorin the data tree as we did above. 20 | 21 | ### Getting data dimensions 22 | Next, we want to find the dimensions of the data at a particular bottom node, e.g. the node "KPIFastM" which is the bottom node in the following tree branch: 23 | 24 | PR -> PR0101 -> PR0301B -> HMPIM07 25 | 26 | The following code fetches dimensions for the variable `HMPIM07`: 27 | 28 | ```r 29 | bottomNode <- scbGetMetadata("HMPIM07") 30 | dims <- scbGetDims(bottomNode) 31 | ``` 32 | 33 | The first call, `scbGetMetadata("HMPIM07")`, returns a friendly message informing the user that this is a bottom node in the data tree. This call also provides us with a resulting object, `bottomNode`, which contains the URL to the node. We will recycle this when getting 'real' data from the database. 34 | 35 | The second call, `scbGetDims(bottomNode)` also prints out a friendly message stating that the dimensions for the data at this node are "ContentsCode" and "Tid". We can now either pass on a wildcard ("*") to these dimensions, or a value, or a range of values on vector form. 36 | 37 | To see what values are allowed for each dimension, have a look at the `dims` object using `print(dims)`. You will see that this is actually a list, and the values for each of the dimensions can be found by looking closer at each of the elements in the list by calling `dims[[n]]` where `n` is the number of the dimension you want to look at. 38 | 39 | ### Getting the data 40 | The information we got above, i.e. the URL to the data node and the dimensions required for the call, can now be used to construct a call to the API to fetch the actual data: 41 | ```r 42 | sdata <- scbGetData(bottomNode$URL, list(SPIN2007 = "*", ContentsCode = "PR0301I4", Tid = c("2010M02","2011M03"))) 43 | ``` 44 | 45 | The data can now be inspected, e.g. by doing `View(sdata)`. 46 | 47 | 48 | ### Cleaning up the results 49 | Unfortunately, the beta version of the SCB web API often returns faulty formatted data, which can cause a lot of pain. In version 0.3 of pxweb this can be handled directly by setting the parameter `clean = TRUE` in the `scbGetData()` function. So to get cleaned and molten data for the same call as in the previous example, just add `clean = TRUE`: 50 | ```r 51 | sdata <- scbGetData(bottomNode$URL, 52 | list(SPIN2007 = "*", ContentsCode = "PR0301I4", Tid = c("2010M02","2011M03")), 53 | clean=TRUE) 54 | ``` 55 | The data should now be ready for use. 56 | 57 | ## Further examples 58 | Further examples of advanced package usage are included in the "examples" folder installed with this package. To locate this folder on your system, run `system.file(package = "pxweb")` from the R terminal. 59 | 60 | -------------------------------------------------------------------------------- /tests/testthat/test-pxweb_constructor.R: -------------------------------------------------------------------------------- 1 | # Test suits for the examples in the documentation 2 | 3 | context("pxweb_constructor") 4 | 5 | test_that(desc = "Constructor works as it should with Statistics Sweden", { 6 | # CRAN seem to run tests in parallel, hence API tests cannot be run on CRAN. 7 | skip_on_cran() 8 | skip_if_offline() 9 | 10 | expect_silent(pxapi1 <- pxweb(url = "https://api.scb.se/OV0104/v1/doris/sv/ssd/START/ME/ME0104/ME0104C/ME0104T24")) 11 | expect_true(file.exists(pxapi1$paths$rda_file_path)) 12 | expect_true(length(pxapi1$calls$time_stamps) > 0) 13 | expect_true(is.pxweb(pxapi1)) 14 | expect_silent(pxapi2 <- pxweb(url = "https://api.scb.se/OV0104/v1/doris/sv/ssd/START/ME/ME0104/ME0104C/ME0104T24")) 15 | expect_true(length(pxapi2$calls$time_stamps) == length(pxapi2$calls$time_stamps)) 16 | 17 | expect_silent(pxweb:::pxweb_clear_cache(pxapi1)) 18 | 19 | expect_silent(pxweb(url = "https://api.scb.se/OV0104/v1/doris/sv?config")) 20 | expect_silent(pxweb(url = "https://api.scb.se/OV0104/v1/doris/sv?config")) # Cached 21 | expect_silent(pxweb:::pxweb_clear_cache(pxapi1)) 22 | 23 | # Handling of subpath 24 | expect_silent(pxapi1 <- pxweb(url = "https://api.scb.se/OV0104/v1/doris/sv/ssd/START/ME/ME0104/ME0104C/ME0104T24")) 25 | expect_equal(pxapi1$paths$api_subpath$path, "OV0104/v1/doris/sv") 26 | expect_silent(pxapi1 <- pxweb(url = "https://api.scb.se/OV0104/v1/doris/en/ssd/START/ME/ME0104/ME0104C/ME0104T24")) 27 | expect_equal(pxapi1$paths$api_subpath$path, "OV0104/v1/doris/en") 28 | }) 29 | 30 | 31 | test_that(desc = "Constructor works for erroneous urls", { 32 | # CRAN seem to run tests in parallel, hence API tests cannot be run on CRAN. 33 | skip_on_cran() 34 | skip_if_offline() 35 | 36 | expect_silent(pxapi1 <- pxweb(url = "https://api.scb.se/OV0104/v1/doris/sv/ssd/START/ME/ME0104/ME0104C/ME0104T24")) 37 | 38 | expect_error(pxweb(url = "api.scb.se/OV0104/v1/doris/sv/ssd/START/ME/ME0104/ME0104C/ME0104T24")) 39 | expect_silent(pxweb(url = "https://api.scb.se/OV0104/v1/dosasasasas")) 40 | expect_error(pxweb(url = "http://www.statistikdatabasen.scb.se/pxweb/sv/ssd/")) 41 | expect_error(pxweb(url = "https://sv.wikipedia.org/wiki/ISO_639")) 42 | expect_silent(pxweb(url = "https://api.scb.se")) 43 | 44 | expect_silent(pxweb:::pxweb_clear_cache(pxapi1)) 45 | 46 | expect_error(pxweb(url = "api.scb.se/OV0104/v1/doris/sv/ssd/START/ME/ME0104/ME0104C/ME0104T24")) 47 | expect_error(pxweb(url = "https://api.scb.se/OV0104/v1/dosasasasas")) 48 | expect_error(pxweb(url = "https://api.scb.se")) 49 | }) 50 | 51 | 52 | test_that(desc = "Cache cleaner and print", { 53 | # CRAN seem to run tests in parallel, hence API tests cannot be run on CRAN. 54 | skip_on_cran() 55 | skip_if_offline() 56 | 57 | expect_silent(pxapi1 <- pxweb(url = "https://api.scb.se/OV0104/v1/doris/sv/ssd/START/ME/ME0104/ME0104C/ME0104T24")) 58 | expect_silent(pxapi2 <- pxweb("https://statfin.stat.fi/PXWeb/api/v1/fi/StatFin/tym/tyonv/statfin_tyonv_pxt_001.px")) 59 | expect_true(file.exists(pxapi1$paths$rda_file_path)) 60 | expect_silent(pxweb:::pxweb_clear_cache()) 61 | expect_false(file.exists(pxapi1$paths$rda_file_path)) 62 | 63 | expect_output(print(pxapi1), "PXWEB API") 64 | }) 65 | 66 | test_that(desc = "pxweb_clear_cache() without any files", { 67 | # CRAN seem to run tests in parallel, hence API tests cannot be run on CRAN. 68 | skip_on_cran() 69 | 70 | expect_silent(pxweb_clear_cache()) 71 | expect_silent(pxweb_clear_cache()) 72 | }) 73 | 74 | 75 | test_that(desc = "pxweb_clear_cache() without any files and WARNING for redirect.", { 76 | # CRAN seem to run tests in parallel, hence API tests cannot be run on CRAN. 77 | skip_on_cran() 78 | 79 | expect_silent(pxweb_clear_cache()) 80 | expect_silent(pxweb_clear_cache()) 81 | 82 | # Now not working 83 | # expect_warning(pxweb("http://pxweb.asub.ax/PXWeb/api/v1/sv/"), regexp = "PXWEB URL CHANGE") 84 | }) 85 | -------------------------------------------------------------------------------- /R/pxweb.R: -------------------------------------------------------------------------------- 1 | #' S3 constructor for \code{pxweb} api object. 2 | #' 3 | #' @description 4 | #' The pxwebapi object contain all information to do calls to the pxweb api and keep count 5 | #' of the number of calls. The object is constructed 6 | #' The object will also be cached in R temp folder to minimize calls to api. 7 | #' All urls should be passed through the constructor to set up the pxweb api config. 8 | #' 9 | #' \emph{Garantuees}: 10 | #' The base_url has been pinged 11 | #' The sub_path has been checked 12 | #' The config has been captured from the API 13 | #' The url has been checked to be a pxweb api (through config) 14 | #' 15 | #' @param url an url to a pxweb api including language and version of the api. See examples. 16 | #' @param x an an object to test if it is a \code{pxweb} object. 17 | #' @param ... further arguments supplied to \code{print()}. 18 | #' 19 | #' @return 20 | #' A \code{pxweb} object. 21 | #' 22 | #' @examples 23 | #' \dontrun{ 24 | #' pxapi_1 <- 25 | #' pxweb("https://api.scb.se/OV0104/v1/doris/sv/ssd/START/ME/ME0104/ME0104C/ME0104T24") 26 | #' pxapi_2 <- 27 | #' pxweb(url = "https://api.scb.se/OV0104/v1/doris/sv") 28 | #' } 29 | #' 30 | #' @export 31 | pxweb <- function(url) { 32 | if (is.pxweb(url)) { 33 | return(url) 34 | } 35 | checkmate::assert_string(url) 36 | url_parsed <- parse_url_or_fail(x = url) 37 | if(!has_internet(url_parsed$hostname)){ 38 | message(no_internet_msg(url_parsed$hostname)) 39 | return(NULL) 40 | } 41 | 42 | obj <- list( 43 | url = url_parsed, 44 | config = NULL, 45 | calls = NULL, 46 | paths = NULL 47 | ) 48 | 49 | # Add path to temp api storage and time_stamp slot 50 | obj$paths <- list(rda_file_path = build_pxweb_rda_file_path(obj)) 51 | if (file.exists(obj$paths$rda_file_path)) { 52 | obj$calls <- load_pxweb_calls(obj) 53 | } else { 54 | obj$calls <- list(time_stamps = list()) 55 | } 56 | 57 | 58 | # Add the config slot (require one call first construction of the session) 59 | obj <- pxweb_add_config(obj) 60 | 61 | # Add subpath and query path 62 | obj <- pxweb_add_api_subpath(obj) 63 | 64 | # Create object 65 | class(obj) <- c("pxweb", "list") 66 | assert_pxweb(obj) 67 | save_pxweb(obj) 68 | 69 | obj 70 | } 71 | 72 | 73 | #' @rdname pxweb 74 | #' @keywords internal 75 | #' @export 76 | is.pxweb <- function(x) inherits(x, "pxweb") 77 | 78 | #' @rdname pxweb 79 | #' @export 80 | print.pxweb <- function(x, ...) { 81 | cat("PXWEB API\n") 82 | cat("url:", httr::build_url(x$url), "\n") 83 | cat("config:\n") 84 | for (i in seq_along(x$config)) { 85 | cat(paste0(" ", names(x$config)[i], ": ", x$config[i], "\n")) 86 | } 87 | cat("calls:\n") 88 | for (i in seq_along(x$calls$time_stamps)) { 89 | cat(paste0(" ", x$calls$time_stamps[[i]], "\n")) 90 | } 91 | cat("paths:\n") 92 | cat(paste0(" ", names(x$paths)[1], ": ", x$paths[[1]], "\n")) 93 | cat(paste0(" ", names(x$paths)[2], ": ", x$paths[[2]]$path, "\n")) 94 | } 95 | 96 | 97 | #' Fix url characters 98 | #' @param x a string to fix 99 | #' @keywords internal 100 | pxweb_fix_url <- function(x) { 101 | checkmate::assert_string(x) 102 | # URLencode cannot handle partially encoded strings 103 | x <- utils::URLencode(utils::URLdecode(x)) 104 | x 105 | } 106 | 107 | #' Setup temorary directory for the pxweb 108 | #' @param to to what part of the temp folder (apis or logs) 109 | #' @keywords internal 110 | pxweb_tempdir <- function(to = "apis") { 111 | checkmate::assert_choice(to, c("apis", "logs")) 112 | tmp_dir_apis <- file.path(tempdir(), "pxweb", "apis") 113 | tmp_dir_logs <- file.path(tempdir(), "pxweb", "logs") 114 | if (!dir.exists(tmp_dir_apis)) { 115 | dir.create(tmp_dir_apis, recursive = TRUE) 116 | } 117 | if (!dir.exists(tmp_dir_logs)) { 118 | dir.create(tmp_dir_logs, recursive = TRUE) 119 | } 120 | if (to == "apis") { 121 | return(tmp_dir_apis) 122 | } else { 123 | return(tmp_dir_logs) 124 | } 125 | } 126 | 127 | no_internet_msg <- function(host){ 128 | return(paste0("No internet access to '", host, "'.")) 129 | } 130 | 131 | has_internet <- function(host){ 132 | !is.null(curl::nslookup(host, error = FALSE)) 133 | } 134 | -------------------------------------------------------------------------------- /R/pxweb_add_config.R: -------------------------------------------------------------------------------- 1 | #' Add the config slot to a pxweb object 2 | #' 3 | #' @details 4 | #' Checks if there exist a config object in the object. 5 | #' Otherwise it query the api to get it and add that call to the call stack. 6 | #' 7 | #' @param obj an object to add config to 8 | #' 9 | #' @keywords internal 10 | pxweb_add_config <- function(obj) { 11 | assert_pxweb_url(obj) 12 | assert_pxweb_rda_file_path(obj) 13 | 14 | if (inherits(obj, "pxweb")) { 15 | return(obj) 16 | } 17 | 18 | if (file.exists(obj$paths$rda_file_path)) { 19 | obj$config <- load_pxweb_config(obj) 20 | return(obj) 21 | } 22 | 23 | # Do a call to get the cfg and check if PXWEB API 24 | # Add that one call has been made 25 | call_time_stamp <- Sys.time() 26 | cfg_url <- build_pxweb_config_url(obj) 27 | r <- httr::GET(cfg_url) 28 | pxweb_http_log_response(r) 29 | 30 | # Check that we get a config back 31 | 32 | if (!is_pxweb_config_response(r)) { 33 | base_url <- build_pxweb_url(obj) 34 | r2 <- httr::GET(base_url) 35 | pxweb_http_log_response(r2) 36 | if (is_pxweb_response(r2)) { 37 | stop(paste0("\nThis is an old PXWEB API not supported by pxweb R package\n(version PX-Web 2014 Dec R1 or later is supported): \n", httr::build_url(obj$url)), call. = FALSE) 38 | } else { 39 | stop(paste0("\nThis is not a PXWEB API: \n", httr::build_url(obj$url)), call. = FALSE) 40 | } 41 | } 42 | 43 | httpwr <- http_was_redirected(r) 44 | if (httpwr$was_redirected) { 45 | warning("PXWEB URL CHANGE:\n from: ", httpwr$redirected_from, "\n to: ", httpwr$redirected_to, call. = FALSE) 46 | } 47 | 48 | cfg <- httr::content(r, "parsed") 49 | if(!is.null(cfg$maxCells)){ 50 | mvtd <- cfg$maxCells 51 | } else { 52 | mvtd <- cfg$maxValues 53 | } 54 | 55 | obj$config <- list( 56 | calls_per_period = cfg$maxCalls, 57 | period_in_seconds = cfg$timeWindow, 58 | max_values_to_download = mvtd, 59 | CORS = cfg$CORS 60 | ) 61 | 62 | # Add the call to the stack 63 | obj <- pxweb_add_call(obj, call_time_stamp) 64 | obj 65 | } 66 | 67 | 68 | #' Check if a response is a pxweb config response 69 | #' 70 | #' @param x a response object 71 | #' @keywords internal 72 | is_pxweb_config_response <- function(x) { 73 | checkmate::assert_class(x, "response") 74 | if (httr::http_error(x)) { 75 | return(FALSE) 76 | } 77 | cfg <- suppressMessages(try(httr::content(x, "parsed"), silent = TRUE)) 78 | (all(c("maxValues", "maxCalls", "timeWindow", "CORS") %in% names(cfg))) & !inherits(cfg, "try-error") 79 | } 80 | 81 | 82 | 83 | #' http_was_redirected 84 | #' 85 | #' @param r an httr response object, e.g. from a call to httr::GET() 86 | #' 87 | #' @return list with slots \code{was_redirected}, \code{redirected_from} and \code{redirected_to} 88 | #' 89 | #' @references 90 | #' Function in large parts taken from \url{https://petermeissner.de/blog/2018/11/07/using-httr-to-detect-redirects/}. 91 | #' 92 | #' @examples 93 | #' \dontrun{ 94 | #' r <- httr::GET("http://httpbin.org/redirect/2") 95 | #' pxweb:::http_was_redirected(r) 96 | #' } 97 | #' @keywords internal 98 | http_was_redirected <- function(r) { 99 | checkmate::assert_class(r, "response") 100 | 101 | # extract status 102 | status <- 103 | vapply( 104 | X = r$all_headers, 105 | FUN = `[[`, 106 | FUN.VALUE = integer(1), 107 | "status" 108 | ) 109 | 110 | # Remove config etc 111 | redirected_from <- httr::parse_url(r$request$url) 112 | redirected_from$params <- NULL 113 | redirected_from$query <- NULL 114 | redirected_from$fragment <- NULL 115 | redirected_from$username <- NULL 116 | redirected_from$password <- NULL 117 | redirected_to <- httr::parse_url(r$url) 118 | redirected_to$params <- NULL 119 | redirected_to$query <- NULL 120 | redirected_to$fragment <- NULL 121 | redirected_to$username <- NULL 122 | redirected_to$password <- NULL 123 | 124 | # check domains in location against original domain 125 | list( 126 | was_redirected = any(status >= 300 & status < 400), 127 | redirected_from = httr::build_url(redirected_from), 128 | redirected_to = httr::build_url(redirected_to) 129 | ) 130 | } 131 | -------------------------------------------------------------------------------- /R/pxweb_metadata.R: -------------------------------------------------------------------------------- 1 | #' Construct a \code{pxweb_metadata} object. 2 | #' 3 | #' @description 4 | #' An object that contain the metadata for a given PXWEB table. 5 | #' 6 | #' @param x a list returned from a PXWEB API to convert to a \code{pxweb_metadata} object. 7 | #' 8 | #' @return 9 | #' a \code{pxweb_metadata} object 10 | #' 11 | #' @keywords internal 12 | pxweb_metadata <- function(x) { 13 | if (is.null(x$title)) { 14 | x$title <- NA 15 | } 16 | 17 | checkmate::assert_names(names(x), must.include = "variables") 18 | for (i in seq_along(x$variables)) { 19 | if (all(c("values", "valueTexts") %in% names(x$variables[[i]]))) { 20 | checkmate::assert_names(names(x$variables[[i]]), must.include = c("values", "valueTexts")) 21 | x$variables[[i]]$values <- unlist(x$variables[[i]]$values) 22 | x$variables[[i]]$valueTexts <- unlist(x$variables[[i]]$valueTexts) 23 | } 24 | if (is.null(x$variables[[i]]$elimination)) x$variables[[i]]$elimination <- FALSE 25 | if (is.null(x$variables[[i]]$time)) x$variables[[i]]$time <- FALSE 26 | } 27 | class(x) <- c("pxweb_metadata", "list") 28 | assert_pxweb_metadata(x) 29 | x 30 | } 31 | 32 | 33 | 34 | #' Assert that x is a correct \code{pxweb_metadata} object. 35 | #' @param x an object to check. 36 | #' @keywords internal 37 | assert_pxweb_metadata <- function(x) { 38 | checkmate::assert_class(x, c("pxweb_metadata", "list")) 39 | checkmate::assert_names(names(x), must.include = c("title", "variables")) 40 | checkmate::assert_string(x$title, na.ok = TRUE) 41 | 42 | for (i in seq_along(x$variables)) { 43 | checkmate::assert_names(names(x$variables[[i]]), must.include = c("code", "text", "elimination", "time"), .var.name = paste0("names(x$variables[[", i, "]])")) 44 | checkmate::assert_string(x$variables[[i]]$code, .var.name = paste0("x$variables[[", i, "]]$code")) 45 | checkmate::assert_string(x$variables[[i]]$text, .var.name = paste0("x$variables[[", i, "]]$text")) 46 | if (!is.null(x$variables[[i]]$values)) { 47 | checkmate::assert_character(x$variables[[i]]$values, .var.name = paste0("x$variables[[", i, "]]$values")) 48 | checkmate::assert_character(x$variables[[i]]$valueTexts, len = length(unlist(x$variables[[i]]$values)), .var.name = paste0("x$variables[[", i, "]]$valueTexts")) 49 | } 50 | checkmate::assert_flag(x$variables[[i]]$time, .var.name = paste0("x$variables[[", i, "]]$time")) 51 | checkmate::assert_flag(x$variables[[i]]$elimination, .var.name = paste0("x$variables[[", i, "]]$elimination")) 52 | } 53 | } 54 | 55 | 56 | #' @export 57 | print.pxweb_metadata <- function(x, ...) { 58 | cat("PXWEB METADATA\n") 59 | cat(x$title, "\n") 60 | cat("variables:\n") 61 | for (i in seq_along(x$variables)) { 62 | cat(" [[", i, "]] ", x$variables[[i]]$code, ": ", x$variables[[i]]$text, "\n", sep = "") 63 | } 64 | } 65 | 66 | #' Get boolean vector 67 | #' 68 | #' @param pxmd a \code{pxweb_metadata} object. 69 | #' 70 | #' @return pxweb_metadata eliminations as a named boolean vector. 71 | #' 72 | #' @keywords internal 73 | pxweb_metadata_elimination <- function(pxmd) { 74 | checkmate::assert_class(pxmd, "pxweb_metadata") 75 | res <- unlist(lapply(pxmd$variables, function(x) x$elimination)) 76 | names(res) <- unlist(lapply(pxmd$variables, function(x) x$code)) 77 | res 78 | } 79 | 80 | #' Get boolean vector 81 | #' 82 | #' @param pxmd a \code{pxweb_metadata} object. 83 | #' 84 | #' @return pxweb_metadata eliminations as a named boolean vector. 85 | #' 86 | #' @keywords internal 87 | pxweb_metadata_time <- function(pxmd) { 88 | checkmate::assert_class(pxmd, "pxweb_metadata") 89 | res <- unlist(lapply(pxmd$variables, function(x) x$time)) 90 | names(res) <- unlist(lapply(pxmd$variables, function(x) x$code)) 91 | res 92 | } 93 | 94 | 95 | #' Compue the dimension of a metadata object 96 | #' 97 | #' @param pxmd a \code{pxweb_metadata} object. 98 | #' 99 | #' @keywords internal 100 | pxweb_metadata_dim <- function(pxmd) { 101 | checkmate::assert_class(pxmd, "pxweb_metadata") 102 | dim_res <- numeric(length(pxmd$variables)) 103 | for (i in seq_along(pxmd$variables)) { 104 | names(dim_res)[i] <- pxmd$variables[[i]]$code 105 | dim_res[i] <- length(pxmd$variables[[i]]$values) 106 | } 107 | dim_res 108 | } 109 | -------------------------------------------------------------------------------- /R/pxweb_data.R: -------------------------------------------------------------------------------- 1 | #' Construct a \code{pxweb_data} object. 2 | #' 3 | #' @description 4 | #' An object that contain the data for a given PXWEB table. 5 | #' 6 | #' @param x a list returned from a PXWEB API to convert to a \code{pxweb_data} object. 7 | #' 8 | #' @return 9 | #' a \code{pxweb_data} object 10 | #' 11 | #' @keywords internal 12 | pxweb_data <- function(x) { 13 | checkmate::assert_class(x, "list") 14 | class(x) <- c("pxweb_data", "list") 15 | assert_pxweb_data(x) 16 | x 17 | } 18 | 19 | #' Assert that x is a correct \code{pxweb_data} object. 20 | #' @param x an object to check. 21 | #' @keywords internal 22 | assert_pxweb_data <- function(x) { 23 | checkmate::assert_class(x, c("pxweb_data", "list")) 24 | checkmate::assert_names(names(x), must.include = c("columns", "comments", "data")) 25 | 26 | for (i in seq_along(x$columns)) { 27 | checkmate::assert_names(names(x$columns[[i]]), must.include = c("code", "text", "type")) 28 | checkmate::assert_string(x$columns[[i]]$code) 29 | checkmate::assert_string(x$columns[[i]]$text) 30 | checkmate::assert_choice(x$columns[[i]]$type, choices = c("t", "c", "d")) 31 | } 32 | 33 | for (i in seq_along(x$comments)) { 34 | checkmate::assert_names(names(x$comments[[i]]), must.include = c("variable", "value", "comment")) 35 | checkmate::assert_string(x$comments[[i]]$variable) 36 | checkmate::assert_string(x$comments[[i]]$value) 37 | checkmate::assert_string(x$comments[[i]]$comment) 38 | } 39 | 40 | for (i in seq_along(x$data)) { 41 | checkmate::assert_names(names(x$data[[i]]), must.include = c("key", "values")) 42 | checkmate::assert_list(x$data[[i]]$key) 43 | } 44 | } 45 | 46 | 47 | #' @export 48 | print.pxweb_data <- function(x, ...) { 49 | cat("PXWEB DATA\n") 50 | pxdim <- pxweb_data_dim(x) 51 | no_comments <- length(pxweb_data_comments(x)$pxweb_data_comments) 52 | if (no_comments > 0) { 53 | cat("With", pxdim[2], "variables,", pxdim[1], "observations and", no_comments, "comments/footnotes.") 54 | } else { 55 | cat("With", pxdim[2], "variables and", pxdim[1], "observations.") 56 | } 57 | } 58 | 59 | 60 | #' Compute the dimension of the query \code{pxweb_data} object 61 | #' 62 | #' @param pxd a \code{pxweb_data} object. 63 | #' 64 | #' @keywords internal 65 | pxweb_data_dim <- function(pxd) { 66 | checkmate::assert_class(pxd, "pxweb_data") 67 | c(length(pxd$data), length(pxd$columns)) 68 | } 69 | 70 | 71 | #' Get query filter 72 | #' 73 | #' @param pxd a \code{pxweb_data} object. 74 | #' 75 | #' @return character vector with column names. 76 | #' 77 | #' @keywords internal 78 | pxweb_data_colnames <- function(pxd, type = "text") { 79 | checkmate::assert_class(pxd, "pxweb_data") 80 | checkmate::assert_choice(type, choices = c("text", "code")) 81 | unlist(lapply(pxd$columns, function(x) x[[type]])) 82 | } 83 | 84 | 85 | 86 | 87 | #' Convert a pxweb data objects values to valuetext 88 | #' 89 | #' @param x a \code{pxweb_data} object 90 | #' @param variable_code the variable name of the variable to convert. NOTE! Need to be the variable code. 91 | #' @param variable_vector the vector with the variables to convert. 92 | #' @keywords internal 93 | pxd_values_to_valuetexts <- function(x, variable_code, variable_vector) { 94 | checkmate::assert_class(x, classes = "pxweb_data") 95 | pxmd_dim <- pxweb_metadata_dim(x$pxweb_metadata) 96 | checkmate::assert_choice(variable_code, choices = names(pxmd_dim)) 97 | var_idx <- which(names(pxmd_dim) %in% variable_code) 98 | var_labels <- x$pxweb_metadata$variables[[var_idx]]$values 99 | checkmate::assert_subset(variable_vector, choices = var_labels) 100 | checkmate::assert_true(is.character(variable_vector) | is.factor(variable_vector)) 101 | 102 | input_is_factor <- is.factor(variable_vector) 103 | 104 | if (!input_is_factor) { 105 | variable_vector <- as.factor(variable_vector) 106 | } 107 | new_variable_levels <- variable_levels <- levels(variable_vector) 108 | 109 | for (i in seq_along(variable_levels)) { 110 | idx <- which(x$pxweb_metadata$variables[[var_idx]]$values %in% variable_levels[i]) 111 | new_variable_levels[i] <- x$pxweb_metadata$variables[[var_idx]]$valueTexts[idx] 112 | } 113 | levels(variable_vector) <- new_variable_levels 114 | if (!input_is_factor) { 115 | variable_vector <- as.character(variable_vector) 116 | } 117 | variable_vector 118 | } 119 | -------------------------------------------------------------------------------- /README.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | output: github_document 3 | --- 4 | 5 | 6 | ```{r, echo = FALSE} 7 | knitr::opts_chunk$set( 8 | collapse = TRUE, 9 | comment = "#>", 10 | fig.path = "man/figures/" 11 | ) 12 | ``` 13 | 14 | 15 | 16 | [![rOG-badge](https://ropengov.github.io/rogtemplate/reference/figures/ropengov-badge.svg)](http://ropengov.org/) 17 | [![R build status](https://github.com/rOpenGov/pxweb/workflows/R-CMD-check/badge.svg)](https://github.com/rOpenGov/pxweb/actions) 18 | [![codecov](https://codecov.io/gh/rOpenGov/pxweb/branch/master/graph/badge.svg?token=zYtxsus27g)](https://codecov.io/gh/rOpenGov/pxweb) 19 | [![Downloads](http://cranlogs.r-pkg.org/badges/grand-total/pxweb)](https://cran.r-project.org/package=pxweb) 20 | [![Downloads](http://cranlogs.r-pkg.org/badges/pxweb)](https://cran.r-project.org/package=pxweb) 21 | [![CRAN_Status_Badge](https://www.r-pkg.org/badges/version/pxweb)](https://cran.r-project.org/package=pxweb) 22 | [![Gitter](https://badges.gitter.im/rOpenGov/pxweb.svg)](https://gitter.im/rOpenGov/pxweb?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) 23 | [![Watch on GitHub][github-watch-badge]][github-watch] 24 | [![Star on GitHub][github-star-badge]][github-star] 25 | [![Follow](https://img.shields.io/twitter/follow/ropengov.svg?style=social)](https://twitter.com/intent/follow?screen_name=ropengov) 26 | [![R-CMD-check](https://github.com/rOpenGov/pxweb/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/rOpenGov/pxweb/actions/workflows/R-CMD-check.yaml) 27 | 28 | 29 |
30 | 31 | # R tools to access PX-WEB API - the pxweb R package 32 | 33 | 34 | 35 | 36 | The pxweb R package provides tools to interface with the PX-WEB API 37 | for data search, download, manipulation and visualization 38 | purposes. This is used by a large number of statistical authorities 39 | world-wide. It offers methods to utilize information about the data 40 | hierarchy stored behind the PXWEB API. 41 | 42 | Many API services are still in their early stages, and data quality is 43 | sometimes compromised. Issue reports are welcome. 44 | 45 | ## Installation 46 | 47 | The easiest way to use pxweb is to simply install it from CRAN: 48 | 49 | ```{r, eval=FALSE} 50 | install.packages("pxweb") 51 | ``` 52 | 53 | 54 | Alternatively, you can get the latest stable development version: 55 | 56 | ```{r, results='hide', message=FALSE, eval=FALSE} 57 | library(remotes) 58 | remotes::install_github("ropengov/pxweb") 59 | ``` 60 | 61 | In some cases, the organization requires manual proxy settings. This can be set as follows: 62 | 63 | ```{r, results='hide', message=FALSE, eval=FALSE} 64 | library(remotes) 65 | library(httr) 66 | set_config( 67 | use_proxy("64.251.21.73", 8080) # Note! This is an example 68 | ) 69 | remotes::install_github("ropengov/pxweb") 70 | ``` 71 | 72 | ```{r, results='hide', echo=FALSE} 73 | # This resets the config when the README is tested 74 | httr::reset_config() 75 | ``` 76 | 77 | ## Using the package 78 | 79 | For examples, check the [tutorial/vignette](https://ropengov.github.io/pxweb/articles/pxweb.html). 80 | 81 | ## Problems? 82 | 83 | See [TROUBLESHOOTING.md](https://github.com/rOpenGov/pxweb/blob/master/TROUBLESHOOTING.md) or [open an issue](https://github.com/ropengov/pxweb/issues). 84 | 85 | # Contributing 86 | 87 | You are welcome to contact us: 88 | 89 | * [Submit suggestions and bug reports](https://github.com/ropengov/pxweb/issues) (provide the output of `sessionInfo()` and `packageVersion("pxweb")`) 90 | * [Send a pull request](https://github.com/ropengov/pxweb) 91 | * [Star us on the Github page](https://github.com/ropengov/pxweb) 92 | * [Join the discussion in Gitter](https://gitter.im/rOpenGov/pxweb) 93 | 94 | 95 | ### Acknowledgements 96 | 97 | ```{r acknowledgements, comment = "", highlight=FALSE} 98 | citation("pxweb") 99 | ``` 100 | 101 | We are grateful to all [contributors](https://github.com/rOpenGov/pxweb/graphs/contributors)! This project is part of [rOpenGov](http://ropengov.github.io). 102 | 103 | 104 | [github-watch-badge]: https://img.shields.io/github/watchers/ropengov/pxweb.svg?style=social 105 | [github-watch]: https://github.com/ropengov/pxweb/watchers 106 | [github-star-badge]: https://img.shields.io/github/stars/ropengov/pxweb.svg?style=social 107 | [github-star]: https://github.com/ropengov/pxweb/stargazers 108 | 109 | 110 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | [![rOG-badge](https://ropengov.github.io/rogtemplate/reference/figures/ropengov-badge.svg)](http://ropengov.org/) 5 | [![R build 6 | status](https://github.com/rOpenGov/pxweb/workflows/R-CMD-check/badge.svg)](https://github.com/rOpenGov/pxweb/actions) 7 | [![codecov](https://codecov.io/gh/rOpenGov/pxweb/branch/master/graph/badge.svg?token=zYtxsus27g)](https://codecov.io/gh/rOpenGov/pxweb) 8 | [![Downloads](http://cranlogs.r-pkg.org/badges/grand-total/pxweb)](https://cran.r-project.org/package=pxweb) 9 | [![Downloads](http://cranlogs.r-pkg.org/badges/pxweb)](https://cran.r-project.org/package=pxweb) 10 | [![CRAN_Status_Badge](https://www.r-pkg.org/badges/version/pxweb)](https://cran.r-project.org/package=pxweb) 11 | [![Gitter](https://badges.gitter.im/rOpenGov/pxweb.svg)](https://gitter.im/rOpenGov/pxweb?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) 12 | [![Watch on 13 | GitHub](https://img.shields.io/github/watchers/ropengov/pxweb.svg?style=social)](https://github.com/ropengov/pxweb/watchers) 14 | [![Star on 15 | GitHub](https://img.shields.io/github/stars/ropengov/pxweb.svg?style=social)](https://github.com/ropengov/pxweb/stargazers) 16 | [![Follow](https://img.shields.io/twitter/follow/ropengov.svg?style=social)](https://twitter.com/intent/follow?screen_name=ropengov) 17 | [![R-CMD-check](https://github.com/rOpenGov/pxweb/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/rOpenGov/pxweb/actions/workflows/R-CMD-check.yaml) 18 | 19 | 20 |
21 | 22 | # R tools to access PX-WEB API - the pxweb R package 23 | 24 | 25 | 26 | The pxweb R package provides tools to interface with the PX-WEB API for 27 | data search, download, manipulation and visualization purposes. This is 28 | used by a large number of statistical authorities world-wide. It offers 29 | methods to utilize information about the data hierarchy stored behind 30 | the PXWEB API. 31 | 32 | Many API services are still in their early stages, and data quality is 33 | sometimes compromised. Issue reports are welcome. 34 | 35 | ## Installation 36 | 37 | The easiest way to use pxweb is to simply install it from CRAN: 38 | 39 | ``` r 40 | install.packages("pxweb") 41 | ``` 42 | 43 | Alternatively, you can get the latest stable development version: 44 | 45 | ``` r 46 | library(remotes) 47 | remotes::install_github("ropengov/pxweb") 48 | ``` 49 | 50 | In some cases, the organization requires manual proxy settings. This can 51 | be set as follows: 52 | 53 | ``` r 54 | library(remotes) 55 | library(httr) 56 | set_config( 57 | use_proxy("64.251.21.73", 8080) # Note! This is an example 58 | ) 59 | remotes::install_github("ropengov/pxweb") 60 | ``` 61 | 62 | ## Using the package 63 | 64 | For examples, check the 65 | [tutorial/vignette](https://ropengov.github.io/pxweb/articles/pxweb.html). 66 | 67 | ## Problems? 68 | 69 | See 70 | [TROUBLESHOOTING.md](https://github.com/rOpenGov/pxweb/blob/master/TROUBLESHOOTING.md) 71 | or [open an issue](https://github.com/ropengov/pxweb/issues). 72 | 73 | # Contributing 74 | 75 | You are welcome to contact us: 76 | 77 | - [Submit suggestions and bug 78 | reports](https://github.com/ropengov/pxweb/issues) (provide the output 79 | of `sessionInfo()` and `packageVersion("pxweb")`) 80 | - [Send a pull request](https://github.com/ropengov/pxweb) 81 | - [Star us on the Github page](https://github.com/ropengov/pxweb) 82 | - [Join the discussion in Gitter](https://gitter.im/rOpenGov/pxweb) 83 | 84 | ### Acknowledgements 85 | 86 | ``` text 87 | citation("pxweb") 88 | Kindly cite the pxweb R package as follows: 89 | 90 | Kindly cite the 'pxweb' R package as follows: 91 | 92 | Magnusson M, Kainu M, Huovari J, Lahti L (2025). _pxweb: R Interface 93 | to PXWEB APIs_. doi:10.32614/CRAN.package.pxweb 94 | , R package version 95 | 0.17.1, . 96 | 97 | A BibTeX entry for LaTeX users is 98 | 99 | @Manual{R-pxweb, 100 | title = {{pxweb: R Interface to PXWEB APIs}}, 101 | doi = {10.32614/CRAN.package.pxweb}, 102 | author = {Mans Magnusson and Markus Kainu and Janne Huovari and Leo Lahti}, 103 | year = {2025}, 104 | version = {0.17.1}, 105 | note = {R package version 0.17.1}, 106 | url = {https://github.com/rOpenGov/pxweb}, 107 | } 108 | ``` 109 | 110 | We are grateful to all 111 | [contributors](https://github.com/rOpenGov/pxweb/graphs/contributors)! 112 | This project is part of [rOpenGov](http://ropengov.github.io). 113 | -------------------------------------------------------------------------------- /R/pxweb_api_catalogue.R: -------------------------------------------------------------------------------- 1 | #' Get the PXWEB API catalogue 2 | #' 3 | #' @details 4 | #' A list with implemented API:s. 5 | #' 6 | #' @examples 7 | #' pxweb_api_catalogue() 8 | #' 9 | #' @export 10 | pxweb_api_catalogue <- function() { 11 | pxweb_api_catalogue_from_json(pxweb_api_catalogue_path()) 12 | } 13 | 14 | #' @rdname pxweb_api_catalogue 15 | #' @keywords internal 16 | pxweb_api_catalogue_from_json <- function(json) { 17 | checkmate::assert_string(json) 18 | apis <- jsonlite::fromJSON(json) 19 | pxweb_api_catalogue <- list() 20 | for (i in seq_along(apis$apis)) { 21 | pxweb_api_catalogue[[names(apis$apis)[i]]] <- pxweb_api_catalogue_entry(apis$apis[[i]]) 22 | } 23 | class(pxweb_api_catalogue) <- c("pxweb_api_catalogue", "list") 24 | assert_pxweb_api_catalogue(pxweb_api_catalogue) 25 | return(pxweb_api_catalogue) 26 | } 27 | 28 | #' @rdname pxweb_api_catalogue 29 | #' @keywords internal 30 | pxweb_api_catalogue_from_github <- function(branch = "master") { 31 | checkmate::assert_string(branch) 32 | url_raw <- paste0("https://raw.githubusercontent.com/rOpenGov/pxweb/", branch, "/inst/extdata/api.json") 33 | request <- httr::GET(url_raw) 34 | httr::stop_for_status(request) 35 | api_json <- httr::content(request) 36 | pxweb_api_catalogue_from_json(json = api_json) 37 | } 38 | 39 | #' @rdname pxweb_api_catalogue 40 | #' @keywords internal 41 | #' @export 42 | pxweb_api_catalogue_path <- function() { 43 | system.file(file.path("extdata", "api.json"), package = "pxweb") 44 | } 45 | 46 | #' Assert a \code{pxweb_api_catalogue} object 47 | #' @param x an object to assert is a \code{pxweb_api_catalogue_entry}. 48 | #' @keywords internal 49 | assert_pxweb_api_catalogue <- function(x) { 50 | checkmate::assert_class(x, "pxweb_api_catalogue") 51 | for (i in seq_along(x)) { 52 | checkmate::assert_class(x[[i]], "pxweb_api_catalogue_entry") 53 | checkmate::assert_names(names(x)[i], identical.to = httr::parse_url(x[[i]]$url)$hostname, .var.name = paste0("names(x)[", i, "]")) 54 | } 55 | } 56 | 57 | 58 | #' Constructor for \code{pxweb_api_catalogue_entry}. 59 | #' @param x an object to convert to a \code{pxweb_api_catalogue_entry} object. 60 | pxweb_api_catalogue_entry <- function(x) { 61 | UseMethod("pxweb_api_catalogue_entry") 62 | } 63 | 64 | #' @rdname pxweb_api_catalogue_entry 65 | #' @export 66 | pxweb_api_catalogue_entry.list <- function(x) { 67 | class(x) <- c("pxweb_api_catalogue_entry", "list") 68 | assert_pxweb_api_catalogue_entry(x) 69 | x 70 | } 71 | 72 | #' @rdname pxweb_api_catalogue_entry 73 | #' @param x an object to assert is a \code{pxweb_api_catalogue_entry}. 74 | #' @keywords internal 75 | assert_pxweb_api_catalogue_entry <- function(x) { 76 | checkmate::assert_class(x, "pxweb_api_catalogue_entry") 77 | checkmate::assert_names(names(x), must.include = c("description", "url", "version", "lang")) 78 | if (!is.null(x$alias)) { 79 | checkmate::assert_character(x$alias, min.chars = 2) 80 | } 81 | checkmate::assert_string(x$description, min.chars = 2) 82 | checkmate::assert_string(x$url, pattern = "\\[version\\]") 83 | checkmate::assert_string(x$url, pattern = "\\[lang\\]") 84 | checkmate::assert_string(x$url, pattern = "^http") 85 | checkmate::assert_character(x$version, min.chars = 1) 86 | checkmate::assert_character(x$lang, min.chars = 1) 87 | if (!is.null(x$period_in_seconds)) { 88 | checkmate::assert_int(x$period_in_seconds, lower = 1) 89 | } 90 | if (!is.null(x$calls_per_period)) { 91 | checkmate::assert_int(x$calls_per_period, lower = 1) 92 | } 93 | if (!is.null(x$max_values_to_download)) { 94 | checkmate::assert_int(x$max_values_to_download, lower = 1) 95 | } 96 | } 97 | 98 | 99 | #' Print a catalogue entry 100 | #' @param x an object used to select a method. 101 | #' @param ... further arguments passed to or from other methods. 102 | #' @keywords internal 103 | #' @export 104 | print.pxweb_api_catalogue_entry <- function(x, ...) { 105 | cat("Api:", pxweb_api_name(x)) 106 | cat("\n ", x$description, "\n") 107 | if (length(x$alias) > 0) { 108 | cat(" ('", paste(x$alias, collapse = "', '"), "')", sep = "") 109 | cat("\n") 110 | } 111 | cat("Version(s) :", paste(x$version, collapse = ", "), "\n") 112 | cat("Language(s) :", paste(x$lang, collapse = ", "), "\n") 113 | if (!is.null(x$calls_per_period) & !is.null(x$period_in_seconds) & !is.null(x$max_values_to_download)) { 114 | cat("Limit(s) :", x$calls_per_period, "calls per", x$period_in_seconds, "sec.\n") 115 | cat(" ", x$max_values_to_download, " values per call.\n") 116 | } 117 | cat("Url template :\n", x$url, "\n") 118 | } 119 | 120 | 121 | 122 | #' @keywords internal 123 | pxweb_api_catalogue_alias_table <- function() { 124 | pxac <- pxweb_api_catalogue() 125 | dfs <- list() 126 | for (i in seq_along(pxac)) { 127 | dfs[[i]] <- data.frame( 128 | name = names(pxac)[i], 129 | alias = c(names(pxac)[i], pxac[[i]]$alias), 130 | idx = i 131 | ) 132 | } 133 | do.call(rbind, dfs) 134 | } 135 | -------------------------------------------------------------------------------- /inst/examples/ex_dimension_mining.R: -------------------------------------------------------------------------------- 1 | require(httr) 2 | require(RJSONIO) 3 | require(stringr) 4 | require(data.table) 5 | require(ggplot2) 6 | 7 | ##### EXAMPLE: HIERARCHY MINING ##### 8 | kMaxLevels = 4 9 | 10 | kTakeSample = FALSE 11 | kSamplesize = 10 12 | 13 | 14 | 15 | # RUN -------------------------------------------------------------------------- 16 | ## INIT: Define the data containers 17 | hierarchy <- as.data.table(get_pxweb_levels(descriptions=TRUE)) 18 | setnames( 19 | hierarchy, 20 | names(hierarchy), 21 | paste(names(hierarchy), "_lv1", sep = "") 22 | ) 23 | emptyRows <- list() 24 | tableAtLevel <- list() 25 | timeSeries <- data.table(obs=integer(), level=integer(), id=character(), time=numeric()) 26 | count <- 0 27 | 28 | ## Warn if kTakeSample is FALSE 29 | if (!kTakeSample) { 30 | cat("\n\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n") 31 | cat("WARNING: Fetching data ALL NODES in the SCB API.\n") 32 | cat("This might take a VERY LONG TIME!\n") 33 | cat("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n\n") 34 | 35 | } 36 | 37 | ## Run loop 38 | for (j in 2:kMaxLevels) { 39 | 40 | # Take a sample of Hierarchy to make it manageable 41 | if (kTakeSample) { 42 | hierarchy <- hierarchy[ 43 | sample( 44 | nrow(hierarchy), 45 | min(nrow(hierarchy),kSamplesize*(j-1))) 46 | ] 47 | } 48 | 49 | # Define the sublevel at which we will be looking 50 | idLevel <- j 51 | 52 | cat("*******************************************\n") 53 | cat("Getting data for level", idLevel,"\n") 54 | cat("*******************************************\n\n") 55 | 56 | # Clear input data 57 | subLevelData <- data.table( 58 | topId = character(), 59 | bottomId = character(), 60 | description = character(), 61 | URL = character() 62 | ) 63 | 64 | topLevelName <- paste0("id_lv", idLevel-1) 65 | topURLName <- paste0("URL_lv", idLevel-1) 66 | bottomLevelName <- paste0("id_lv", idLevel) 67 | bottomURLName <- paste0("URL_lv", idLevel) 68 | descName <- paste0("description_lv", idLevel) 69 | 70 | for (i in 1:nrow(hierarchy)) { 71 | count <- count + 1 72 | nodeURL <- hierarchy[i, topURLName, with=FALSE][[1]] 73 | nodeId <- hierarchy[i, topLevelName, with=FALSE][[1]] 74 | if (nodeId != "") { 75 | tid <- system.time({ 76 | 77 | ## QUICK FIX FOR BUGS IN THE SCB API: 78 | if (!nodeId %in% c("BE0001T04BAr")) { 79 | 80 | # Trim levels (some levels are returned with trailing whitespace) 81 | queryLevels <- get_pxweb_levels(path = nodeURL, descriptions=TRUE, quiet=FALSE) 82 | } else { 83 | queryLevels <- NULL 84 | } 85 | 86 | if (!is.null(queryLevels$id)) { 87 | queryData <- data.table( 88 | topId = nodeId, 89 | bottomId = as.character(queryLevels$id), 90 | description = as.character(queryLevels$description), 91 | URL = queryLevels$URL 92 | ) 93 | } else { 94 | queryData <- data.table( 95 | topId = nodeId, 96 | bottomId = "", 97 | description = "", 98 | URL = "" 99 | ) 100 | } 101 | 102 | cat("Level",j-1, "value: ",nodeId,"\n") 103 | cat("Level",j , "values:",queryData$bottomId,"\n") 104 | 105 | subLevelData <- rbind(subLevelData,queryData) 106 | }) 107 | } else { 108 | # Make sure the timestamp from the previous query doesn't cause us 109 | # to post the next query too soon 110 | tid <- c(0,0,0) 111 | } 112 | 113 | # Create time series object for analysis purposes 114 | timeSeries <- rbind(timeSeries, 115 | list(obs = count, 116 | level = j, 117 | id = nodeId, 118 | time = tid[[3]])) 119 | cat("Time taken for query:", tid[[3]],"\n\n") 120 | 121 | # Ensure we don't overdo our query limit (1/sec) by adding 122 | # 0.1-1.2 seconds sleep time, depending on past query processing time 123 | if(tid[[3]] != 0) { Sys.sleep(1.2-min(tid[[3]],1.1)) } 124 | } 125 | 126 | setnames( 127 | subLevelData, 128 | names(subLevelData), 129 | c(topLevelName, bottomLevelName, descName, bottomURLName) 130 | ) 131 | 132 | hierarchy <- merge(hierarchy,subLevelData, 133 | by = paste0(topLevelName), 134 | all.x = TRUE) 135 | 136 | # emptyRows[[j]] <- hierarchy[get(bottomLevelName) == ""] 137 | tableAtLevel[[j]] <- hierarchy 138 | 139 | if(all(hierarchy[,bottomLevelName,with=FALSE] == "") | nrow(hierarchy) == 0) { 140 | stop("Reached bottom node in all data tree paths. Stopping.") 141 | } 142 | 143 | # hierarchy <- hierarchy[get(bottomLevelName) != ""] 144 | } 145 | 146 | # Order columns 147 | hierarchy <- hierarchy[,list( 148 | id_lv1, 149 | description_lv1, 150 | URL_lv1, 151 | id_lv2, 152 | description_lv2, 153 | URL_lv2, 154 | id_lv3, 155 | description_lv3, 156 | URL_lv3, 157 | id_lv4, 158 | description_lv4, 159 | URL_lv4 160 | )] 161 | 162 | hierarchy_bk <- copy(hierarchy) 163 | save(hierarchy,file="hierarchy.RData") 164 | 165 | View(hierarchy) --------------------------------------------------------------------------------