├── .github ├── .gitignore └── workflows │ └── check-standard.yaml ├── LICENSE ├── tests ├── testthat.R └── testthat │ ├── test-load.R │ ├── test-codelist.R │ ├── test_content_type.R │ ├── test_overview.R │ ├── test_data_info.R │ ├── test_get_metadata.R │ ├── test_search.R │ └── test_get_data.R ├── vignettes ├── p_jsa.png └── introduction.Rmd ├── docs ├── articles │ ├── p_jsa.png │ ├── introduction_files │ │ ├── figure-html │ │ │ └── jsa-claimaints-1.png │ │ ├── anchor-sections-1.0 │ │ │ ├── anchor-sections.css │ │ │ └── anchor-sections.js │ │ ├── header-attrs-2.1 │ │ │ └── header-attrs.js │ │ ├── header-attrs-2.2 │ │ │ └── header-attrs.js │ │ ├── header-attrs-2.5 │ │ │ └── header-attrs.js │ │ └── header-attrs-2.7 │ │ │ └── header-attrs.js │ ├── Introduction-to-work-and-health-nomis-indicators_files │ │ ├── figure-html │ │ │ ├── Treemap-1.png │ │ │ ├── Pie_Charts-1.png │ │ │ ├── Pie_Charts-2.png │ │ │ └── Stacked_Bar-1.png │ │ ├── anchor-sections-1.0 │ │ │ ├── anchor-sections.css │ │ │ └── anchor-sections.js │ │ ├── header-attrs-2.2 │ │ │ └── header-attrs.js │ │ ├── header-attrs-2.5 │ │ │ └── header-attrs.js │ │ └── header-attrs-2.7 │ │ │ └── header-attrs.js │ └── index.html ├── reference │ ├── Rplot001.png │ ├── nomisr.html │ ├── nomis_api_key.html │ └── index.html ├── pkgdown.yml ├── docsearch.json ├── link.svg ├── sitemap.xml ├── bootstrap-toc.css ├── docsearch.js ├── jquery.sticky-kit.min.js ├── pkgdown.js ├── bootstrap-toc.js ├── LICENSE-text.html ├── 404.html ├── CONDUCT.html ├── LICENSE.html ├── CODE_OF_CONDUCT.html ├── authors.html ├── pkgdown.css └── CONTRIBUTING.html ├── inst ├── JOSS │ ├── paper_files │ │ └── figure-html │ │ │ └── plot-demo-1.png │ ├── paper.bib │ ├── paper.md │ └── paper.Rmd └── CITATION ├── .gitignore ├── R ├── utils-base-urls.R ├── utils-tidy.R ├── utils-query.R ├── dataset_info.R ├── nomisr-package.R ├── content_type.R ├── utils-get-data.R ├── api-key.R ├── codelist.R ├── search.R ├── overview.R └── metadata.R ├── nomisr.Rproj ├── cran-comments.md ├── .Rbuildignore ├── NAMESPACE ├── man ├── nomisr.Rd ├── nomis_api_key.Rd ├── nomis_data_info.Rd ├── nomis_content_type.Rd ├── nomis_codelist.Rd ├── nomis_search.Rd ├── nomis_get_metadata.Rd ├── nomis_overview.Rd └── nomis_get_data.Rd ├── LICENSE.md ├── _pkgdown.yml ├── CODE_OF_CONDUCT.md ├── DESCRIPTION ├── CONTRIBUTING.md ├── NEWS.md └── README.Rmd /.github/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | YEAR: 2018 2 | COPYRIGHT HOLDER: Evan Odell 3 | -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(nomisr) 3 | 4 | test_check("nomisr") 5 | -------------------------------------------------------------------------------- /vignettes/p_jsa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci/nomisr/HEAD/vignettes/p_jsa.png -------------------------------------------------------------------------------- /docs/articles/p_jsa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci/nomisr/HEAD/docs/articles/p_jsa.png -------------------------------------------------------------------------------- /docs/reference/Rplot001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci/nomisr/HEAD/docs/reference/Rplot001.png -------------------------------------------------------------------------------- /tests/testthat/test-load.R: -------------------------------------------------------------------------------- 1 | context("test-load.R") 2 | 3 | test_that("package loading works", { 4 | expect_silent(library(nomisr)) 5 | }) 6 | -------------------------------------------------------------------------------- /inst/JOSS/paper_files/figure-html/plot-demo-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci/nomisr/HEAD/inst/JOSS/paper_files/figure-html/plot-demo-1.png -------------------------------------------------------------------------------- /docs/pkgdown.yml: -------------------------------------------------------------------------------- 1 | pandoc: 2.17.1 2 | pkgdown: 2.0.1 3 | pkgdown_sha: ~ 4 | articles: 5 | introduction: introduction.html 6 | last_built: 2022-01-31T20:33Z 7 | 8 | -------------------------------------------------------------------------------- /docs/articles/introduction_files/figure-html/jsa-claimaints-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci/nomisr/HEAD/docs/articles/introduction_files/figure-html/jsa-claimaints-1.png -------------------------------------------------------------------------------- /docs/articles/Introduction-to-work-and-health-nomis-indicators_files/figure-html/Treemap-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci/nomisr/HEAD/docs/articles/Introduction-to-work-and-health-nomis-indicators_files/figure-html/Treemap-1.png -------------------------------------------------------------------------------- /docs/articles/Introduction-to-work-and-health-nomis-indicators_files/figure-html/Pie_Charts-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci/nomisr/HEAD/docs/articles/Introduction-to-work-and-health-nomis-indicators_files/figure-html/Pie_Charts-1.png -------------------------------------------------------------------------------- /docs/articles/Introduction-to-work-and-health-nomis-indicators_files/figure-html/Pie_Charts-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci/nomisr/HEAD/docs/articles/Introduction-to-work-and-health-nomis-indicators_files/figure-html/Pie_Charts-2.png -------------------------------------------------------------------------------- /docs/articles/Introduction-to-work-and-health-nomis-indicators_files/figure-html/Stacked_Bar-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci/nomisr/HEAD/docs/articles/Introduction-to-work-and-health-nomis-indicators_files/figure-html/Stacked_Bar-1.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .Ruserdata 5 | src/*.o 6 | src/*.so 7 | src/*.dll 8 | ropensci-issue-draft.md 9 | a.csv 10 | a.xlsx 11 | ~$a.xlsx 12 | reviewer-response.md 13 | R/nomis_overview.R 14 | .build.timestamp 15 | inst/JOSS/paper.html -------------------------------------------------------------------------------- /R/utils-base-urls.R: -------------------------------------------------------------------------------- 1 | 2 | ## Utility variables to assist query building 3 | base_url <- "https://www.nomisweb.co.uk/api/v01/dataset/" 4 | 5 | content_url <- "https://www.nomisweb.co.uk/api/v01/contenttype/" 6 | 7 | codelist_url <- "https://www.nomisweb.co.uk/api/v01/codelist/" 8 | -------------------------------------------------------------------------------- /docs/articles/introduction_files/anchor-sections-1.0/anchor-sections.css: -------------------------------------------------------------------------------- 1 | /* Styles for section anchors */ 2 | a.anchor-section {margin-left: 10px; visibility: hidden; color: inherit;} 3 | a.anchor-section::before {content: '#';} 4 | .hasAnchor:hover a.anchor-section {visibility: visible;} 5 | -------------------------------------------------------------------------------- /docs/articles/Introduction-to-work-and-health-nomis-indicators_files/anchor-sections-1.0/anchor-sections.css: -------------------------------------------------------------------------------- 1 | /* Styles for section anchors */ 2 | a.anchor-section {margin-left: 10px; visibility: hidden; color: inherit;} 3 | a.anchor-section::before {content: '#';} 4 | .hasAnchor:hover a.anchor-section {visibility: visible;} 5 | -------------------------------------------------------------------------------- /tests/testthat/test-codelist.R: -------------------------------------------------------------------------------- 1 | context("test-codelist.R") 2 | 3 | test_that("nomis_codelist is working", { 4 | skip_on_cran() 5 | 6 | codelist <- nomis_codelist("NM_1_1", "SEX") 7 | expect_type(codelist, "list") 8 | expect_true(tibble::is_tibble(codelist)) 9 | expect_true(all(c("id", "parentCode", "label.en") %in% names(codelist))) 10 | }) 11 | -------------------------------------------------------------------------------- /inst/CITATION: -------------------------------------------------------------------------------- 1 | bibentry(bibtype = "article", 2 | title = "{nomisr}: Access Nomis UK Labour Market Data With R", 3 | volume = 3, 4 | doi = "10.21105/joss.00859", 5 | number = 27, 6 | journal = "The Journal of Open Source Software", 7 | year = 2018, 8 | month = "July", 9 | pages = 859, 10 | author = c(person("Evan", "Odell"))) 11 | -------------------------------------------------------------------------------- /nomisr.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: knitr 13 | LaTeX: pdfLaTeX 14 | 15 | BuildType: Package 16 | PackageUseDevtools: Yes 17 | PackageInstallArgs: --no-multiarch --with-keep.source 18 | PackageRoxygenize: rd,collate,namespace 19 | -------------------------------------------------------------------------------- /tests/testthat/test_content_type.R: -------------------------------------------------------------------------------- 1 | library(nomisr) 2 | context("nomis_content_type") 3 | 4 | test_that("nomis_content_type return expected format", { 5 | skip_on_cran() 6 | 7 | expect_error(nomis_content_type()) 8 | 9 | content_id <- nomis_content_type("sources", "jsa") 10 | expect_true(nrow(content_id) == 1) 11 | expect_length(content_id, 4) 12 | expect_type(content_id, "list") 13 | expect_true(tibble::is_tibble(content_id)) 14 | }) 15 | -------------------------------------------------------------------------------- /docs/docsearch.json: -------------------------------------------------------------------------------- 1 | { 2 | "index_name": "nomisr", 3 | "start_urls": {}, 4 | "sitemap_urls": "/sitemap.xml", 5 | "selectors": { 6 | "lvl0": ".contents h1", 7 | "lvl1": ".contents h2", 8 | "lvl2": ".contents h3, .contents th, .contents dt", 9 | "lvl3": ".contents h4", 10 | "lvl4": ".contents h5", 11 | "text": ".contents p, .contents li, .usage, .template-article .contents .pre" 12 | }, 13 | "selectors_exclude": ".dont-index" 14 | } 15 | -------------------------------------------------------------------------------- /tests/testthat/test_overview.R: -------------------------------------------------------------------------------- 1 | library(nomisr) 2 | context("nomis_overview") 3 | 4 | 5 | test_that("nomis_overview return expected format", { 6 | skip_on_cran() 7 | 8 | q <- nomis_overview("NM_1650_1") 9 | expect_length(q, 2) 10 | expect_equal(nrow(q), 21) 11 | expect_true(tibble::is_tibble(q)) 12 | 13 | s <- nomis_overview("NM_1650_1", select = c("Units", "Keywords")) 14 | expect_length(s, 2) 15 | expect_equal(nrow(s), 3) 16 | expect_true(tibble::is_tibble(s)) 17 | 18 | expect_error(nomis_overview()) 19 | }) 20 | -------------------------------------------------------------------------------- /cran-comments.md: -------------------------------------------------------------------------------- 1 | 2 | ## Release summary 3 | 4 | This is an update of the `nomisr` package, version number 0.4.7. It requires 5 | the use of readr >= 2.1.2 to ensure calls work silently. 6 | 7 | ## Test environments 8 | * local macOS install, R 4.2.0 9 | * win-builder (devel and release) 10 | * Windows Server 2022, release (on GitHub Actions) 11 | * macOS Big Sur 11.6.6, release (on GitHub Actions) 12 | * ubuntu 20.04 (devel and release) (on GitHub Actions) 13 | 14 | ## R CMD check results 15 | 16 | 0 errors | 0 warnings | 0 notes 17 | -------------------------------------------------------------------------------- /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^CODE_OF_CONDUCT\.md$ 2 | ^.*\.Rproj$ 3 | ^\.Rproj\.user$ 4 | ^README\.Rmd$ 5 | ^README-.*\.png$ 6 | ^\.travis\.yml$ 7 | ^\.Rhistory$ 8 | ^appveyor\.yml$ 9 | ^_pkgdown\.yml$ 10 | ^ropensci-issue-draft\.md$ 11 | ^CONDUCT\.md$ 12 | ^a\.csv$ 13 | ^a\.xlsx$ 14 | ^~$a\.xlsx$ 15 | ^reviewer-response\.md$ 16 | ^R/nomis_overview\.R$ 17 | ^\.build\.timestamp$ 18 | ^LICENSE\.MD$ 19 | ^LICENSE\.md$ 20 | ^docs$ 21 | ^\.github$ 22 | ^CONTRIBUTING\.md$ 23 | ^cran-comments\.md$ 24 | CONTRIBUTING.md 25 | ^CRAN-RELEASE$ 26 | vignettes/Introduction-to-work-and-health-nomis-indicators.Rmd 27 | ^CRAN-SUBMISSION$ 28 | -------------------------------------------------------------------------------- /docs/articles/introduction_files/header-attrs-2.1/header-attrs.js: -------------------------------------------------------------------------------- 1 | // Pandoc 2.9 adds attributes on both header and div. We remove the former (to 2 | // be compatible with the behavior of Pandoc < 2.8). 3 | document.addEventListener('DOMContentLoaded', function(e) { 4 | var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); 5 | var i, h, a; 6 | for (i = 0; i < hs.length; i++) { 7 | h = hs[i]; 8 | if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 9 | a = h.attributes; 10 | while (a.length > 0) h.removeAttribute(a[0].name); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /docs/articles/introduction_files/header-attrs-2.2/header-attrs.js: -------------------------------------------------------------------------------- 1 | // Pandoc 2.9 adds attributes on both header and div. We remove the former (to 2 | // be compatible with the behavior of Pandoc < 2.8). 3 | document.addEventListener('DOMContentLoaded', function(e) { 4 | var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); 5 | var i, h, a; 6 | for (i = 0; i < hs.length; i++) { 7 | h = hs[i]; 8 | if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 9 | a = h.attributes; 10 | while (a.length > 0) h.removeAttribute(a[0].name); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /docs/articles/introduction_files/header-attrs-2.5/header-attrs.js: -------------------------------------------------------------------------------- 1 | // Pandoc 2.9 adds attributes on both header and div. We remove the former (to 2 | // be compatible with the behavior of Pandoc < 2.8). 3 | document.addEventListener('DOMContentLoaded', function(e) { 4 | var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); 5 | var i, h, a; 6 | for (i = 0; i < hs.length; i++) { 7 | h = hs[i]; 8 | if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 9 | a = h.attributes; 10 | while (a.length > 0) h.removeAttribute(a[0].name); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /docs/articles/introduction_files/header-attrs-2.7/header-attrs.js: -------------------------------------------------------------------------------- 1 | // Pandoc 2.9 adds attributes on both header and div. We remove the former (to 2 | // be compatible with the behavior of Pandoc < 2.8). 3 | document.addEventListener('DOMContentLoaded', function(e) { 4 | var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); 5 | var i, h, a; 6 | for (i = 0; i < hs.length; i++) { 7 | h = hs[i]; 8 | if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 9 | a = h.attributes; 10 | while (a.length > 0) h.removeAttribute(a[0].name); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /docs/articles/Introduction-to-work-and-health-nomis-indicators_files/header-attrs-2.2/header-attrs.js: -------------------------------------------------------------------------------- 1 | // Pandoc 2.9 adds attributes on both header and div. We remove the former (to 2 | // be compatible with the behavior of Pandoc < 2.8). 3 | document.addEventListener('DOMContentLoaded', function(e) { 4 | var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); 5 | var i, h, a; 6 | for (i = 0; i < hs.length; i++) { 7 | h = hs[i]; 8 | if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 9 | a = h.attributes; 10 | while (a.length > 0) h.removeAttribute(a[0].name); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /docs/articles/Introduction-to-work-and-health-nomis-indicators_files/header-attrs-2.5/header-attrs.js: -------------------------------------------------------------------------------- 1 | // Pandoc 2.9 adds attributes on both header and div. We remove the former (to 2 | // be compatible with the behavior of Pandoc < 2.8). 3 | document.addEventListener('DOMContentLoaded', function(e) { 4 | var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); 5 | var i, h, a; 6 | for (i = 0; i < hs.length; i++) { 7 | h = hs[i]; 8 | if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 9 | a = h.attributes; 10 | while (a.length > 0) h.removeAttribute(a[0].name); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /docs/articles/Introduction-to-work-and-health-nomis-indicators_files/header-attrs-2.7/header-attrs.js: -------------------------------------------------------------------------------- 1 | // Pandoc 2.9 adds attributes on both header and div. We remove the former (to 2 | // be compatible with the behavior of Pandoc < 2.8). 3 | document.addEventListener('DOMContentLoaded', function(e) { 4 | var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); 5 | var i, h, a; 6 | for (i = 0; i < hs.length; i++) { 7 | h = hs[i]; 8 | if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 9 | a = h.attributes; 10 | while (a.length > 0) h.removeAttribute(a[0].name); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /R/utils-tidy.R: -------------------------------------------------------------------------------- 1 | 2 | nomis_tidy <- function(df, tidy_style) { 3 | if (nrow(df) > 0) { 4 | names(df) <- tolower(names(df)) # NOMIS defaults to screaming snake case 5 | 6 | if (tidy_style == "snake_case") { 7 | case <- "snake" 8 | } else if (tidy_style == "camelCase") { 9 | case <- "small_camel" 10 | } else if (tidy_style == "period.case") { 11 | case <- "snake" 12 | } else { 13 | case <- tidy_style 14 | } 15 | names(df) <- snakecase::to_any_case(names(df), case) 16 | if (tidy_style == "period.case") { 17 | names(df) <- gsub("_", "\\.", names(df), perl = TRUE) 18 | } 19 | } 20 | df 21 | } 22 | -------------------------------------------------------------------------------- /tests/testthat/test_data_info.R: -------------------------------------------------------------------------------- 1 | library(nomisr) 2 | context("nomis_data_info") 3 | 4 | 5 | test_that("nomis_data_info return expected format", { 6 | skip_on_cran() 7 | 8 | x <- nomis_data_info() 9 | 10 | expect_length(x, 14) 11 | expect_type(x, "list") 12 | expect_true(tibble::is_tibble(x)) 13 | 14 | expect_error( 15 | nomis_data_info("lalala"), 16 | "Nomis API did not return data in required json format" 17 | ) 18 | 19 | y <- nomis_data_info("NM_1658_1", tidy = TRUE) 20 | expect_length(y, 12) 21 | expect_type(y, "list") 22 | expect_true(tibble::is_tibble(y)) 23 | expect_equal(nrow(y), 1) 24 | expect_equal(y$id, "NM_1658_1") 25 | expect_true(y$uri %in% x$uri) 26 | }) 27 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export(nomis_api_key) 4 | export(nomis_codelist) 5 | export(nomis_content_type) 6 | export(nomis_data_info) 7 | export(nomis_get_data) 8 | export(nomis_get_metadata) 9 | export(nomis_overview) 10 | export(nomis_search) 11 | importFrom(dplyr,bind_rows) 12 | importFrom(httr,GET) 13 | importFrom(httr,content) 14 | importFrom(httr,http_error) 15 | importFrom(httr,http_type) 16 | importFrom(httr,status_code) 17 | importFrom(jsonlite,fromJSON) 18 | importFrom(rlang,list2) 19 | importFrom(rsdmx,readSDMX) 20 | importFrom(snakecase,to_any_case) 21 | importFrom(snakecase,to_snake_case) 22 | importFrom(tibble,as_tibble) 23 | importFrom(tibble,enframe) 24 | importFrom(utils,menu) 25 | importFrom(utils,packageVersion) 26 | -------------------------------------------------------------------------------- /tests/testthat/test_get_metadata.R: -------------------------------------------------------------------------------- 1 | library(nomisr) 2 | context("nomis_get_metadata") 3 | 4 | test_that("nomis_get_metadata return expected format", { 5 | skip_on_cran() 6 | 7 | expect_error(nomis_get_metadata(), "The dataset ID must be specified.") 8 | 9 | b <- nomis_get_metadata("NM_1_1", "item", search = "*married*") 10 | expect_equal(nrow(b), 1) 11 | expect_true(tibble::is_tibble(b)) 12 | 13 | d <- nomis_get_metadata( 14 | id = "NM_893_1", concept = "C_AHTHUK11", type = "1" 15 | ) 16 | expect_equal(nrow(d), 1) 17 | expect_true(tibble::is_tibble(d)) 18 | 19 | e <- nomis_get_metadata( 20 | "NM_1_1", "item", 21 | geography = 1879048226, sex = 5 22 | ) 23 | expect_equal(nrow(e), 5) 24 | expect_true(tibble::is_tibble(e)) 25 | }) 26 | -------------------------------------------------------------------------------- /inst/JOSS/paper.bib: -------------------------------------------------------------------------------- 1 | @Manual{muller2018, 2 | title = {tibble: Simple Data Frames}, 3 | author = {Kirill Müller and Hadley Wickham}, 4 | year = {2018}, 5 | note = {R package version 1.4.2}, 6 | url = {https://CRAN.R-project.org/package=tibble}, 7 | } 8 | 9 | 10 | @Manual{ons1981, 11 | title = {Nomis: Official Labour Market Statistics}, 12 | author = {{Office for National Statistics}}, 13 | year = {1981}, 14 | url = {https://www.nomisweb.co.uk/}, 15 | } 16 | 17 | @Manual{henry2018, 18 | title = {rlang: Functions for Base Types and Core R and 'Tidyverse' Features}, 19 | author = {Lionel Henry and Hadley Wickham}, 20 | year = {2018}, 21 | note = {R package version 0.2.1}, 22 | url = {https://CRAN.R-project.org/package=rlang}, 23 | } -------------------------------------------------------------------------------- /man/nomisr.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/nomisr-package.R 3 | \docType{package} 4 | \name{nomisr} 5 | \alias{nomisr-package} 6 | \title{nomisr: Access Nomis UK Labour Market Data with R} 7 | \description{ 8 | Access UK official statistics from the Nomis database. Nomis 9 | includes data from the Census, the Labour Force Survey, DWP benefit 10 | statistics and other economic and demographic data from the Office for 11 | National Statistics. 12 | } 13 | \details{ 14 | The package provides functions to find what data is available, metadata, 15 | including the variables and query options for different datasets and 16 | a function for downloading data. 17 | 18 | The full API documentation and optional registration for an API key is 19 | available at \url{https://www.nomisweb.co.uk/api/v01/help}. 20 | } 21 | -------------------------------------------------------------------------------- /docs/link.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /R/utils-query.R: -------------------------------------------------------------------------------- 1 | 2 | ## utility function for queries on available data 3 | 4 | 5 | nomis_query_util <- function(query, tidy) { 6 | api_resp <- httr::GET(paste0(base_url, query)) 7 | if (http_type(api_resp) != "application/json") { 8 | stop("Nomis API did not return data in required json format", call. = FALSE) 9 | } 10 | 11 | if (httr::http_error(api_resp)) { 12 | stop( 13 | paste0( 14 | "Nomis API request failed with status ", 15 | httr::status_code(api_resp) 16 | ), 17 | call. = FALSE 18 | ) 19 | } 20 | 21 | avail_response <- jsonlite::fromJSON(api_resp$url, flatten = TRUE) 22 | 23 | df <- tibble::as_tibble(avail_response$structure$keyfamilies$keyfamily) 24 | 25 | if (nrow(df) == 0) { 26 | stop("API request did not return any results", call. = FALSE) 27 | } 28 | 29 | if (tidy) { 30 | names(df) <- snakecase::to_snake_case(names(df)) 31 | } 32 | 33 | df 34 | } 35 | -------------------------------------------------------------------------------- /man/nomis_api_key.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/api-key.R 3 | \name{nomis_api_key} 4 | \alias{nomis_api_key} 5 | \title{Nomis API Key} 6 | \usage{ 7 | nomis_api_key(check_env = FALSE) 8 | } 9 | \arguments{ 10 | \item{check_env}{If TRUE, will check the environment variable 11 | \code{NOMIS_API_KEY} first before asking for user input.} 12 | } 13 | \description{ 14 | Assign or reassign API key for Nomis. 15 | } 16 | \details{ 17 | The Nomis API has an optional key. Using the key means that 100,000 18 | rows can be returned per call, which can speed up larger data requests and 19 | reduce the chances of being rate limited or having requests timing out. 20 | 21 | By default, \code{nomisr} will look for the environment variable 22 | \code{NOMIS_API_KEY} when the package is loaded. If found, the API key will 23 | be stored in the session option \code{nomisr.API.key}. If you would like to 24 | reload the API key or would like to manually enter one in, this function 25 | may be used. 26 | 27 | You can sign up for an API key 28 | \href{https://www.nomisweb.co.uk/myaccount/userjoin.asp}{here}. 29 | } 30 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | Copyright (c) 2018 Evan Odell 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /docs/articles/introduction_files/anchor-sections-1.0/anchor-sections.js: -------------------------------------------------------------------------------- 1 | // Anchor sections v1.0 written by Atsushi Yasumoto on Oct 3rd, 2020. 2 | document.addEventListener('DOMContentLoaded', function() { 3 | // Do nothing if AnchorJS is used 4 | if (typeof window.anchors === 'object' && anchors.hasOwnProperty('hasAnchorJSLink')) { 5 | return; 6 | } 7 | 8 | const h = document.querySelectorAll('h1, h2, h3, h4, h5, h6'); 9 | 10 | // Do nothing if sections are already anchored 11 | if (Array.from(h).some(x => x.classList.contains('hasAnchor'))) { 12 | return null; 13 | } 14 | 15 | // Use section id when pandoc runs with --section-divs 16 | const section_id = function(x) { 17 | return ((x.classList.contains('section') || (x.tagName === 'SECTION')) 18 | ? x.id : ''); 19 | }; 20 | 21 | // Add anchors 22 | h.forEach(function(x) { 23 | const id = x.id || section_id(x.parentElement); 24 | if (id === '') { 25 | return null; 26 | } 27 | let anchor = document.createElement('a'); 28 | anchor.href = '#' + id; 29 | anchor.classList = ['anchor-section']; 30 | x.classList.add('hasAnchor'); 31 | x.appendChild(anchor); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /_pkgdown.yml: -------------------------------------------------------------------------------- 1 | url: https://docs.ropensci.org 2 | 3 | template: 4 | params: 5 | bootswatch: journal 6 | 7 | 8 | authors: 9 | Evan Odell: 10 | href: https://evanodell.com 11 | 12 | 13 | navbar: 14 | structure: 15 | left: [intro, reference, articles, tutorials, news, packages] 16 | right: [evan, search, github, lightswitch] 17 | components: 18 | evan: 19 | icon: fa-home fa-lg 20 | href: https://evanodell.com 21 | packages: 22 | text: "Packages" 23 | menu: 24 | - text: "Documentation Home" 25 | href: https://docs.evanodell.com 26 | - text: "---------" 27 | - text: "hansard" 28 | href: https://docs.evanodell.com/hansard 29 | - text: "mnis" 30 | href: https://docs.evanodell.com/mnis 31 | - text: "parlitools" 32 | href: https://docs.evanodell.com/parlitools 33 | - text: "nomisr" 34 | href: https://docs.evanodell.com/nomisr 35 | - text: "fixerapi" 36 | href: https://docs.evanodell.com/fixerapi 37 | - text: "refuge" 38 | href: https://docs.evanodell.com/refuge 39 | - text: "emisc" 40 | href: https://docs.evanodell.com/emisc 41 | 42 | -------------------------------------------------------------------------------- /docs/articles/Introduction-to-work-and-health-nomis-indicators_files/anchor-sections-1.0/anchor-sections.js: -------------------------------------------------------------------------------- 1 | // Anchor sections v1.0 written by Atsushi Yasumoto on Oct 3rd, 2020. 2 | document.addEventListener('DOMContentLoaded', function() { 3 | // Do nothing if AnchorJS is used 4 | if (typeof window.anchors === 'object' && anchors.hasOwnProperty('hasAnchorJSLink')) { 5 | return; 6 | } 7 | 8 | const h = document.querySelectorAll('h1, h2, h3, h4, h5, h6'); 9 | 10 | // Do nothing if sections are already anchored 11 | if (Array.from(h).some(x => x.classList.contains('hasAnchor'))) { 12 | return null; 13 | } 14 | 15 | // Use section id when pandoc runs with --section-divs 16 | const section_id = function(x) { 17 | return ((x.classList.contains('section') || (x.tagName === 'SECTION')) 18 | ? x.id : ''); 19 | }; 20 | 21 | // Add anchors 22 | h.forEach(function(x) { 23 | const id = x.id || section_id(x.parentElement); 24 | if (id === '') { 25 | return null; 26 | } 27 | let anchor = document.createElement('a'); 28 | anchor.href = '#' + id; 29 | anchor.classList = ['anchor-section']; 30 | x.classList.add('hasAnchor'); 31 | x.appendChild(anchor); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /R/dataset_info.R: -------------------------------------------------------------------------------- 1 | 2 | #' Nomis data structures 3 | #' 4 | #' Retrieve metadata on the structure and available variables for all available 5 | #' data sets or the information available in a specific dataset based on its ID. 6 | #' 7 | #' @param id Dataset ID. If empty, returns data on all available datasets. 8 | #' If the ID of a dataset, returns metadata for that particular dataset. 9 | #' 10 | #' @param tidy If `TRUE`, converts tibble names to snakecase. 11 | #' 12 | #' @return A tibble with all available datasets and their metadata. 13 | #' @export 14 | #' @seealso [nomis_get_data()] 15 | #' @seealso [nomis_get_metadata()] 16 | #' @seealso [nomis_overview()] 17 | #' @seealso [nomis_codelist()] 18 | #' 19 | #' @examples 20 | #' \donttest{ 21 | #' 22 | #' # Get info on all datasets 23 | #' x <- nomis_data_info() 24 | #' 25 | #' tibble::glimpse(x) 26 | #' 27 | #' # Get info on a particular dataset 28 | #' y <- nomis_data_info("NM_1658_1") 29 | #' 30 | #' tibble::glimpse(y) 31 | #' } 32 | #' 33 | nomis_data_info <- function(id, tidy = FALSE) { 34 | if (missing(id)) { 35 | data_info_query <- "def.sdmx.json" 36 | } else { 37 | data_info_query <- paste0(id, "/def.sdmx.json") 38 | } 39 | 40 | df <- nomis_query_util(data_info_query, tidy) 41 | 42 | df 43 | } 44 | -------------------------------------------------------------------------------- /man/nomis_data_info.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dataset_info.R 3 | \name{nomis_data_info} 4 | \alias{nomis_data_info} 5 | \title{Nomis data structures} 6 | \usage{ 7 | nomis_data_info(id, tidy = FALSE) 8 | } 9 | \arguments{ 10 | \item{id}{Dataset ID. If empty, returns data on all available datasets. 11 | If the ID of a dataset, returns metadata for that particular dataset.} 12 | 13 | \item{tidy}{If \code{TRUE}, converts tibble names to snakecase.} 14 | } 15 | \value{ 16 | A tibble with all available datasets and their metadata. 17 | } 18 | \description{ 19 | Retrieve metadata on the structure and available variables for all available 20 | data sets or the information available in a specific dataset based on its ID. 21 | } 22 | \examples{ 23 | \donttest{ 24 | 25 | # Get info on all datasets 26 | x <- nomis_data_info() 27 | 28 | tibble::glimpse(x) 29 | 30 | # Get info on a particular dataset 31 | y <- nomis_data_info("NM_1658_1") 32 | 33 | tibble::glimpse(y) 34 | } 35 | 36 | } 37 | \seealso{ 38 | \code{\link[=nomis_get_data]{nomis_get_data()}} 39 | 40 | \code{\link[=nomis_get_metadata]{nomis_get_metadata()}} 41 | 42 | \code{\link[=nomis_overview]{nomis_overview()}} 43 | 44 | \code{\link[=nomis_codelist]{nomis_codelist()}} 45 | } 46 | -------------------------------------------------------------------------------- /tests/testthat/test_search.R: -------------------------------------------------------------------------------- 1 | library(nomisr) 2 | context("nomis_search") 3 | 4 | test_that("nomis_search return expected format", { 5 | skip_on_cran() 6 | 7 | y <- nomis_search(keywords = "Claimants") 8 | expect_length(y, 14) 9 | expect_type(y, "list") 10 | expect_true(tibble::is_tibble(y)) 11 | 12 | x <- nomis_search("*seekers*") 13 | expect_length(x, 14) 14 | expect_type(x, "list") 15 | expect_true(tibble::is_tibble(x)) 16 | 17 | z <- nomis_search("*Seekers*") 18 | expect_length(z, 14) 19 | expect_type(z, "list") 20 | expect_true(tibble::is_tibble(z)) 21 | expect_equal(x[1], z[1]) 22 | expect_equal(names(x), names(z)) 23 | 24 | a_description <- nomis_search(description = c("*actively*", "*seeking*")) 25 | expect_type(a_description, "list") 26 | expect_true(tibble::is_tibble(a_description)) 27 | expect_length(a_description, 14) 28 | 29 | expect_error(nomis_search(content_type = "source")) 30 | 31 | b_content_type <- nomis_search(content_type = "sources-jsa") 32 | expect_type(b_content_type, "list") 33 | expect_true(tibble::is_tibble(b_content_type)) 34 | expect_length(b_content_type, 14) 35 | 36 | c_units <- nomis_search(units = "*person*") 37 | expect_type(c_units, "list") 38 | expect_true(tibble::is_tibble(c_units)) 39 | expect_length(c_units, 14) 40 | }) 41 | -------------------------------------------------------------------------------- /man/nomis_content_type.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/content_type.R 3 | \name{nomis_content_type} 4 | \alias{nomis_content_type} 5 | \title{Nomis dataset content types} 6 | \usage{ 7 | nomis_content_type(content_type, id = NULL) 8 | } 9 | \arguments{ 10 | \item{content_type}{A string with the content type to return metadata on.} 11 | 12 | \item{id}{A string with an optional \code{content_type} id.} 13 | } 14 | \value{ 15 | A tibble with metadata on a given content type. 16 | } 17 | \description{ 18 | Nomis content type metadata is included in annotation tags, in the form of 19 | \verb{contenttype/} in the \code{annotationtitle} column in 20 | the \code{annotations.annotation} list-column returned from 21 | \code{\link[=nomis_data_info]{nomis_data_info()}}. For example, the content types returned from 22 | dataset "NM_1658_1", using \code{nomis_data_info("NM_1658_1")}, are 23 | "geoglevel", "2001census" and "sources". 24 | } 25 | \examples{ 26 | \donttest{ 27 | a <- nomis_content_type("sources") 28 | 29 | tibble::glimpse(a) 30 | 31 | b <- nomis_content_type("sources", id = "census") 32 | 33 | tibble::glimpse(b) 34 | } 35 | 36 | } 37 | \seealso{ 38 | \code{\link[=nomis_search]{nomis_search()}} 39 | 40 | \code{\link[=nomis_data_info]{nomis_data_info()}} 41 | } 42 | -------------------------------------------------------------------------------- /R/nomisr-package.R: -------------------------------------------------------------------------------- 1 | 2 | #' nomisr: Access Nomis UK Labour Market Data with R 3 | #' 4 | #' Access UK official statistics from the Nomis database. Nomis 5 | #' includes data from the Census, the Labour Force Survey, DWP benefit 6 | #' statistics and other economic and demographic data from the Office for 7 | #' National Statistics. 8 | #' 9 | #' The package provides functions to find what data is available, metadata, 10 | #' including the variables and query options for different datasets and 11 | #' a function for downloading data. 12 | #' 13 | #' The full API documentation and optional registration for an API key is 14 | #' available at \url{https://www.nomisweb.co.uk/api/v01/help}. 15 | #' 16 | #' @docType package 17 | #' @name nomisr 18 | #' @importFrom jsonlite fromJSON 19 | #' @importFrom tibble as_tibble enframe 20 | #' @importFrom httr http_type GET http_error status_code content 21 | #' @importFrom dplyr bind_rows 22 | #' @importFrom utils menu packageVersion 23 | #' @importFrom rsdmx readSDMX 24 | #' @importFrom rlang list2 25 | #' @importFrom snakecase to_snake_case to_any_case 26 | #' @aliases NULL nomisr-package 27 | NULL 28 | 29 | # Checking for API key on package load 30 | .onLoad <- function(libname, pkgname) { 31 | if (is.null(getOption("nomisr.API.key"))) { 32 | key <- Sys.getenv("NOMIS_API_KEY") 33 | if (key != "") options("nomisr.API.key" = key) 34 | } 35 | 36 | invisible() 37 | } 38 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Code of Conduct 2 | 3 | As contributors and maintainers of this project, we pledge to respect all people who 4 | contribute through reporting issues, posting feature requests, updating documentation, 5 | submitting pull requests or patches, and other activities. 6 | 7 | We are committed to making participation in this project a harassment-free experience for 8 | everyone, regardless of level of experience, gender, gender identity and expression, 9 | sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion. 10 | 11 | Examples of unacceptable behavior by participants include the use of sexual language or 12 | imagery, derogatory comments or personal attacks, trolling, public or private harassment, 13 | insults, or other unprofessional conduct. 14 | 15 | Project maintainers have the right and responsibility to remove, edit, or reject comments, 16 | commits, code, wiki edits, issues, and other contributions that are not aligned to this 17 | Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed 18 | from the project team. 19 | 20 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by 21 | opening an issue or contacting one or more of the project maintainers. 22 | 23 | This Code of Conduct is adapted from the Contributor Covenant 24 | (https:contributor-covenant.org), version 1.0.0, available at 25 | https://contributor-covenant.org/version/1/0/0/ 26 | -------------------------------------------------------------------------------- /R/content_type.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | #' Nomis dataset content types 4 | #' 5 | #' Nomis content type metadata is included in annotation tags, in the form of 6 | #' `contenttype/` in the `annotationtitle` column in 7 | #' the `annotations.annotation` list-column returned from 8 | #' [nomis_data_info()]. For example, the content types returned from 9 | #' dataset "NM_1658_1", using `nomis_data_info("NM_1658_1")`, are 10 | #' "geoglevel", "2001census" and "sources". 11 | #' 12 | #' @param content_type A string with the content type to return metadata on. 13 | #' 14 | #' @param id A string with an optional `content_type` id. 15 | #' 16 | #' @return A tibble with metadata on a given content type. 17 | #' @export 18 | #' @seealso [nomis_search()] 19 | #' @seealso [nomis_data_info()] 20 | #' 21 | #' @examples 22 | #' \donttest{ 23 | #' a <- nomis_content_type("sources") 24 | #' 25 | #' tibble::glimpse(a) 26 | #' 27 | #' b <- nomis_content_type("sources", id = "census") 28 | #' 29 | #' tibble::glimpse(b) 30 | #' } 31 | #' 32 | nomis_content_type <- function(content_type, id = NULL) { 33 | if (missing(content_type)) { 34 | stop("content_type must be specified", call. = FALSE) 35 | } 36 | 37 | if (is.null(id)) { 38 | id_query <- "" 39 | } else { 40 | id_query <- paste0("/id/", id) 41 | } 42 | 43 | content_query <- paste0(content_url, content_type, id_query, ".json") 44 | 45 | content_query2 <- jsonlite::fromJSON(content_query, flatten = TRUE) 46 | 47 | df <- tibble::as_tibble(data.frame(content_query2$contenttype$item)) 48 | 49 | df 50 | } 51 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: nomisr 2 | Type: Package 3 | Title: Access 'Nomis' UK Labour Market Data 4 | Version: 0.4.7 5 | Authors@R: c( 6 | person( 7 | "Evan", "Odell", email = "evanodell91@gmail.com", role = c("aut", "cre"), 8 | comment = c(ORCID='0000-0003-1845-808X')), 9 | person( 10 | "Paul", "Egeler", email = "paulegeler@gmail.com", role = c("rev", "ctb")), 11 | person( 12 | "Christophe", "Dervieux", role = "rev", 13 | comment = c(ORCID='0000-0003-4474-2498')), 14 | person( 15 | "Nina", "Robery", role = "ctb", 16 | comment = "Work and Health Indicators with nomisr vignette") 17 | ) 18 | Description: Access UK official statistics from the 'Nomis' database. 19 | 'Nomis' includes data from the Census, the Labour Force Survey, DWP benefit 20 | statistics and other economic and demographic data from the Office for 21 | National Statistics, based around statistical geographies. See 22 | for full API documentation. 23 | URL: https://github.com/ropensci/nomisr, https://docs.evanodell.com/nomisr 24 | BugReports: https://github.com/ropensci/nomisr/issues 25 | License: MIT + file LICENSE 26 | Depends: R (>= 3.4.0) 27 | Imports: 28 | jsonlite, 29 | tibble, 30 | dplyr, 31 | httr, 32 | utils, 33 | rsdmx, 34 | rlang, 35 | snakecase 36 | RoxygenNote: 7.2.0 37 | Suggests: 38 | knitr, 39 | rmarkdown, 40 | testthat, 41 | purrr, 42 | tidyr, 43 | magrittr, 44 | ggplot2, 45 | scales, 46 | readr 47 | VignetteBuilder: knitr 48 | Encoding: UTF-8 49 | Roxygen: list(markdown = TRUE) 50 | -------------------------------------------------------------------------------- /R/utils-get-data.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | # utility function used in `nomis_get_data` 4 | 5 | 6 | nomis_get_data_util <- function(query) { 7 | api_get <- httr::GET(paste0(base_url, query)) 8 | if (httr::http_error(api_get)) { 9 | paste0( 10 | "Nomis API request failed with status ", 11 | httr::status_code(api_get) 12 | ) 13 | return(invisible(NULL)) 14 | } 15 | 16 | df <- tryCatch( 17 | { 18 | if (packageVersion("readr") >= "2.1.2") { 19 | httr::content(api_get, encoding = 'UTF-8', show_col_types = FALSE) 20 | } else { 21 | httr::content(api_get) 22 | } 23 | }, 24 | error = function(cond) { 25 | err <- conditionMessage(cond) 26 | if (startsWith(err, "Cannot read file")) { 27 | message( 28 | "It is likely you have included a parameter that is ", 29 | "not available to query in this dataset.\n\n", 30 | "Here's the original error message:\n", cond 31 | ) 32 | } else { 33 | message( 34 | "It is likely that you have been automatically rate limited ", 35 | "by the Nomis API.\n", 36 | "You can make smaller data requests, or try again later.\n\n", 37 | "Here's the original error message:\n", cond 38 | ) 39 | } 40 | return(NA) 41 | }, 42 | warning = function(cond) { 43 | stop("The API request did not return any results. ", 44 | "Please check your parameters.", 45 | call. = FALSE 46 | ) 47 | } 48 | ) 49 | 50 | if ("OBS_VALUE" %in% names(df)) { 51 | df$OBS_VALUE <- as.double(df$OBS_VALUE) 52 | } 53 | df 54 | } 55 | -------------------------------------------------------------------------------- /man/nomis_codelist.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/codelist.R 3 | \name{nomis_codelist} 4 | \alias{nomis_codelist} 5 | \title{Nomis codelists} 6 | \usage{ 7 | nomis_codelist(id, concept, search = NULL) 8 | } 9 | \arguments{ 10 | \item{id}{A string with the ID of the particular dataset. Must be specified.} 11 | 12 | \item{concept}{A string with the variable concept to return options for. If 13 | left empty, returns all the variables for the dataset specified by \code{id}. 14 | Codes are not case sensitive and must be specified.} 15 | 16 | \item{search}{Search for codes that contain a given string. The wildcard 17 | character \code{*} can be added to the beginning and/or end of each 18 | search string. Search strings are not case sensitive. 19 | Defaults to \code{NULL}. Note that the search function is not very powerful 20 | for some datasets.} 21 | } 22 | \value{ 23 | A tibble with the codes used to query specific concepts. 24 | } 25 | \description{ 26 | Nomis uses its own internal coding for query concepts. \code{nomis_codelist} 27 | returns the codes for a given concept in a \code{tibble}, given a dataset 28 | ID and a concept name. 29 | Note that some codelists, particularly geography, can be very large. 30 | } 31 | \examples{ 32 | \donttest{ 33 | x <- nomis_codelist("NM_1_1", "item") 34 | 35 | 36 | # Searching for codes ending with "london" 37 | y <- nomis_codelist("NM_1_1", "geography", search = "*london") 38 | 39 | 40 | z <- nomis_codelist("NM_161_1", "cause_of_death") 41 | } 42 | 43 | } 44 | \seealso{ 45 | \code{\link[=nomis_data_info]{nomis_data_info()}} 46 | 47 | \code{\link[=nomis_get_metadata]{nomis_get_metadata()}} 48 | 49 | \code{\link[=nomis_overview]{nomis_overview()}} 50 | } 51 | -------------------------------------------------------------------------------- /docs/sitemap.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | /404.html 5 | 6 | 7 | /CODE_OF_CONDUCT.html 8 | 9 | 10 | /CONDUCT.html 11 | 12 | 13 | /CONTRIBUTING.html 14 | 15 | 16 | /LICENSE-text.html 17 | 18 | 19 | /LICENSE.html 20 | 21 | 22 | /articles/Introduction-to-work-and-health-nomis-indicators.html 23 | 24 | 25 | /articles/index.html 26 | 27 | 28 | /articles/introduction.html 29 | 30 | 31 | /authors.html 32 | 33 | 34 | /index.html 35 | 36 | 37 | /news/index.html 38 | 39 | 40 | /reference/index.html 41 | 42 | 43 | /reference/nomis_api_key.html 44 | 45 | 46 | /reference/nomis_codelist.html 47 | 48 | 49 | /reference/nomis_content_type.html 50 | 51 | 52 | /reference/nomis_data_info.html 53 | 54 | 55 | /reference/nomis_get_data.html 56 | 57 | 58 | /reference/nomis_get_metadata.html 59 | 60 | 61 | /reference/nomis_overview.html 62 | 63 | 64 | /reference/nomis_search.html 65 | 66 | 67 | /reference/nomisr.html 68 | 69 | 70 | /reviewer-response.html 71 | 72 | 73 | /ropensci-issue-draft.html 74 | 75 | 76 | -------------------------------------------------------------------------------- /.github/workflows/check-standard.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 | 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 | 26 | env: 27 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 28 | R_KEEP_PKG_SOURCE: yes 29 | 30 | steps: 31 | - uses: actions/checkout@v2 32 | 33 | - uses: r-lib/actions/setup-pandoc@v1 34 | 35 | - uses: r-lib/actions/setup-r@v1 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@v1 42 | with: 43 | extra-packages: rcmdcheck 44 | 45 | - uses: r-lib/actions/check-r-package@v1 46 | 47 | - name: Show testthat output 48 | if: always() 49 | run: find check -name 'testthat.Rout*' -exec cat '{}' \; || true 50 | shell: bash 51 | 52 | - name: Upload check results 53 | if: failure() 54 | uses: actions/upload-artifact@main 55 | with: 56 | name: ${{ runner.os }}-r${{ matrix.config.r }}-results 57 | path: check 58 | -------------------------------------------------------------------------------- /R/api-key.R: -------------------------------------------------------------------------------- 1 | 2 | #' Nomis API Key 3 | #' 4 | #' @description Assign or reassign API key for Nomis. 5 | #' 6 | #' @details The Nomis API has an optional key. Using the key means that 100,000 7 | #' rows can be returned per call, which can speed up larger data requests and 8 | #' reduce the chances of being rate limited or having requests timing out. 9 | #' 10 | #' @details By default, `nomisr` will look for the environment variable 11 | #' `NOMIS_API_KEY` when the package is loaded. If found, the API key will 12 | #' be stored in the session option `nomisr.API.key`. If you would like to 13 | #' reload the API key or would like to manually enter one in, this function 14 | #' may be used. 15 | #' 16 | #' @details You can sign up for an API key 17 | #' [here](https://www.nomisweb.co.uk/myaccount/userjoin.asp). 18 | #' 19 | #' @param check_env If TRUE, will check the environment variable 20 | #' `NOMIS_API_KEY` first before asking for user input. 21 | #' 22 | #' @export 23 | nomis_api_key <- function(check_env = FALSE) { 24 | if (check_env) { 25 | key <- Sys.getenv("NOMIS_API_KEY") 26 | if (key != "") { 27 | message("Updating NOMIS_API_KEY environment variable...") 28 | options("nomisr.API.key" = key) 29 | return(invisible()) 30 | } else { 31 | warning("Couldn't find environment variable 'NOMIS_API_KEY'") 32 | } 33 | } 34 | 35 | if (interactive()) { 36 | key <- readline("Please enter your API key and press enter: ") 37 | } else { 38 | cat("Please enter your API key and press enter: ") 39 | key <- readLines(con = "stdin", n = 1) 40 | } 41 | 42 | if (identical(key, "")) { 43 | stop("Nomis API key entry failed", call. = FALSE) 44 | } 45 | 46 | message("Updating NOMIS_API_KEY environment variable...") 47 | options("nomisr.API.key" = key) 48 | invisible() 49 | } 50 | -------------------------------------------------------------------------------- /R/codelist.R: -------------------------------------------------------------------------------- 1 | 2 | #' Nomis codelists 3 | #' 4 | #' Nomis uses its own internal coding for query concepts. `nomis_codelist` 5 | #' returns the codes for a given concept in a `tibble`, given a dataset 6 | #' ID and a concept name. 7 | #' Note that some codelists, particularly geography, can be very large. 8 | #' 9 | #' @param id A string with the ID of the particular dataset. Must be specified. 10 | #' 11 | #' @param concept A string with the variable concept to return options for. If 12 | #' left empty, returns all the variables for the dataset specified by `id`. 13 | #' Codes are not case sensitive and must be specified. 14 | #' 15 | #' @param search Search for codes that contain a given string. The wildcard 16 | #' character `*` can be added to the beginning and/or end of each 17 | #' search string. Search strings are not case sensitive. 18 | #' Defaults to `NULL`. Note that the search function is not very powerful 19 | #' for some datasets. 20 | #' 21 | #' @return A tibble with the codes used to query specific concepts. 22 | #' @export 23 | #' @seealso [nomis_data_info()] 24 | #' @seealso [nomis_get_metadata()] 25 | #' @seealso [nomis_overview()] 26 | #' 27 | #' @examples 28 | #' \donttest{ 29 | #' x <- nomis_codelist("NM_1_1", "item") 30 | #' 31 | #' 32 | #' # Searching for codes ending with "london" 33 | #' y <- nomis_codelist("NM_1_1", "geography", search = "*london") 34 | #' 35 | #' 36 | #' z <- nomis_codelist("NM_161_1", "cause_of_death") 37 | #' } 38 | #' 39 | nomis_codelist <- function(id, concept, search = NULL) { 40 | if (missing(id)) { 41 | stop("id must be specified", call. = FALSE) 42 | } 43 | 44 | id_query <- paste0(gsub("NM", "CL", id), "_") 45 | 46 | search_query <- ifelse(is.null(search), "", paste0("?search=", search)) 47 | 48 | code_query <- paste0( 49 | codelist_url, id_query, concept, 50 | ".def.sdmx.xml", search_query 51 | ) 52 | 53 | df <- tibble::as_tibble(rsdmx::readSDMX(code_query)) 54 | 55 | df 56 | } 57 | -------------------------------------------------------------------------------- /docs/bootstrap-toc.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Table of Contents v0.4.1 (http://afeld.github.io/bootstrap-toc/) 3 | * Copyright 2015 Aidan Feldman 4 | * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ 5 | 6 | /* modified from https://github.com/twbs/bootstrap/blob/94b4076dd2efba9af71f0b18d4ee4b163aa9e0dd/docs/assets/css/src/docs.css#L548-L601 */ 7 | 8 | /* All levels of nav */ 9 | nav[data-toggle='toc'] .nav > li > a { 10 | display: block; 11 | padding: 4px 20px; 12 | font-size: 13px; 13 | font-weight: 500; 14 | color: #767676; 15 | } 16 | nav[data-toggle='toc'] .nav > li > a:hover, 17 | nav[data-toggle='toc'] .nav > li > a:focus { 18 | padding-left: 19px; 19 | color: #563d7c; 20 | text-decoration: none; 21 | background-color: transparent; 22 | border-left: 1px solid #563d7c; 23 | } 24 | nav[data-toggle='toc'] .nav > .active > a, 25 | nav[data-toggle='toc'] .nav > .active:hover > a, 26 | nav[data-toggle='toc'] .nav > .active:focus > a { 27 | padding-left: 18px; 28 | font-weight: bold; 29 | color: #563d7c; 30 | background-color: transparent; 31 | border-left: 2px solid #563d7c; 32 | } 33 | 34 | /* Nav: second level (shown on .active) */ 35 | nav[data-toggle='toc'] .nav .nav { 36 | display: none; /* Hide by default, but at >768px, show it */ 37 | padding-bottom: 10px; 38 | } 39 | nav[data-toggle='toc'] .nav .nav > li > a { 40 | padding-top: 1px; 41 | padding-bottom: 1px; 42 | padding-left: 30px; 43 | font-size: 12px; 44 | font-weight: normal; 45 | } 46 | nav[data-toggle='toc'] .nav .nav > li > a:hover, 47 | nav[data-toggle='toc'] .nav .nav > li > a:focus { 48 | padding-left: 29px; 49 | } 50 | nav[data-toggle='toc'] .nav .nav > .active > a, 51 | nav[data-toggle='toc'] .nav .nav > .active:hover > a, 52 | nav[data-toggle='toc'] .nav .nav > .active:focus > a { 53 | padding-left: 28px; 54 | font-weight: 500; 55 | } 56 | 57 | /* from https://github.com/twbs/bootstrap/blob/e38f066d8c203c3e032da0ff23cd2d6098ee2dd6/docs/assets/css/src/docs.css#L631-L634 */ 58 | nav[data-toggle='toc'] .nav > .active > ul { 59 | display: block; 60 | } 61 | -------------------------------------------------------------------------------- /man/nomis_search.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/search.R 3 | \name{nomis_search} 4 | \alias{nomis_search} 5 | \title{Search Nomis datasets} 6 | \usage{ 7 | nomis_search( 8 | name = NULL, 9 | description = NULL, 10 | keywords = NULL, 11 | content_type = NULL, 12 | units = NULL, 13 | tidy = FALSE 14 | ) 15 | } 16 | \arguments{ 17 | \item{name}{A string or character vector of strings to search for in 18 | available dataset names. Defaults to \code{NULL}.} 19 | 20 | \item{description}{A string or character vector of strings to search for in 21 | available dataset descriptions. Note that \code{description} looks for 22 | complete matches, so wildcards should be used at the start and end of 23 | each string. Defaults to \code{NULL}.} 24 | 25 | \item{keywords}{A string or character vector of strings to search for in 26 | available dataset keywords. Defaults to \code{NULL}.} 27 | 28 | \item{content_type}{A string or character vector of strings to search for 29 | in available dataset content types. \code{content_type} can include an 30 | optional ID for that content type. Defaults to \code{NULL}.} 31 | 32 | \item{units}{A string or character vector of strings to search for in 33 | available dataset units. Defaults to \code{NULL}.} 34 | 35 | \item{tidy}{If \code{TRUE}, converts tibble names to snakecase.} 36 | } 37 | \value{ 38 | A tibble with details on all datasets matching the search query. 39 | } 40 | \description{ 41 | A function to search for datasets on given topics. In the case of multiple 42 | search parameters, returns metadata on all datasets matching one or more 43 | of the parameters. The wildcard character \code{*} can be added to the 44 | beginning and/or end of each search string. 45 | } 46 | \examples{ 47 | \donttest{ 48 | x <- nomis_search(name = "*seekers*") 49 | 50 | y <- nomis_search(keywords = "Claimants") 51 | 52 | # Return metadata of all datasets with content_type "sources". 53 | a <- nomis_search(content_type = "sources") 54 | 55 | 56 | # Return metadata of all datasets with content_type "sources" and 57 | # source ID "acses" 58 | b <- nomis_search(content_type = "sources-acses") 59 | } 60 | 61 | } 62 | \seealso{ 63 | \code{\link[=nomis_content_type]{nomis_content_type()}} 64 | } 65 | -------------------------------------------------------------------------------- /docs/docsearch.js: -------------------------------------------------------------------------------- 1 | $(function() { 2 | 3 | // register a handler to move the focus to the search bar 4 | // upon pressing shift + "/" (i.e. "?") 5 | $(document).on('keydown', function(e) { 6 | if (e.shiftKey && e.keyCode == 191) { 7 | e.preventDefault(); 8 | $("#search-input").focus(); 9 | } 10 | }); 11 | 12 | $(document).ready(function() { 13 | // do keyword highlighting 14 | /* modified from https://jsfiddle.net/julmot/bL6bb5oo/ */ 15 | var mark = function() { 16 | 17 | var referrer = document.URL ; 18 | var paramKey = "q" ; 19 | 20 | if (referrer.indexOf("?") !== -1) { 21 | var qs = referrer.substr(referrer.indexOf('?') + 1); 22 | var qs_noanchor = qs.split('#')[0]; 23 | var qsa = qs_noanchor.split('&'); 24 | var keyword = ""; 25 | 26 | for (var i = 0; i < qsa.length; i++) { 27 | var currentParam = qsa[i].split('='); 28 | 29 | if (currentParam.length !== 2) { 30 | continue; 31 | } 32 | 33 | if (currentParam[0] == paramKey) { 34 | keyword = decodeURIComponent(currentParam[1].replace(/\+/g, "%20")); 35 | } 36 | } 37 | 38 | if (keyword !== "") { 39 | $(".contents").unmark({ 40 | done: function() { 41 | $(".contents").mark(keyword); 42 | } 43 | }); 44 | } 45 | } 46 | }; 47 | 48 | mark(); 49 | }); 50 | }); 51 | 52 | /* Search term highlighting ------------------------------*/ 53 | 54 | function matchedWords(hit) { 55 | var words = []; 56 | 57 | var hierarchy = hit._highlightResult.hierarchy; 58 | // loop to fetch from lvl0, lvl1, etc. 59 | for (var idx in hierarchy) { 60 | words = words.concat(hierarchy[idx].matchedWords); 61 | } 62 | 63 | var content = hit._highlightResult.content; 64 | if (content) { 65 | words = words.concat(content.matchedWords); 66 | } 67 | 68 | // return unique words 69 | var words_uniq = [...new Set(words)]; 70 | return words_uniq; 71 | } 72 | 73 | function updateHitURL(hit) { 74 | 75 | var words = matchedWords(hit); 76 | var url = ""; 77 | 78 | if (hit.anchor) { 79 | url = hit.url_without_anchor + '?q=' + escape(words.join(" ")) + '#' + hit.anchor; 80 | } else { 81 | url = hit.url + '?q=' + escape(words.join(" ")); 82 | } 83 | 84 | return url; 85 | } 86 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to `nomisr` 2 | 3 | Thank you for any and all contributions! Following these guidelines will help streamline the process of contributing and make sure that we're all on the same page. While we ask that you read this guide and follow it to the best of your abilities, we welcome contributions from all, regardless of your level of experience. 4 | 5 | By participating in this project, you agree to abide by the [code of conduct](https://github.com/ropensci/nomisr/blob/master/CONDUCT.md). 6 | 7 | # Types of contributions 8 | 9 | Don't feel that you must be a computer whiz to make meaningful contributions. Feel free to: 10 | 11 | - Identify areas for future development ([open an Issue](https://github.com/ropensci/nomisr/issues)) 12 | - Identify issues/bugs ([open an Issue](https://github.com/ropensci/nomisr/issues)) 13 | - Write tutorials/vignettes ([open a Pull Request](https://github.com/ropensci/nomisr/pulls) to contribute to the ones here, or make your own elsewhere and send us a link) 14 | - Add functionality ([open a Pull Request](https://github.com/ropensci/nomisr/pulls)) 15 | - Fix bugs ([open a Pull Request](https://github.com/ropensci/nomisr/pulls)) 16 | 17 | # New to GitHub? 18 | 19 | Getting ready to make your first contribution? Here are a couple of tutorials you may wish to check out: 20 | 21 | - [Tutorial for first-timers](https://github.com/Roshanjossey/first-contributions) 22 | - [How to contribute (in-depth lessons)](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github) 23 | - [GitHub on setup](https://help.github.com/articles/set-up-git) 24 | - [GitHub on pull requests](https://help.github.com/articles/using-pull-requests/).) 25 | 26 | 27 | # How to contribute code 28 | 29 | - Fork the repository 30 | - Clone the repository from GitHub to your computer e.g,. `git clone https://github.com/ropensci/nomisr.git` 31 | - Make sure to track progress upstream (i.e., on our version of `nomisr` at `ropensci/nomisr`) 32 | - `git remote add upstream https://github.com/ropensci/nomisr.git` 33 | - Before making changes make sure to pull changes in from upstream with `git pull upstream` 34 | - Make your changes 35 | - For changes beyond minor typos, add an item to NEWS.md describing the changes and add yourself to the DESCRIPTION file as a contributor 36 | - Push to your GitHub account 37 | - Submit a pull request to home base (likely master branch, but check to make sure) at `ropensci/nomisr` 38 | 39 | # Code formatting 40 | 41 | - In general follow the convention of (snake_case functions and argument names, etc.) 42 | - Where there is conflict, default to the style of `nomisr` 43 | - Use explicit package imports (i.e. package_name::package_function) and avoid @import if at all possible 44 | -------------------------------------------------------------------------------- /docs/jquery.sticky-kit.min.js: -------------------------------------------------------------------------------- 1 | /* Sticky-kit v1.1.2 | WTFPL | Leaf Corcoran 2015 | */ 2 | /* 3 | Source: https://github.com/leafo/sticky-kit 4 | License: MIT 5 | */ 6 | (function(){var b,f;b=this.jQuery||window.jQuery;f=b(window);b.fn.stick_in_parent=function(d){var A,w,J,n,B,K,p,q,k,E,t;null==d&&(d={});t=d.sticky_class;B=d.inner_scrolling;E=d.recalc_every;k=d.parent;q=d.offset_top;p=d.spacer;w=d.bottoming;null==q&&(q=0);null==k&&(k=void 0);null==B&&(B=!0);null==t&&(t="is_stuck");A=b(document);null==w&&(w=!0);J=function(a,d,n,C,F,u,r,G){var v,H,m,D,I,c,g,x,y,z,h,l;if(!a.data("sticky_kit")){a.data("sticky_kit",!0);I=A.height();g=a.parent();null!=k&&(g=g.closest(k)); 7 | if(!g.length)throw"failed to find stick parent";v=m=!1;(h=null!=p?p&&a.closest(p):b("
"))&&h.css("position",a.css("position"));x=function(){var c,f,e;if(!G&&(I=A.height(),c=parseInt(g.css("border-top-width"),10),f=parseInt(g.css("padding-top"),10),d=parseInt(g.css("padding-bottom"),10),n=g.offset().top+c+f,C=g.height(),m&&(v=m=!1,null==p&&(a.insertAfter(h),h.detach()),a.css({position:"",top:"",width:"",bottom:""}).removeClass(t),e=!0),F=a.offset().top-(parseInt(a.css("margin-top"),10)||0)-q, 8 | u=a.outerHeight(!0),r=a.css("float"),h&&h.css({width:a.outerWidth(!0),height:u,display:a.css("display"),"vertical-align":a.css("vertical-align"),"float":r}),e))return l()};x();if(u!==C)return D=void 0,c=q,z=E,l=function(){var b,l,e,k;if(!G&&(e=!1,null!=z&&(--z,0>=z&&(z=E,x(),e=!0)),e||A.height()===I||x(),e=f.scrollTop(),null!=D&&(l=e-D),D=e,m?(w&&(k=e+u+c>C+n,v&&!k&&(v=!1,a.css({position:"fixed",bottom:"",top:c}).trigger("sticky_kit:unbottom"))),eb&&!v&&(c-=l,c=Math.max(b-u,c),c=Math.min(q,c),m&&a.css({top:c+"px"})))):e>F&&(m=!0,b={position:"fixed",top:c},b.width="border-box"===a.css("box-sizing")?a.outerWidth()+"px":a.width()+"px",a.css(b).addClass(t),null==p&&(a.after(h),"left"!==r&&"right"!==r||h.append(a)),a.trigger("sticky_kit:stick")),m&&w&&(null==k&&(k=e+u+c>C+n),!v&&k)))return v=!0,"static"===g.css("position")&&g.css({position:"relative"}), 10 | a.css({position:"absolute",bottom:d,top:"auto"}).trigger("sticky_kit:bottom")},y=function(){x();return l()},H=function(){G=!0;f.off("touchmove",l);f.off("scroll",l);f.off("resize",y);b(document.body).off("sticky_kit:recalc",y);a.off("sticky_kit:detach",H);a.removeData("sticky_kit");a.css({position:"",bottom:"",top:"",width:""});g.position("position","");if(m)return null==p&&("left"!==r&&"right"!==r||a.insertAfter(h),h.remove()),a.removeClass(t)},f.on("touchmove",l),f.on("scroll",l),f.on("resize", 11 | y),b(document.body).on("sticky_kit:recalc",y),a.on("sticky_kit:detach",H),setTimeout(l,0)}};n=0;for(K=this.length;n 38 | Figure 1. Data retrieved with `nomisr` is ready for plotting. 39 | 40 | 41 | `nomisr` is available on GitHub at . 42 | 43 | # Acknowledgements 44 | 45 | I thank Paul Egeler for his contributions to `nomisr` and his code review comments, and Christophe Dervieux for his code review comments. 46 | 47 | 48 | # References 49 | -------------------------------------------------------------------------------- /man/nomis_overview.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/overview.R 3 | \name{nomis_overview} 4 | \alias{nomis_overview} 5 | \title{Nomis dataset overview} 6 | \usage{ 7 | nomis_overview(id, select = NULL) 8 | } 9 | \arguments{ 10 | \item{id}{The ID of the particular dataset. Returns no data if not specified.} 11 | 12 | \item{select}{A string or character vector of one or more overview parts to 13 | select, excluding all others. \code{select} is not case sensitive. The 14 | options for \code{select} are described below, and are taken from the 15 | \href{https://www.nomisweb.co.uk/api/v01/help}{Nomis API help page}.} 16 | } 17 | \value{ 18 | A tibble with two columns, one a character vector with the name of 19 | the metadata category, and the other a list column of values for each 20 | category. 21 | } 22 | \description{ 23 | Returns an overview of available metadata for a given dataset. 24 | } 25 | \section{Overview part options}{ 26 | 27 | 28 | \describe{ 29 | \item{DatasetInfo}{General dataset information such as name, description, 30 | sub-description, mnemonic, restricted access and status} 31 | \item{Coverage}{Shows the geographic coverage of the main geography 32 | dimension in this dataset (e.g. United Kingdom, England and Wales etc.)} 33 | \item{Keywords}{The keywords allocated to the dataset} 34 | \item{Units}{The units of measure supported by the dataset} 35 | \item{ContentTypes}{The classifications allocated to this dataset} 36 | \item{DateMetadata}{Information about the first release, last update and 37 | next update} 38 | \item{Contact}{Details for the point of contact for this dataset} 39 | \item{Analyses}{Show the available analysis breakdowns of this dataset} 40 | \item{Dimensions}{Individual dimension information (e.g. sex, geography, 41 | date, etc.)} 42 | \item{Dimension-concept}{Allows a specific dimension to be selected (e.g. 43 | dimension-geography would allow information about geography dimension). This 44 | is not used if "Dimensions" is specified too.} 45 | \item{Codes}{Full list of selectable codes, excluding Geography, which as a 46 | list of Types instead. (Requires "Dimensions" to be selected too)} 47 | \item{Codes-concept}{Full list of selectable codes for a specific dimension, 48 | excluding Geography, which as a list of Types instead. This is not used if 49 | "Codes" is specified too (Requires "Dimensions" or equivalent to be 50 | selected too)} 51 | \item{DimensionMetadata}{Any available metadata attached at the dimensional 52 | level (Requires "Dimensions" or equivalent to be selected too)} 53 | \item{Make}{Information about whether user defined codes can be created with 54 | the MAKE parameter when querying data (Requires "Dimensions" or equivalent 55 | to be selected too)} 56 | \item{DatasetMetadata}{Metadata attached at the dataset level} 57 | } 58 | } 59 | 60 | \examples{ 61 | \donttest{ 62 | library(dplyr) 63 | 64 | q <- nomis_overview("NM_1650_1") 65 | 66 | q \%>\% 67 | tidyr::unnest(name) \%>\% 68 | glimpse() 69 | 70 | s <- nomis_overview("NM_1650_1", select = c("Units", "Keywords")) 71 | 72 | s \%>\% 73 | tidyr::unnest(name) \%>\% 74 | glimpse() 75 | } 76 | 77 | } 78 | \seealso{ 79 | \code{\link[=nomis_data_info]{nomis_data_info()}} 80 | 81 | \code{\link[=nomis_get_metadata]{nomis_get_metadata()}} 82 | } 83 | -------------------------------------------------------------------------------- /R/search.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | #' Search Nomis datasets 4 | #' 5 | #' A function to search for datasets on given topics. In the case of multiple 6 | #' search parameters, returns metadata on all datasets matching one or more 7 | #' of the parameters. The wildcard character `*` can be added to the 8 | #' beginning and/or end of each search string. 9 | #' 10 | #' @param name A string or character vector of strings to search for in 11 | #' available dataset names. Defaults to `NULL`. 12 | #' 13 | #' @param description A string or character vector of strings to search for in 14 | #' available dataset descriptions. Note that `description` looks for 15 | #' complete matches, so wildcards should be used at the start and end of 16 | #' each string. Defaults to `NULL`. 17 | #' 18 | #' @param keywords A string or character vector of strings to search for in 19 | #' available dataset keywords. Defaults to `NULL`. 20 | #' 21 | #' @param content_type A string or character vector of strings to search for 22 | #' in available dataset content types. `content_type` can include an 23 | #' optional ID for that content type. Defaults to `NULL`. 24 | #' 25 | #' @param units A string or character vector of strings to search for in 26 | #' available dataset units. Defaults to `NULL`. 27 | #' 28 | #' @param tidy If `TRUE`, converts tibble names to snakecase. 29 | #' 30 | #' @return A tibble with details on all datasets matching the search query. 31 | #' @export 32 | #' @seealso [nomis_content_type()] 33 | #' 34 | #' @examples 35 | #' \donttest{ 36 | #' x <- nomis_search(name = "*seekers*") 37 | #' 38 | #' y <- nomis_search(keywords = "Claimants") 39 | #' 40 | #' # Return metadata of all datasets with content_type "sources". 41 | #' a <- nomis_search(content_type = "sources") 42 | #' 43 | #' 44 | #' # Return metadata of all datasets with content_type "sources" and 45 | #' # source ID "acses" 46 | #' b <- nomis_search(content_type = "sources-acses") 47 | #' } 48 | #' 49 | nomis_search <- function(name = NULL, description = NULL, 50 | keywords = NULL, content_type = NULL, units = NULL, 51 | tidy = FALSE) { 52 | if (length(name) > 0) { 53 | name_query <- paste0( 54 | "&search=name-", 55 | paste0(name, collapse = ",") 56 | ) 57 | } else { 58 | name_query <- "" 59 | } 60 | 61 | if (length(description) > 0) { 62 | description_query <- paste0( 63 | "&search=description-", 64 | paste0(description, collapse = ",") 65 | ) 66 | } else { 67 | description_query <- "" 68 | } 69 | 70 | if (length(keywords) > 0) { 71 | keywords_query <- paste0( 72 | "&search=keywords-", 73 | paste0(keywords, collapse = ",") 74 | ) 75 | } else { 76 | keywords_query <- "" 77 | } 78 | 79 | if (length(content_type) > 0) { 80 | content_type_query <- paste0( 81 | "&search=contenttype-", 82 | paste0(content_type, collapse = ",") 83 | ) 84 | } else { 85 | content_type_query <- "" 86 | } 87 | 88 | if (length(units) > 0) { 89 | units_query <- paste0( 90 | "&search=units-", 91 | paste0(units, collapse = ",") 92 | ) 93 | } else { 94 | units_query <- "" 95 | } 96 | 97 | query <- paste0( 98 | "def.sdmx.json?", name_query, description_query, 99 | keywords_query, content_type_query, units_query 100 | ) 101 | 102 | df <- nomis_query_util(query, tidy) 103 | 104 | df 105 | } 106 | -------------------------------------------------------------------------------- /R/overview.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | #' Nomis dataset overview 4 | #' 5 | #' Returns an overview of available metadata for a given dataset. 6 | #' 7 | #' @param id The ID of the particular dataset. Returns no data if not specified. 8 | #' 9 | #' @param select A string or character vector of one or more overview parts to 10 | #' select, excluding all others. `select` is not case sensitive. The 11 | #' options for `select` are described below, and are taken from the 12 | #' \href{https://www.nomisweb.co.uk/api/v01/help}{Nomis API help page}. 13 | #' 14 | #' @return A tibble with two columns, one a character vector with the name of 15 | #' the metadata category, and the other a list column of values for each 16 | #' category. 17 | #' 18 | #' @section Overview part options: 19 | #' 20 | #' \describe{ 21 | #' \item{DatasetInfo}{General dataset information such as name, description, 22 | #' sub-description, mnemonic, restricted access and status} 23 | #' \item{Coverage}{Shows the geographic coverage of the main geography 24 | #' dimension in this dataset (e.g. United Kingdom, England and Wales etc.)} 25 | #' \item{Keywords}{The keywords allocated to the dataset} 26 | #' \item{Units}{The units of measure supported by the dataset} 27 | #' \item{ContentTypes}{The classifications allocated to this dataset} 28 | #' \item{DateMetadata}{Information about the first release, last update and 29 | #' next update} 30 | #' \item{Contact}{Details for the point of contact for this dataset} 31 | #' \item{Analyses}{Show the available analysis breakdowns of this dataset} 32 | #' \item{Dimensions}{Individual dimension information (e.g. sex, geography, 33 | #' date, etc.)} 34 | #' \item{Dimension-concept}{Allows a specific dimension to be selected (e.g. 35 | #' dimension-geography would allow information about geography dimension). This 36 | #' is not used if "Dimensions" is specified too.} 37 | #' \item{Codes}{Full list of selectable codes, excluding Geography, which as a 38 | #' list of Types instead. (Requires "Dimensions" to be selected too)} 39 | #' \item{Codes-concept}{Full list of selectable codes for a specific dimension, 40 | #' excluding Geography, which as a list of Types instead. This is not used if 41 | #' "Codes" is specified too (Requires "Dimensions" or equivalent to be 42 | #' selected too)} 43 | #' \item{DimensionMetadata}{Any available metadata attached at the dimensional 44 | #' level (Requires "Dimensions" or equivalent to be selected too)} 45 | #' \item{Make}{Information about whether user defined codes can be created with 46 | #' the MAKE parameter when querying data (Requires "Dimensions" or equivalent 47 | #' to be selected too)} 48 | #' \item{DatasetMetadata}{Metadata attached at the dataset level} 49 | #' } 50 | #' 51 | #' @export 52 | #' 53 | #' @seealso [nomis_data_info()] 54 | #' @seealso [nomis_get_metadata()] 55 | #' 56 | #' @examples 57 | #' \donttest{ 58 | #' library(dplyr) 59 | #' 60 | #' q <- nomis_overview("NM_1650_1") 61 | #' 62 | #' q %>% 63 | #' tidyr::unnest(name) %>% 64 | #' glimpse() 65 | #' 66 | #' s <- nomis_overview("NM_1650_1", select = c("Units", "Keywords")) 67 | #' 68 | #' s %>% 69 | #' tidyr::unnest(name) %>% 70 | #' glimpse() 71 | #' } 72 | #' 73 | nomis_overview <- function(id, select = NULL) { 74 | if (missing(id)) { 75 | stop("The dataset ID must be specified.", call. = FALSE) 76 | } 77 | 78 | select_query <- ifelse(is.null(select), "", 79 | paste0( 80 | "?select=", 81 | paste0(select, collapse = ",") 82 | ) 83 | ) 84 | 85 | query <- paste0(base_url, id, ".overview.json", select_query) 86 | 87 | s <- jsonlite::fromJSON(query, flatten = TRUE) 88 | 89 | df <- tibble::enframe(s$overview) 90 | 91 | df 92 | } 93 | -------------------------------------------------------------------------------- /docs/pkgdown.js: -------------------------------------------------------------------------------- 1 | /* http://gregfranko.com/blog/jquery-best-practices/ */ 2 | (function($) { 3 | $(function() { 4 | 5 | $('.navbar-fixed-top').headroom(); 6 | 7 | $('body').css('padding-top', $('.navbar').height() + 10); 8 | $(window).resize(function(){ 9 | $('body').css('padding-top', $('.navbar').height() + 10); 10 | }); 11 | 12 | $('[data-toggle="tooltip"]').tooltip(); 13 | 14 | var cur_path = paths(location.pathname); 15 | var links = $("#navbar ul li a"); 16 | var max_length = -1; 17 | var pos = -1; 18 | for (var i = 0; i < links.length; i++) { 19 | if (links[i].getAttribute("href") === "#") 20 | continue; 21 | // Ignore external links 22 | if (links[i].host !== location.host) 23 | continue; 24 | 25 | var nav_path = paths(links[i].pathname); 26 | 27 | var length = prefix_length(nav_path, cur_path); 28 | if (length > max_length) { 29 | max_length = length; 30 | pos = i; 31 | } 32 | } 33 | 34 | // Add class to parent
  • , and enclosing
  • if in dropdown 35 | if (pos >= 0) { 36 | var menu_anchor = $(links[pos]); 37 | menu_anchor.parent().addClass("active"); 38 | menu_anchor.closest("li.dropdown").addClass("active"); 39 | } 40 | }); 41 | 42 | function paths(pathname) { 43 | var pieces = pathname.split("/"); 44 | pieces.shift(); // always starts with / 45 | 46 | var end = pieces[pieces.length - 1]; 47 | if (end === "index.html" || end === "") 48 | pieces.pop(); 49 | return(pieces); 50 | } 51 | 52 | // Returns -1 if not found 53 | function prefix_length(needle, haystack) { 54 | if (needle.length > haystack.length) 55 | return(-1); 56 | 57 | // Special case for length-0 haystack, since for loop won't run 58 | if (haystack.length === 0) { 59 | return(needle.length === 0 ? 0 : -1); 60 | } 61 | 62 | for (var i = 0; i < haystack.length; i++) { 63 | if (needle[i] != haystack[i]) 64 | return(i); 65 | } 66 | 67 | return(haystack.length); 68 | } 69 | 70 | /* Clipboard --------------------------*/ 71 | 72 | function changeTooltipMessage(element, msg) { 73 | var tooltipOriginalTitle=element.getAttribute('data-original-title'); 74 | element.setAttribute('data-original-title', msg); 75 | $(element).tooltip('show'); 76 | element.setAttribute('data-original-title', tooltipOriginalTitle); 77 | } 78 | 79 | if(ClipboardJS.isSupported()) { 80 | $(document).ready(function() { 81 | var copyButton = ""; 82 | 83 | $("div.sourceCode").addClass("hasCopyButton"); 84 | 85 | // Insert copy buttons: 86 | $(copyButton).prependTo(".hasCopyButton"); 87 | 88 | // Initialize tooltips: 89 | $('.btn-copy-ex').tooltip({container: 'body'}); 90 | 91 | // Initialize clipboard: 92 | var clipboardBtnCopies = new ClipboardJS('[data-clipboard-copy]', { 93 | text: function(trigger) { 94 | return trigger.parentNode.textContent.replace(/\n#>[^\n]*/g, ""); 95 | } 96 | }); 97 | 98 | clipboardBtnCopies.on('success', function(e) { 99 | changeTooltipMessage(e.trigger, 'Copied!'); 100 | e.clearSelection(); 101 | }); 102 | 103 | clipboardBtnCopies.on('error', function() { 104 | changeTooltipMessage(e.trigger,'Press Ctrl+C or Command+C to copy'); 105 | }); 106 | }); 107 | } 108 | })(window.jQuery || window.$) 109 | -------------------------------------------------------------------------------- /inst/JOSS/paper.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'nomisr: Access ''Nomis'' UK Labour Market Data' 3 | authors: 4 | - affiliation: '1' 5 | name: Evan Odell 6 | orcid: 0000-0003-1845-808X 7 | date: "`r Sys.Date()`" 8 | output: 9 | html_document: 10 | keep_md: yes 11 | bibliography: paper.bib 12 | tags: 13 | - R 14 | - geography 15 | - official statistics 16 | affiliations: 17 | - index: 1 18 | name: Disability Rights UK 19 | --- 20 | 21 | ```{r options, message=FALSE, warning=FALSE, include=FALSE} 22 | library(nomisr) 23 | library(ggplot2) 24 | library(dplyr) 25 | 26 | knitr::opts_chunk$set(cache = FALSE) 27 | 28 | options(width = 90, tibble.max_extra_cols = 0) 29 | ``` 30 | 31 | The University of Durham runs the Nomis database of labour market statistics on behalf of the UK's Office for National Statistics [-@ons1981]. As of publication, Nomis contains 1,249 datasets, almost all of which are based around differing statistical geographies. All the data is freely available and does not require users to create accounts to download data, and Nomis provides an interactive web platform for downloading data. However, like all GUI downloading systems, there is a risk that users will select the wrong option without realising their mistake, and downloading multiple datasets is tedious, repetitive work. The `nomisr` package provides functions to identify datasets available through Nomis, the variables and query options for those datasets, and a function for downloading data, including combining large datasets into a single `tibble` [@muller2018] 32 | 33 | `nomisr` is designed around a three stage workflow, with functions for each stage: 34 | 35 | 1. Identifying available datasets, using the `nomis_data_info()` without any parameters to return a tibble with the names and basic metadata of all available datasets, or the `nomis_search()` function to retrieve a tibble of datasets matching a given search term. 36 | 37 | 1. Identifying metadata, including "concepts", the name Nomis uses for variables that can be specified when retrieving data. This is done using the `nomis_get_metadata()` function. 38 | 39 | 1. Downloading data, using the `nomis_get_data()` function, which requires the ID of a given dataset, and accepts parameters specifying the geographic concept (either all geographies of a given area type or one or more specific geographic areas of a given type) and any other concepts used to specify queries. 40 | 41 | `nomisr` is able to return specific releases of a given dataset (to aid reproducible research) or the most recent available data. The `nomis_get_data()` function includes common parameters built into the function, and also accepts unquoted concepts and concept values using quasiquotation [@henry2018], in order to accomodate the wide range of concepts used by different Nomis datasets. 42 | 43 | Data downloaded with `nomisr` is in a `tibble` that is ready for plotting (see Figure 1) or mapping with other R packages. Specifying geographies in `nomisr` requires using Nomis' internal geography coding, but all data downloads include standard ONS geography codes to aid mapping. 44 | 45 | ```{r plot-demo, echo=FALSE, message=FALSE, warning=FALSE, dpi = 600} 46 | 47 | mort_data <- nomis_get_data(id = "NM_161_1", date = "2016", 48 | geography = "TYPE480", 49 | cause_of_death = "440", 50 | sex = 0, age = 0, MEASURE = 6) 51 | 52 | mort_data <- mort_data %>% 53 | arrange(OBS_VALUE) %>% # sort your dataframe 54 | mutate(GEOGRAPHY_NAME = factor(GEOGRAPHY_NAME, unique(GEOGRAPHY_NAME))) # 55 | 56 | blood_cancer <- ggplot(mort_data, aes(x = GEOGRAPHY_NAME, 57 | y = OBS_VALUE, fill = OBS_VALUE)) + 58 | geom_col() + 59 | scale_fill_viridis_c(option = "plasma", name = "% of Deaths") + 60 | labs(title = "Percentage of Total Deaths from Blood Cancers", 61 | subtitle = "Regions of England and Wales, 2016") + 62 | xlab("Region") + 63 | ylab("Percentage of Deaths") + 64 | theme(legend.position="none", 65 | axis.text.x = element_text(angle=30, hjust=1)) 66 | 67 | blood_cancer 68 | ``` 69 | Figure 1. Data retrieved with `nomisr` is ready for plotting. 70 | 71 | 72 | `nomisr` is available on GitHub at . 73 | 74 | # Acknowledgements 75 | 76 | I thank Paul Egeler for his contributions to `nomisr` and his code review comments, and Christophe Dervieux for his code review comments. 77 | 78 | 79 | # References 80 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # nomisr 0.4.7 4 | 5 | * Checks for readr version to avoid error when reading CSV content 6 | (#31 thanks owenjonesuob and AlexStead) 7 | 8 | * Sets encoding to UTF-8 for csv files. 9 | 10 | # nomisr 0.4.5 11 | 12 | * Better error message when API returns empty data in some circumstances. 13 | 14 | * Suppressed printing of column types when reading CSV files (#25, thanks jackobailey) 15 | 16 | * Removed 2nd vignette due to errors 17 | 18 | 19 | # nomisr 0.4.4 20 | 21 | * replaced `as.tibble` with `as_tibble` 22 | 23 | * Includes second vignette "Work and Health Indicators with nomisr" 24 | 25 | # nomisr 0.4.3 26 | 27 | * Fix readme links 28 | 29 | # nomisr 0.4.2 30 | 31 | * Error handling improvements when using non-existent parameters, and clarifies 32 | error messages when no data is available for a given query. 33 | 34 | * Removes redundant call to API (#19), thanks @Chrisjb 35 | 36 | * New `tidy` parameter in `nomis_get_metadata()` to convert names to snake_case. 37 | 38 | * Now using the `snakecase` package to implement name cleaning, 39 | providing a broader range of naming styles. 40 | 41 | * `nomis_get_metadata()` now makes existence of time concept explicit in the 42 | tibble returned by `nomis_get_metadata({id})`. 43 | 44 | 45 | # nomisr 0.4.1 46 | 47 | * Adding `query_id` parameter to `nomis_get_data()` 48 | 49 | * Changed documentation to use `roxygen` markdown 50 | 51 | ## Bug fixes 52 | 53 | * Fixed bug where the `select` parameter in `nomis_get_data()` didn't work if 54 | "OBS_VALUE" was not one of the variables. (@JimShady, #12) 55 | 56 | 57 | # nomisr 0.4.0 58 | 59 | * Version bump for CRAN 60 | 61 | * Citation now refers to JOSS paper 62 | 63 | * Some minor changes to internal code for easier maintenance 64 | 65 | * Documentation updates to clarify difference between `time` and `date` 66 | parameters in `nomis_get_data()` 67 | 68 | 69 | # nomisr 0.3.2 (non-CRAN release) 70 | 71 | ## New features and function changes 72 | 73 | * The `tidy` parameter in `nomis_get_data()` now defaults to `FALSE` in order 74 | to preserve existing workflows. 75 | 76 | # nomisr 0.3.1 (non-CRAN release) 77 | 78 | ## New features and function changes 79 | 80 | * `nomis_get_data()` now includes `tidy` and `tidy_style` parameters. 81 | `nomis_get_data()` now defaults to converting all variable names to 82 | "snake_case". `tidy_style` also accepts "camelCase" and "period.case" as name 83 | style options. 84 | 85 | ## Bug fixes 86 | 87 | * Dot queries to `nomis_get_data()` work with case-insensitive measurements 88 | more persistently. 89 | 90 | ## Other updates 91 | 92 | * Clarification of need to specified as `NULL` unused named parameters in 93 | `nomis_get_data()` when using similarly named parameters in `...`. 94 | 95 | # nomisr 0.3.0 96 | 97 | ## New features and function changes 98 | 99 | * New `nomis_codelist()` function, which returns the internal coding for 100 | different concepts used by the NOMIS API in a `tibble`, given a dataset 101 | ID and a concept name. 102 | 103 | * The `additional_queries` parameter in `nomis_get_data()` and 104 | `nomis_get_metadata()` has been deprecated and will eventually be removed. 105 | Please use the `...` parameter for queries including concepts not available 106 | through the default parameters. 107 | 108 | * The `sex` parameter in `nomis_get_data()` will also work with datasets that 109 | use "gender" instead of "sex". 110 | 111 | ## Internal changes and bug fixes 112 | 113 | * Uses `rsdmx` to parse metadata, fixing #7. 114 | 115 | # nomisr 0.2.0 116 | 117 | * Improved API key handling (#5) 118 | 119 | * Increased test coverage 120 | 121 | * Adding rOpenSci reviewers to DESCRIPTION file. 122 | 123 | 124 | # nomisr 0.1.0 125 | 126 | * Moved to rOpenSci github repository 127 | 128 | * Added API key functionality, which is not required by the API but is 129 | useful for large requests. 130 | 131 | * In interactive sessions, users are asked if they want to continue when 132 | calling more than 15 pages of data at a time. 133 | 134 | # nomisr 0.0.2 135 | 136 | * Introduction of additional parameters to the `nomis_get_data()` and 137 | `nomis_codes()` functions, improvements to documentation. 138 | 139 | # nomisr 0.0.1 140 | 141 | * 1st release. Rudimentary functions for retrieving information on available 142 | datasets and downloading datasets from nomis, with some limited parameters. 143 | 144 | -------------------------------------------------------------------------------- /R/metadata.R: -------------------------------------------------------------------------------- 1 | 2 | #' Nomis metadata concepts and types 3 | #' 4 | #' @description Retrieve all concept code options of all Nomis datasets, 5 | #' concept code options for a given dataset, or the all the options for a given 6 | #' concept variable from a particular dataset. Specifying `concept` will 7 | #' return all the options for a given variable in a particular dataset. 8 | #' 9 | #' @description If looking for a more detailed overview of all available 10 | #' metadata for a given dataset, see [nomis_overview()]. 11 | #' 12 | #' @param id The ID of the particular dataset. Returns no data if not specified. 13 | #' 14 | #' @param concept A string with the variable concept to return options for. If 15 | #' left empty, returns all the variables for the dataset specified by `id`. 16 | #' Codes are not case sensitive. Defaults to `NULL`. 17 | #' 18 | #' @param type A string with options for a particular code value, to return 19 | #' types of variables available for a given code. Defaults to `NULL`. If 20 | #' `concept == NULL`, `type` will be ignored. 21 | #' 22 | #' @param search A string or character vector of strings to search for in the 23 | #' metadata. Defaults to `NULL`. As in [nomis_search()], the 24 | #' wildcard character `*` can be added to the beginning and/or end of each 25 | #' search string. 26 | #' 27 | #' @param additional_queries Any other additional queries to pass to the API. 28 | #' See \url{https://www.nomisweb.co.uk/api/v01/help} for instructions on 29 | #' query structure. Defaults to `NULL`. Deprecated in package 30 | #' versions greater than 0.2.0 and will eventually be removed. 31 | #' 32 | #' @param ... Use to pass any other parameters to the API. 33 | #' 34 | #' @param tidy If `TRUE`, converts tibble names to snakecase. 35 | #' 36 | #' @seealso [nomis_data_info()] 37 | #' @seealso [nomis_get_data()] 38 | #' @seealso [nomis_overview()] 39 | #' 40 | #' @return A tibble with metadata options for queries using [nomis_get_data()]. 41 | #' @export 42 | #' 43 | #' @examples 44 | #' \donttest{ 45 | #' a <- nomis_get_metadata("NM_1_1") 46 | #' 47 | #' print(a) 48 | #' 49 | #' b <- nomis_get_metadata("NM_1_1", "geography") 50 | #' 51 | #' tibble::glimpse(b) 52 | #' 53 | #' # returns all types of geography 54 | #' c <- nomis_get_metadata("NM_1_1", "geography", "TYPE") 55 | #' 56 | #' tibble::glimpse(c) 57 | #' 58 | #' # returns geography types available within Wigan 59 | #' d <- nomis_get_metadata("NM_1_1", "geography", "1879048226") 60 | #' 61 | #' tibble::glimpse(d) 62 | #' 63 | #' e <- nomis_get_metadata("NM_1_1", "item", geography = 1879048226, sex = 5) 64 | #' 65 | #' print(e) 66 | #' 67 | #' f <- nomis_get_metadata("NM_1_1", "item", search = "*married*") 68 | #' 69 | #' tibble::glimpse(f) 70 | #' } 71 | #' 72 | nomis_get_metadata <- function(id, concept = NULL, type = NULL, search = NULL, 73 | additional_queries = NULL, ..., tidy = FALSE) { 74 | if (missing(id)) { 75 | stop("The dataset ID must be specified.", call. = FALSE) 76 | } 77 | 78 | # Warning message for additional queries 79 | if (length(additional_queries) > 0) { 80 | additional_query <- additional_queries 81 | 82 | message("The `additional_query` parameter is 83 | deprecated, please use `...` instead") 84 | } else { 85 | additional_query <- NULL 86 | } 87 | 88 | if (is.null(concept)) { 89 | no_code_q <- nomis_data_info(id) 90 | 91 | df1 <- tibble::as_tibble( 92 | as.data.frame(no_code_q$components.dimension) 93 | ) 94 | 95 | names(no_code_q) <- gsub("components.timedimension.", "", 96 | names(no_code_q), 97 | fixed = TRUE 98 | ) 99 | 100 | no_code_q <- no_code_q[c("codelist", "conceptref")] 101 | 102 | df <- bind_rows(df1, no_code_q) 103 | 104 | df$isfrequencydimension[is.na(df$isfrequencydimension)] <- "false" 105 | } else { 106 | type_query <- ifelse(is.null(type), "", paste0("/", type)) 107 | 108 | search_query <- ifelse(is.null(search), "", 109 | paste0( 110 | "&search=", 111 | paste0(search, collapse = ",") 112 | ) 113 | ) 114 | 115 | dots <- rlang::list2(...) ## eval the dots 116 | 117 | dots_list <- c() 118 | 119 | for (i in seq_along(dots)) { # retrieve the dots 120 | dots_list[i] <- ifelse(length(dots[[i]]) > 0, 121 | paste0( 122 | "&", names(dots[i]), "=", 123 | paste0(dots[[i]], collapse = ",") 124 | ), 125 | "" 126 | ) 127 | } 128 | 129 | dots_query <- paste0(dots_list, collapse = "") 130 | 131 | df <- tibble::as_tibble(rsdmx::readSDMX( 132 | paste0( 133 | base_url, id, "/", concept, 134 | type_query, "/def.sdmx.xml?", 135 | search_query, 136 | additional_queries, dots_query 137 | ) 138 | )) 139 | } 140 | 141 | if (tidy) { 142 | names(df) <- snakecase::to_snake_case(names(df)) 143 | } 144 | 145 | df 146 | } 147 | -------------------------------------------------------------------------------- /docs/bootstrap-toc.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Table of Contents v0.4.1 (http://afeld.github.io/bootstrap-toc/) 3 | * Copyright 2015 Aidan Feldman 4 | * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ 5 | (function() { 6 | 'use strict'; 7 | 8 | window.Toc = { 9 | helpers: { 10 | // return all matching elements in the set, or their descendants 11 | findOrFilter: function($el, selector) { 12 | // http://danielnouri.org/notes/2011/03/14/a-jquery-find-that-also-finds-the-root-element/ 13 | // http://stackoverflow.com/a/12731439/358804 14 | var $descendants = $el.find(selector); 15 | return $el.filter(selector).add($descendants).filter(':not([data-toc-skip])'); 16 | }, 17 | 18 | generateUniqueIdBase: function(el) { 19 | var text = $(el).text(); 20 | var anchor = text.trim().toLowerCase().replace(/[^A-Za-z0-9]+/g, '-'); 21 | return anchor || el.tagName.toLowerCase(); 22 | }, 23 | 24 | generateUniqueId: function(el) { 25 | var anchorBase = this.generateUniqueIdBase(el); 26 | for (var i = 0; ; i++) { 27 | var anchor = anchorBase; 28 | if (i > 0) { 29 | // add suffix 30 | anchor += '-' + i; 31 | } 32 | // check if ID already exists 33 | if (!document.getElementById(anchor)) { 34 | return anchor; 35 | } 36 | } 37 | }, 38 | 39 | generateAnchor: function(el) { 40 | if (el.id) { 41 | return el.id; 42 | } else { 43 | var anchor = this.generateUniqueId(el); 44 | el.id = anchor; 45 | return anchor; 46 | } 47 | }, 48 | 49 | createNavList: function() { 50 | return $(''); 51 | }, 52 | 53 | createChildNavList: function($parent) { 54 | var $childList = this.createNavList(); 55 | $parent.append($childList); 56 | return $childList; 57 | }, 58 | 59 | generateNavEl: function(anchor, text) { 60 | var $a = $(''); 61 | $a.attr('href', '#' + anchor); 62 | $a.text(text); 63 | var $li = $('
  • '); 64 | $li.append($a); 65 | return $li; 66 | }, 67 | 68 | generateNavItem: function(headingEl) { 69 | var anchor = this.generateAnchor(headingEl); 70 | var $heading = $(headingEl); 71 | var text = $heading.data('toc-text') || $heading.text(); 72 | return this.generateNavEl(anchor, text); 73 | }, 74 | 75 | // Find the first heading level (`

    `, then `

    `, etc.) that has more than one element. Defaults to 1 (for `

    `). 76 | getTopLevel: function($scope) { 77 | for (var i = 1; i <= 6; i++) { 78 | var $headings = this.findOrFilter($scope, 'h' + i); 79 | if ($headings.length > 1) { 80 | return i; 81 | } 82 | } 83 | 84 | return 1; 85 | }, 86 | 87 | // returns the elements for the top level, and the next below it 88 | getHeadings: function($scope, topLevel) { 89 | var topSelector = 'h' + topLevel; 90 | 91 | var secondaryLevel = topLevel + 1; 92 | var secondarySelector = 'h' + secondaryLevel; 93 | 94 | return this.findOrFilter($scope, topSelector + ',' + secondarySelector); 95 | }, 96 | 97 | getNavLevel: function(el) { 98 | return parseInt(el.tagName.charAt(1), 10); 99 | }, 100 | 101 | populateNav: function($topContext, topLevel, $headings) { 102 | var $context = $topContext; 103 | var $prevNav; 104 | 105 | var helpers = this; 106 | $headings.each(function(i, el) { 107 | var $newNav = helpers.generateNavItem(el); 108 | var navLevel = helpers.getNavLevel(el); 109 | 110 | // determine the proper $context 111 | if (navLevel === topLevel) { 112 | // use top level 113 | $context = $topContext; 114 | } else if ($prevNav && $context === $topContext) { 115 | // create a new level of the tree and switch to it 116 | $context = helpers.createChildNavList($prevNav); 117 | } // else use the current $context 118 | 119 | $context.append($newNav); 120 | 121 | $prevNav = $newNav; 122 | }); 123 | }, 124 | 125 | parseOps: function(arg) { 126 | var opts; 127 | if (arg.jquery) { 128 | opts = { 129 | $nav: arg 130 | }; 131 | } else { 132 | opts = arg; 133 | } 134 | opts.$scope = opts.$scope || $(document.body); 135 | return opts; 136 | } 137 | }, 138 | 139 | // accepts a jQuery object, or an options object 140 | init: function(opts) { 141 | opts = this.helpers.parseOps(opts); 142 | 143 | // ensure that the data attribute is in place for styling 144 | opts.$nav.attr('data-toggle', 'toc'); 145 | 146 | var $topContext = this.helpers.createChildNavList(opts.$nav); 147 | var topLevel = this.helpers.getTopLevel(opts.$scope); 148 | var $headings = this.helpers.getHeadings(opts.$scope, topLevel); 149 | this.helpers.populateNav($topContext, topLevel, $headings); 150 | } 151 | }; 152 | 153 | $(function() { 154 | $('nav[data-toggle="toc"]').each(function(i, el) { 155 | var $nav = $(el); 156 | Toc.init($nav); 157 | }); 158 | }); 159 | })(); 160 | -------------------------------------------------------------------------------- /README.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | output: github_document 3 | --- 4 | 5 | 6 | 7 | ```{r, echo = FALSE} 8 | knitr::opts_chunk$set( 9 | collapse = TRUE, 10 | comment = "#>", 11 | fig.path = "README-" 12 | ) 13 | ``` 14 | 15 | # nomisr 16 | 17 | 18 | [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) 19 | [![CRAN_Status_Badge](https://www.r-pkg.org/badges/version/nomisr)](https://cran.r-project.org/package=nomisr) 20 | [![GitHub tag](https://img.shields.io/github/tag/ropensci/nomisr.svg)](https://github.com/ropensci/nomisr) 21 | [![](https://cranlogs.r-pkg.org/badges/grand-total/nomisr)](https://cran.r-project.org/package=nomisr) 22 | [![R build status](https://github.com/ropensci/nomisr/workflows/R-CMD-check/badge.svg)](https://github.com/ropensci/nomisr/actions) 23 | [![Coverage Status](https://img.shields.io/codecov/c/github/ropensci/nomisr/master.svg)](https://codecov.io/github/ropensci/nomisr?branch=master) 24 | [![ropensci](https://badges.ropensci.org/190_status.svg)](https://github.com/ropensci/software-review/issues/190) 25 | [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.1157908.svg)](https://doi.org/10.5281/zenodo.1157908) 26 | [![DOI](https://joss.theoj.org/papers/10.21105/joss.00859/status.svg)](https://doi.org/10.21105/joss.00859) 27 | 28 | 29 | `nomisr` is for accessing UK official statistics from the [Nomis](https://www.nomisweb.co.uk/) database through R. Nomis contains data from the Census, the Labour Force Survey, DWP benefit statistics and other economic and demographic data, and is maintained on behalf of the Office for National Statistics by the University of Durham. 30 | 31 | The `nomisr` package provides functions to find what data is available, the variables and query options for different datasets and a function for downloading data. `nomisr` returns data in [`tibble`](https://cran.r-project.org/package=tibble) format. Most of the data available through `nomisr` is based around statistical geographies, with a handful of exceptions. 32 | 33 | The package is for demographers, economists, geographers, public health researchers and any other researchers who are interested in geographic factors. The package aims to aid reproducibility, reduce the need to manually download area profiles, and allow easy linking of different datasets covering the same geographic area. 34 | 35 | ## Installation 36 | 37 | `nomisr` is available on CRAN: 38 | 39 | ```{r cran-installation, eval = FALSE} 40 | install.packages("nomisr") 41 | ``` 42 | 43 | You can install the development version `nomisr` from github with: 44 | 45 | ```{r gh-installation, eval = FALSE} 46 | # install.packages("devtools") 47 | devtools::install_github("ropensci/nomisr") 48 | ``` 49 | 50 | ## Using `nomisr` 51 | 52 | `nomisr` contains functions to search for datasets, identify the query options for different datasets and retrieve data from queries, all done with [`tibbles`](https://tibble.tidyverse.org/), to take advantage of how `tibble` manages list-columns. The use of metadata queries, rather than simply downloading all available data, is useful to avoid overwhelming the rate limits of the API. 53 | 54 | There are `nomisr` vignette [introduction](https://docs.evanodell.com/nomisr/articles/introduction.html) has details on all available functions and basic demonstrations of their use. 55 | 56 | The example below demonstrates a workflow to retrieve the latest data on Jobseeker's Allowance with rates and proportions, on a national level, with all male claimants and workforce. 57 | 58 | ```{r example} 59 | library(nomisr) 60 | jobseekers_search <- nomis_search(name = "*Jobseeker*") 61 | 62 | tibble::glimpse(jobseekers_search) 63 | 64 | jobseekers_measures <- nomis_get_metadata("NM_1_1", "measures") 65 | 66 | tibble::glimpse(jobseekers_measures) 67 | 68 | jobseekers_geography <- nomis_get_metadata("NM_1_1", "geography", "TYPE") 69 | 70 | tail(jobseekers_geography) 71 | 72 | jobseekers_sex <- nomis_get_metadata("NM_1_1", "sex", "TYPE") 73 | 74 | tibble::glimpse(jobseekers_sex) 75 | 76 | z <- nomis_get_data(id = "NM_1_1", time = "latest", geography = "TYPE499", 77 | measures=c(20100, 20201), sex=5) 78 | 79 | tibble::glimpse(z) 80 | ``` 81 | 82 | There is a lot of data available through Nomis, and there are some limits to the amount of data that can be retrieved within a certain period of time, although those are not published. For more details, see the [full API documentation](https://www.nomisweb.co.uk/api/v01/help) from Nomis. Full package documentation is available at [docs.evanodell.com/nomisr](https://docs.evanodell.com/nomisr). 83 | 84 | 85 | ## Meta 86 | 87 | Bug reports, suggestions, and code contributions are all welcome. Please see [CONTRIBUTING.md](https://github.com/ropensci/nomisr/blob/master/CONTRIBUTING.md) for details. 88 | 89 | Please note that this project is released with a [Contributor Code of Conduct](https://github.com/ropensci/nomisr/blob/master/CODE_OF_CONDUCT.md). By participating in this project you agree to abide by its terms. 90 | 91 | Please note that this project is not affiliated with the Office for National Statistics or the University of Durham (who run Nomis on behalf of the Office for National Statistics). 92 | 93 | Please use the reference below when citing `nomisr`, or use `citation(package = 'nomisr')`. 94 | 95 | Odell, (2018). nomisr: Access 'Nomis' UK Labour Market Data. _Journal of Open Source Software_, 3(27), 859, doi: [10.21105/joss.00859](https://doi.org/10.21105/joss.00859). 96 | 97 | A BibTeX entry for LaTeX users is 98 | ``` 99 | @Article{odell2018, 100 | title = {{nomisr}: Access Nomis UK Labour Market Data With R}, 101 | volume = {3}, 102 | doi = {10.21105/joss.00859}, 103 | number = {27}, 104 | journal = {The Journal of Open Source Software}, 105 | year = {2018}, 106 | month = {July}, 107 | pages = {859}, 108 | author = {Evan Odell}, 109 | } 110 | ``` 111 | License: [MIT](https://github.com/ropensci/nomisr/blob/master/LICENSE.md) 112 | 113 | [![ropensci_footer](https://ropensci.org/public_images/ropensci_footer.png)](https://ropensci.org) 114 | 115 | -------------------------------------------------------------------------------- /docs/articles/index.html: -------------------------------------------------------------------------------- 1 | 2 | Articles • nomisr 6 | 7 | 8 |
    9 |
    84 | 85 | 86 | 87 |
    88 |
    89 | 92 | 93 |
    94 |

    All vignettes

    95 |

    96 | 97 |
    Introduction to nomisr
    98 |
    99 |
    100 |
    101 |
    102 | 103 | 104 |
    107 | 108 |
    109 |

    Site built with pkgdown 110 | 2.0.1.

    111 |
    112 | 113 |
    114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /docs/LICENSE-text.html: -------------------------------------------------------------------------------- 1 | 2 | License • nomisr 6 | 7 | 8 |
    9 |
    84 | 85 | 86 | 87 |
    88 |
    89 | 92 | 93 |
    YEAR: 2018
     94 | COPYRIGHT HOLDER: Evan Odell
     95 | 
    96 | 97 |
    98 | 99 | 102 | 103 |
    104 | 105 | 106 | 107 |
    110 | 111 |
    112 |

    Site built with pkgdown 113 | 2.0.1.

    114 |
    115 | 116 |
    117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | -------------------------------------------------------------------------------- /docs/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Page not found (404) • nomisr 9 | 10 | 11 | 12 | 13 | 14 | 15 | 19 | 20 | 21 | 22 | 23 |
    24 |
    108 | 109 | 110 | 111 | 112 |
    113 |
    114 | 117 | 118 | Content not found. Please use links in the navbar. 119 | 120 |
    121 | 122 | 126 | 127 |
    128 | 129 | 130 | 131 |
    135 | 136 |
    137 |

    138 |

    Site built with pkgdown 139 | 2.0.1.

    140 |
    141 | 142 |
    143 |
    144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | -------------------------------------------------------------------------------- /docs/CONDUCT.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Contributor Code of Conduct • nomisr 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 44 | 45 | 46 | 47 | 48 | 55 | 56 | 57 | 58 | 59 |
    60 |
    61 | 143 | 144 | 145 |
    146 | 147 |
    148 |
    149 | 152 | 153 |
    154 | 155 |

    As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.

    156 |

    We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.

    157 |

    Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.

    158 |

    Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.

    159 |

    Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.

    160 |

    This Code of Conduct is adapted from the Contributor Covenant (https:contributor-covenant.org), version 1.0.0, available at https://contributor-covenant.org/version/1/0/0/

    161 |
    162 | 163 |
    164 | 165 |
    166 | 167 | 168 |
    169 | 172 | 173 |
    174 |

    Site built with pkgdown.

    175 |
    176 | 177 |
    178 |
    179 | 180 | 181 | 182 | 183 | 184 | 185 | -------------------------------------------------------------------------------- /docs/LICENSE.html: -------------------------------------------------------------------------------- 1 | 2 | MIT License • nomisr 6 | 7 | 8 |
    9 |
    84 | 85 | 86 | 87 |
    88 |
    89 | 92 | 93 |
    94 | 95 |

    Copyright (c) 2018 Evan Odell

    96 |

    Permission is hereby granted, free of charge, to any person obtaining 97 | a copy of this software and associated documentation files (the 98 | “Software”), to deal in the Software without restriction, including 99 | without limitation the rights to use, copy, modify, merge, publish, 100 | distribute, sublicense, and/or sell copies of the Software, and to 101 | permit persons to whom the Software is furnished to do so, subject to 102 | the following conditions:

    103 |

    The above copyright notice and this permission notice shall be 104 | included in all copies or substantial portions of the Software.

    105 |

    THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, 106 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 107 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 108 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 109 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 110 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 111 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

    112 |
    113 | 114 |
    115 | 116 | 119 | 120 |
    121 | 122 | 123 | 124 |
    127 | 128 |
    129 |

    Site built with pkgdown 130 | 2.0.1.

    131 |
    132 | 133 |
    134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | -------------------------------------------------------------------------------- /docs/reference/nomisr.html: -------------------------------------------------------------------------------- 1 | 2 | nomisr: Access Nomis UK Labour Market Data with R — nomisr • nomisr 9 | 10 | 11 |
    12 |
    87 | 88 | 89 | 90 |
    91 |
    92 | 97 | 98 |
    99 |

    Access UK official statistics from the Nomis database. Nomis 100 | includes data from the Census, the Labour Force Survey, DWP benefit 101 | statistics and other economic and demographic data from the Office for 102 | National Statistics.

    103 |
    104 | 105 | 106 |
    107 |

    Details

    108 |

    The package provides functions to find what data is available, metadata, 109 | including the variables and query options for different datasets and 110 | a function for downloading data.

    111 |

    The full API documentation and optional registration for an API key is 112 | available at https://www.nomisweb.co.uk/api/v01/help.

    113 |
    114 | 115 |
    116 | 119 |
    120 | 121 | 122 |
    125 | 126 |
    127 |

    Site built with pkgdown 128 | 2.0.1.

    129 |
    130 | 131 |
    132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | -------------------------------------------------------------------------------- /docs/CODE_OF_CONDUCT.html: -------------------------------------------------------------------------------- 1 | 2 | Contributor Code of Conduct • nomisr 6 | 7 | 8 |
    9 |
    84 | 85 | 86 | 87 |
    88 |
    89 | 92 | 93 |
    94 | 95 |

    As contributors and maintainers of this project, we pledge to respect 96 | all people who contribute through reporting issues, posting feature 97 | requests, updating documentation, submitting pull requests or patches, 98 | and other activities.

    99 |

    We are committed to making participation in this project a 100 | harassment-free experience for everyone, regardless of level of 101 | experience, gender, gender identity and expression, sexual orientation, 102 | disability, personal appearance, body size, race, ethnicity, age, or 103 | religion.

    104 |

    Examples of unacceptable behavior by participants include the use of 105 | sexual language or imagery, derogatory comments or personal attacks, 106 | trolling, public or private harassment, insults, or other unprofessional 107 | conduct.

    108 |

    Project maintainers have the right and responsibility to remove, 109 | edit, or reject comments, commits, code, wiki edits, issues, and other 110 | contributions that are not aligned to this Code of Conduct. Project 111 | maintainers who do not follow the Code of Conduct may be removed from 112 | the project team.

    113 |

    Instances of abusive, harassing, or otherwise unacceptable behavior 114 | may be reported by opening an issue or contacting one or more of the 115 | project maintainers.

    116 |

    This Code of Conduct is adapted from the Contributor Covenant (https:contributor-covenant.org), version 1.0.0, 117 | available at https://contributor-covenant.org/version/1/0/0/

    118 |
    119 | 120 |
    121 | 122 | 125 | 126 |
    127 | 128 | 129 | 130 |
    133 | 134 |
    135 |

    Site built with pkgdown 136 | 2.0.1.

    137 |
    138 | 139 |
    140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /docs/reference/nomis_api_key.html: -------------------------------------------------------------------------------- 1 | 2 | Nomis API Key — nomis_api_key • nomisr 6 | 7 | 8 |
    9 |
    84 | 85 | 86 | 87 |
    88 |
    89 | 94 | 95 |
    96 |

    Assign or reassign API key for Nomis.

    97 |
    98 | 99 |
    100 |
    nomis_api_key(check_env = FALSE)
    101 |
    102 | 103 |
    104 |

    Arguments

    105 |
    check_env
    106 |

    If TRUE, will check the environment variable 107 | NOMIS_API_KEY first before asking for user input.

    108 |
    109 |
    110 |

    Details

    111 |

    The Nomis API has an optional key. Using the key means that 100,000 112 | rows can be returned per call, which can speed up larger data requests and 113 | reduce the chances of being rate limited or having requests timing out.

    114 |

    By default, nomisr will look for the environment variable 115 | NOMIS_API_KEY when the package is loaded. If found, the API key will 116 | be stored in the session option nomisr.API.key. If you would like to 117 | reload the API key or would like to manually enter one in, this function 118 | may be used.

    119 |

    You can sign up for an API key 120 | here.

    121 |
    122 | 123 |
    124 | 127 |
    128 | 129 | 130 |
    133 | 134 |
    135 |

    Site built with pkgdown 136 | 2.0.1.

    137 |
    138 | 139 |
    140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /docs/authors.html: -------------------------------------------------------------------------------- 1 | 2 | Authors and Citation • nomisr 6 | 7 | 8 |
    9 |
    84 | 85 | 86 | 87 |
    88 |
    89 |
    90 | 93 | 94 | 95 |
    • 96 |

      Evan Odell. Author, maintainer. 97 |

      98 |
    • 99 |
    • 100 |

      Paul Egeler. Reviewer, contributor. 101 |

      102 |
    • 103 |
    • 104 |

      Christophe Dervieux. Reviewer. 105 |

      106 |
    • 107 |
    • 108 |

      Nina Robery. Contributor. 109 |
      Work and Health Indicators with nomisr vignette

      110 |
    • 111 |
    112 |
    113 |
    114 |

    Citation

    115 | Source: inst/CITATION 116 |
    117 |
    118 | 119 | 120 |

    Odell E (2018). 121 | “nomisr: Access Nomis UK Labour Market Data With R.” 122 | The Journal of Open Source Software, 3(27), 859. 123 | doi: 10.21105/joss.00859. 124 |

    125 |
    @Article{,
    126 |   title = {{nomisr}: Access Nomis UK Labour Market Data With R},
    127 |   volume = {3},
    128 |   doi = {10.21105/joss.00859},
    129 |   number = {27},
    130 |   journal = {The Journal of Open Source Software},
    131 |   year = {2018},
    132 |   month = {July},
    133 |   pages = {859},
    134 |   author = {Evan Odell},
    135 | }
    136 | 137 |
    138 | 139 |
    140 | 141 | 142 | 143 |
    146 | 147 |
    148 |

    Site built with pkgdown 149 | 2.0.1.

    150 |
    151 | 152 |
    153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | -------------------------------------------------------------------------------- /docs/reference/index.html: -------------------------------------------------------------------------------- 1 | 2 | Function reference • nomisr 6 | 7 | 8 |
    9 |
    84 | 85 | 86 | 87 |
    88 |
    89 | 92 | 93 | 97 | 100 | 101 | 104 | 105 | 108 | 109 | 112 | 113 | 116 | 117 | 120 | 121 | 124 | 125 | 128 | 129 | 132 | 133 |
    94 |

    All functions

    95 |

    96 |
    98 |

    nomis_api_key()

    99 |

    Nomis API Key

    102 |

    nomis_codelist()

    103 |

    Nomis codelists

    106 |

    nomis_content_type()

    107 |

    Nomis dataset content types

    110 |

    nomis_data_info()

    111 |

    Nomis data structures

    114 |

    nomis_get_data()

    115 |

    Retrieve Nomis datasets

    118 |

    nomis_get_metadata()

    119 |

    Nomis metadata concepts and types

    122 |

    nomis_overview()

    123 |

    Nomis dataset overview

    126 |

    nomis_search()

    127 |

    Search Nomis datasets

    130 |

    nomisr

    131 |

    nomisr: Access Nomis UK Labour Market Data with R

    134 | 135 | 138 |
    139 | 140 | 141 |
    144 | 145 |
    146 |

    Site built with pkgdown 147 | 2.0.1.

    148 |
    149 | 150 |
    151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | -------------------------------------------------------------------------------- /docs/pkgdown.css: -------------------------------------------------------------------------------- 1 | /* Sticky footer */ 2 | 3 | /** 4 | * Basic idea: https://philipwalton.github.io/solved-by-flexbox/demos/sticky-footer/ 5 | * Details: https://github.com/philipwalton/solved-by-flexbox/blob/master/assets/css/components/site.css 6 | * 7 | * .Site -> body > .container 8 | * .Site-content -> body > .container .row 9 | * .footer -> footer 10 | * 11 | * Key idea seems to be to ensure that .container and __all its parents__ 12 | * have height set to 100% 13 | * 14 | */ 15 | 16 | html, body { 17 | height: 100%; 18 | } 19 | 20 | body { 21 | position: relative; 22 | } 23 | 24 | body > .container { 25 | display: flex; 26 | height: 100%; 27 | flex-direction: column; 28 | } 29 | 30 | body > .container .row { 31 | flex: 1 0 auto; 32 | } 33 | 34 | footer { 35 | margin-top: 45px; 36 | padding: 35px 0 36px; 37 | border-top: 1px solid #e5e5e5; 38 | color: #666; 39 | display: flex; 40 | flex-shrink: 0; 41 | } 42 | footer p { 43 | margin-bottom: 0; 44 | } 45 | footer div { 46 | flex: 1; 47 | } 48 | footer .pkgdown { 49 | text-align: right; 50 | } 51 | footer p { 52 | margin-bottom: 0; 53 | } 54 | 55 | img.icon { 56 | float: right; 57 | } 58 | 59 | /* Ensure in-page images don't run outside their container */ 60 | .contents img { 61 | max-width: 100%; 62 | height: auto; 63 | } 64 | 65 | /* Fix bug in bootstrap (only seen in firefox) */ 66 | summary { 67 | display: list-item; 68 | } 69 | 70 | /* Typographic tweaking ---------------------------------*/ 71 | 72 | .contents .page-header { 73 | margin-top: calc(-60px + 1em); 74 | } 75 | 76 | dd { 77 | margin-left: 3em; 78 | } 79 | 80 | /* Section anchors ---------------------------------*/ 81 | 82 | a.anchor { 83 | display: none; 84 | margin-left: 5px; 85 | width: 20px; 86 | height: 20px; 87 | 88 | background-image: url(./link.svg); 89 | background-repeat: no-repeat; 90 | background-size: 20px 20px; 91 | background-position: center center; 92 | } 93 | 94 | h1:hover .anchor, 95 | h2:hover .anchor, 96 | h3:hover .anchor, 97 | h4:hover .anchor, 98 | h5:hover .anchor, 99 | h6:hover .anchor { 100 | display: inline-block; 101 | } 102 | 103 | /* Fixes for fixed navbar --------------------------*/ 104 | 105 | .contents h1, .contents h2, .contents h3, .contents h4 { 106 | padding-top: 60px; 107 | margin-top: -40px; 108 | } 109 | 110 | /* Navbar submenu --------------------------*/ 111 | 112 | .dropdown-submenu { 113 | position: relative; 114 | } 115 | 116 | .dropdown-submenu>.dropdown-menu { 117 | top: 0; 118 | left: 100%; 119 | margin-top: -6px; 120 | margin-left: -1px; 121 | border-radius: 0 6px 6px 6px; 122 | } 123 | 124 | .dropdown-submenu:hover>.dropdown-menu { 125 | display: block; 126 | } 127 | 128 | .dropdown-submenu>a:after { 129 | display: block; 130 | content: " "; 131 | float: right; 132 | width: 0; 133 | height: 0; 134 | border-color: transparent; 135 | border-style: solid; 136 | border-width: 5px 0 5px 5px; 137 | border-left-color: #cccccc; 138 | margin-top: 5px; 139 | margin-right: -10px; 140 | } 141 | 142 | .dropdown-submenu:hover>a:after { 143 | border-left-color: #ffffff; 144 | } 145 | 146 | .dropdown-submenu.pull-left { 147 | float: none; 148 | } 149 | 150 | .dropdown-submenu.pull-left>.dropdown-menu { 151 | left: -100%; 152 | margin-left: 10px; 153 | border-radius: 6px 0 6px 6px; 154 | } 155 | 156 | /* Sidebar --------------------------*/ 157 | 158 | #pkgdown-sidebar { 159 | margin-top: 30px; 160 | position: -webkit-sticky; 161 | position: sticky; 162 | top: 70px; 163 | } 164 | 165 | #pkgdown-sidebar h2 { 166 | font-size: 1.5em; 167 | margin-top: 1em; 168 | } 169 | 170 | #pkgdown-sidebar h2:first-child { 171 | margin-top: 0; 172 | } 173 | 174 | #pkgdown-sidebar .list-unstyled li { 175 | margin-bottom: 0.5em; 176 | } 177 | 178 | /* bootstrap-toc tweaks ------------------------------------------------------*/ 179 | 180 | /* All levels of nav */ 181 | 182 | nav[data-toggle='toc'] .nav > li > a { 183 | padding: 4px 20px 4px 6px; 184 | font-size: 1.5rem; 185 | font-weight: 400; 186 | color: inherit; 187 | } 188 | 189 | nav[data-toggle='toc'] .nav > li > a:hover, 190 | nav[data-toggle='toc'] .nav > li > a:focus { 191 | padding-left: 5px; 192 | color: inherit; 193 | border-left: 1px solid #878787; 194 | } 195 | 196 | nav[data-toggle='toc'] .nav > .active > a, 197 | nav[data-toggle='toc'] .nav > .active:hover > a, 198 | nav[data-toggle='toc'] .nav > .active:focus > a { 199 | padding-left: 5px; 200 | font-size: 1.5rem; 201 | font-weight: 400; 202 | color: inherit; 203 | border-left: 2px solid #878787; 204 | } 205 | 206 | /* Nav: second level (shown on .active) */ 207 | 208 | nav[data-toggle='toc'] .nav .nav { 209 | display: none; /* Hide by default, but at >768px, show it */ 210 | padding-bottom: 10px; 211 | } 212 | 213 | nav[data-toggle='toc'] .nav .nav > li > a { 214 | padding-left: 16px; 215 | font-size: 1.35rem; 216 | } 217 | 218 | nav[data-toggle='toc'] .nav .nav > li > a:hover, 219 | nav[data-toggle='toc'] .nav .nav > li > a:focus { 220 | padding-left: 15px; 221 | } 222 | 223 | nav[data-toggle='toc'] .nav .nav > .active > a, 224 | nav[data-toggle='toc'] .nav .nav > .active:hover > a, 225 | nav[data-toggle='toc'] .nav .nav > .active:focus > a { 226 | padding-left: 15px; 227 | font-weight: 500; 228 | font-size: 1.35rem; 229 | } 230 | 231 | /* orcid ------------------------------------------------------------------- */ 232 | 233 | .orcid { 234 | font-size: 16px; 235 | color: #A6CE39; 236 | /* margins are required by official ORCID trademark and display guidelines */ 237 | margin-left:4px; 238 | margin-right:4px; 239 | vertical-align: middle; 240 | } 241 | 242 | /* Reference index & topics ----------------------------------------------- */ 243 | 244 | .ref-index th {font-weight: normal;} 245 | 246 | .ref-index td {vertical-align: top; min-width: 100px} 247 | .ref-index .icon {width: 40px;} 248 | .ref-index .alias {width: 40%;} 249 | .ref-index-icons .alias {width: calc(40% - 40px);} 250 | .ref-index .title {width: 60%;} 251 | 252 | .ref-arguments th {text-align: right; padding-right: 10px;} 253 | .ref-arguments th, .ref-arguments td {vertical-align: top; min-width: 100px} 254 | .ref-arguments .name {width: 20%;} 255 | .ref-arguments .desc {width: 80%;} 256 | 257 | /* Nice scrolling for wide elements --------------------------------------- */ 258 | 259 | table { 260 | display: block; 261 | overflow: auto; 262 | } 263 | 264 | /* Syntax highlighting ---------------------------------------------------- */ 265 | 266 | pre, code, pre code { 267 | background-color: #f8f8f8; 268 | color: #333; 269 | } 270 | pre, pre code { 271 | white-space: pre-wrap; 272 | word-break: break-all; 273 | overflow-wrap: break-word; 274 | } 275 | 276 | pre { 277 | border: 1px solid #eee; 278 | } 279 | 280 | pre .img, pre .r-plt { 281 | margin: 5px 0; 282 | } 283 | 284 | pre .img img, pre .r-plt img { 285 | background-color: #fff; 286 | } 287 | 288 | code a, pre a { 289 | color: #375f84; 290 | } 291 | 292 | a.sourceLine:hover { 293 | text-decoration: none; 294 | } 295 | 296 | .fl {color: #1514b5;} 297 | .fu {color: #000000;} /* function */ 298 | .ch,.st {color: #036a07;} /* string */ 299 | .kw {color: #264D66;} /* keyword */ 300 | .co {color: #888888;} /* comment */ 301 | 302 | .error {font-weight: bolder;} 303 | .warning {font-weight: bolder;} 304 | 305 | /* Clipboard --------------------------*/ 306 | 307 | .hasCopyButton { 308 | position: relative; 309 | } 310 | 311 | .btn-copy-ex { 312 | position: absolute; 313 | right: 0; 314 | top: 0; 315 | visibility: hidden; 316 | } 317 | 318 | .hasCopyButton:hover button.btn-copy-ex { 319 | visibility: visible; 320 | } 321 | 322 | /* headroom.js ------------------------ */ 323 | 324 | .headroom { 325 | will-change: transform; 326 | transition: transform 200ms linear; 327 | } 328 | .headroom--pinned { 329 | transform: translateY(0%); 330 | } 331 | .headroom--unpinned { 332 | transform: translateY(-100%); 333 | } 334 | 335 | /* mark.js ----------------------------*/ 336 | 337 | mark { 338 | background-color: rgba(255, 255, 51, 0.5); 339 | border-bottom: 2px solid rgba(255, 153, 51, 0.3); 340 | padding: 1px; 341 | } 342 | 343 | /* vertical spacing after htmlwidgets */ 344 | .html-widget { 345 | margin-bottom: 10px; 346 | } 347 | 348 | /* fontawesome ------------------------ */ 349 | 350 | .fab { 351 | font-family: "Font Awesome 5 Brands" !important; 352 | } 353 | 354 | /* don't display links in code chunks when printing */ 355 | /* source: https://stackoverflow.com/a/10781533 */ 356 | @media print { 357 | code a:link:after, code a:visited:after { 358 | content: ""; 359 | } 360 | } 361 | 362 | /* Section anchors --------------------------------- 363 | Added in pandoc 2.11: https://github.com/jgm/pandoc-templates/commit/9904bf71 364 | */ 365 | 366 | div.csl-bib-body { } 367 | div.csl-entry { 368 | clear: both; 369 | } 370 | .hanging-indent div.csl-entry { 371 | margin-left:2em; 372 | text-indent:-2em; 373 | } 374 | div.csl-left-margin { 375 | min-width:2em; 376 | float:left; 377 | } 378 | div.csl-right-inline { 379 | margin-left:2em; 380 | padding-left:1em; 381 | } 382 | div.csl-indent { 383 | margin-left: 2em; 384 | } 385 | -------------------------------------------------------------------------------- /vignettes/introduction.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Introduction to nomisr" 3 | author: "Evan Odell" 4 | date: "`r Sys.Date()`" 5 | output: 6 | html_document: 7 | toc: true 8 | toc_float: true 9 | theme: flatly 10 | vignette: > 11 | %\VignetteIndexEntry{Introduction to nomisr} 12 | %\VignetteEngine{knitr::rmarkdown} 13 | %\VignetteEncoding{UTF-8} 14 | --- 15 | 16 | # Introduction to the Nomis API 17 | 18 | `nomisr` is for accessing [Nomis](https://www.nomisweb.co.uk/) data with R. The Nomis API is free to access without registration, and contains up-to-date official statistics, including data from the Census, the Labour Force Survey, DWP benefit statistics and other economic and demographic data. Nomis is maintained on behalf of the Office for National Statistics by the University of Durham. 19 | 20 | There is a lot of data available through Nomis, and there are some limits to the amount of data that can be retrieved within a certain period of time, although those are not published. For more details, see the [full API documentation](https://www.nomisweb.co.uk/api/v01/help) from Nomis. 21 | 22 | Nomis data is based around administrative and statistical geographies, and a particular geography should be specified when downloading data. 23 | 24 | `nomisr` is designed around a pipeline of three key functions: `nomis_data_info()`, `nomis_get_metadata()` and `nomis_get_data()`. The `nomis_overview()`, `nomis_content_type()` and `nomis_search()` functions can assist with this. 25 | 26 | ## Querying data availability 27 | 28 | The `nomis_data_info()` function is focused on the structure and coverage of the available datasets. 29 | 30 | Use the `nomis_data_info()` function without any parameters to get a tibble with metadata for all available datasets: 31 | 32 | ``` 33 | x <- nomis_data_info() 34 | head(x) 35 | ``` 36 | 37 | 38 | `nomis_data_info()` can also be used to query metadata from a specific dataset, using its ID. The example below uses the "LC4408EW - Tenure by number of persons per bedroom in household by household type" dataset from the 2011 census, which has the ID "NM_893_1". 39 | 40 | ```{r specific-dataset, echo=TRUE} 41 | library(nomisr) 42 | y <- nomis_data_info("NM_893_1") 43 | 44 | tibble::glimpse(y) 45 | ``` 46 | 47 | When a tibble with metadata for all datasets or a specific dataset is returned, three of the columns, `annotations.annotation`, `components.attribute` and `components.dimension`, are list-columns of data frames. `annotations.annotation` contains metadata on the dataset, including units and current status. `components.attribute` contains more detailed status metadata. `components.dimension` contains the grouping and summary variables available in the dataset, which vary between different datasets. 48 | 49 | The example below shows how to access data stored in list columns returned from the Nomis API. In the case of requests for metadata from a single dataset, the three columns are all lists with a length of 1. If requesting all dataset information with `nomis_data_info()`, each row is a list of length 1. Each list contains a data.frame, of varrying dimensions depending on the column and dataset. You can unnest individual list-columns to display their data in the same row as data from the rest of the tibble. Due to the differing lengths of the list-columns returned by `nomis_data_info()`, only one list-column can be unnested at a time. 50 | 51 | ```{r specific-dataset-exam, eval=FALSE} 52 | library(dplyr, warn.conflicts = F) 53 | 54 | y$annotations.annotation %>% class() 55 | 56 | y$annotations.annotation %>% length() 57 | 58 | y$annotations.annotation[[1]] %>% class() 59 | 60 | y %>% pull(annotations.annotation) %>% class() 61 | 62 | y %>% pull(annotations.annotation) %>% .[[1]] %>% class() 63 | 64 | y %>% pull(annotations.annotation) %>% purrr::pluck() %>% class() 65 | 66 | ## Unnesting list columns 67 | y %>% tidyr::unnest(annotations.annotation) %>% glimpse() 68 | ``` 69 | 70 | ### Searching for data 71 | 72 | `nomisr` also contains the `nomis_search()` function to search for datasets on particular topics. `nomis_search()` can be used to search in one or more of dataset names, descriptions, keywords, content type and units. If using multiple parameters, `nomis_search()` will return information on all datasets that match one or more parameters. Character vectors of strings can be used in searches, and likewise `nomis_search()` will return information on datasets that match one or more queries. The * is used as a wildcard symbol. `nomis_search()` returns metadata in the same format as `nomis_data_info()`, including using list-columns. The `nomis_content_type()` function can assist in identifying content type IDs for `nomis_search()`. 73 | 74 | ```{r data-searching, eval=FALSE} 75 | a <- nomis_search(name = '*jobseekers*', keywords = 'Claimants') 76 | 77 | tibble::glimpse(a) 78 | 79 | a %>% tidyr::unnest(components.attribute) %>% glimpse() 80 | 81 | b <- nomis_search(keywords = c('Claimants', '*Year*')) 82 | 83 | tibble::glimpse(b) 84 | 85 | b %>% tidyr::unnest(components.attribute) %>% glimpse() 86 | 87 | ``` 88 | 89 | 90 | ### Other ways to access metadata 91 | 92 | `nomis_overview()` returns a tibble with a generalised overview of a given dataset. 93 | 94 | 95 | ```{r overview, eval=FALSE} 96 | q <- nomis_overview("NM_1650_1") 97 | 98 | q %>% tidyr::unnest(name) %>% glimpse() 99 | 100 | ``` 101 | 102 | `nomis_overview()` has a `select` parameter that can be used to select only particular elements of the overview to return. 103 | 104 | ```{r overview-select, eval=FALSE} 105 | s <- nomis_overview("NM_1650_1", select = c("units", "keywords")) 106 | 107 | s %>% tidyr::unnest(name) %>% glimpse() 108 | ``` 109 | 110 | 111 | ## Querying data variables 112 | 113 | Vast amounts of data are available through Nomis and so to avoid overwhelming the API, it is good practice to query what concepts are available, using `nomis_get_metadata()`. While the other metadata functions can return concept metadata, `nomis_get_metadata()` provides greater flexibility and specificity over the returned metadata than `nomis_overview()` and `nomis_data_info()`. 114 | 115 | The example below queries some of the metadata available through the API for the "LC4408EW - Tenure bynumber of persons per bedroom in household by household type" dataset. 116 | 117 | ### Getting concepts 118 | 119 | If provided with just a dataset ID, `nomis_get_metadata()` will return the concepts available for the given dataset. 120 | 121 | ```{r get-metadata, eval=FALSE} 122 | a <- nomis_get_metadata(id = "NM_893_1") 123 | ``` 124 | 125 | ### Concept Values 126 | 127 | If provided with a concept name it returns the available values for that concept. However, in some cases, espescially with the geography concept, there are multiple options available, which Nomis labels types. In that case `nomis_get_metadata()` returns the values of the lowest indexed type available. 128 | 129 | 130 | ```{r concepts, eval=FALSE} 131 | b <- nomis_get_metadata(id = "NM_893_1", concept = "GEOGRAPHY") 132 | ``` 133 | 134 | We can now pass a generic "type" string to the `type` parameter in `nomis_get_metadata()`, which returns all available geography types for dataset "NM_893_1". 135 | 136 | 137 | 138 | ```{r geographies, eval=FALSE} 139 | c <- nomis_get_metadata(id = "NM_893_1", concept = "geography", type = "type") 140 | ``` 141 | 142 | 143 | Passing a specific type to the `type` parameter, in this case "TYPE460" for all post-2010 parliamentary constituencies, returns a tibble with geographic codes for those specific constituencies, which can be used to filter queries. 144 | 145 | 146 | ```{r constituencies, eval=FALSE} 147 | d <- nomis_get_metadata(id = "NM_893_1", 148 | concept = "geography", type = "TYPE460") 149 | 150 | ``` 151 | 152 | 153 | The vast majority (98% as of February 2018) of Nomis datasets include a geographic variable. 154 | 155 | ## Downloading data 156 | 157 | Using the information above, we can now query the latest data on bedroom occupancy per household type in different NHS clinical commissioning groups. 158 | 159 | ```{r ccg, eval=FALSE} 160 | z <- nomis_get_data(id = "NM_893_1", time = "latest", geography = "TYPE266") 161 | ``` 162 | 163 | We can also query bedroom occupancy per household type in the Manchester, Gorton and Manchester, Withington parliamentary constituencies. 164 | 165 | ```{r NM_893_1-gorton-withington, eval=FALSE} 166 | x <- nomis_get_data(id = "NM_893_1", time = "latest", 167 | geography = c("1929380119", "1929380120")) 168 | ``` 169 | 170 | 171 | `nomisr` also allows for time series queries. The example below shows how to retrieve the percentage of the workforce claiming Jobseekers Allowance from January 2015 to January 2020, inclusive, for each region of the UK, divided by male and female claimants, with an accompanying graph. 172 | 173 | 174 | ```{r jsa-claimaints, eval=FALSE} 175 | library(ggplot2) 176 | library(dplyr) 177 | library(nomisr) 178 | 179 | jsa <- nomis_get_data(id = "NM_1_1", time = "2018-01-2021-10", 180 | geography = "TYPE480", measures=20201, 181 | sex=c(5,6), item = 1, tidy = TRUE) 182 | 183 | jsa <- jsa %>% 184 | mutate(date = as.Date(paste0(date, "-01")), 185 | obs_value = obs_value/100) 186 | 187 | theme_set(theme_bw()) 188 | 189 | p_jsa <- ggplot(jsa, aes(x = date, y = obs_value, colour = sex_name)) + 190 | geom_line(size = 1.15) + 191 | scale_colour_viridis_d(end = 0.75, begin = 0.1, name = "Gender") + 192 | scale_x_date(breaks = "6 months", date_labels = "%b %Y") + 193 | scale_y_continuous(labels = scales::percent) + 194 | theme(axis.text.x = element_text(angle = 30, hjust = 1, size = 8), 195 | legend.position = "bottom") + 196 | labs(x = "Date", y= "JSA Claimants (Percentage of Workforce)") + 197 | facet_wrap(~geography_name, scales = "free_y") 198 | 199 | p_jsa 200 | ``` 201 | 202 | ![](p_jsa.png) 203 | 204 | 205 | -------------------------------------------------------------------------------- /man/nomis_get_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data_download.R 3 | \name{nomis_get_data} 4 | \alias{nomis_get_data} 5 | \title{Retrieve Nomis datasets} 6 | \usage{ 7 | nomis_get_data( 8 | id, 9 | time = NULL, 10 | date = NULL, 11 | geography = NULL, 12 | sex = NULL, 13 | measures = NULL, 14 | additional_queries = NULL, 15 | exclude_missing = FALSE, 16 | select = NULL, 17 | tidy = FALSE, 18 | tidy_style = "snake_case", 19 | query_id = NULL, 20 | ... 21 | ) 22 | } 23 | \arguments{ 24 | \item{id}{A string containing the ID of the dataset to retrieve, 25 | in \code{"nm_***_*"} format. The \code{id} parameter is not case sensitive.} 26 | 27 | \item{time}{Parameter for selecting dates and date ranges. Accepts either a 28 | single date value, or two date values and returns all data between the two 29 | date values, There are two styles of values that can be used to query time. 30 | 31 | The first is one or two of \code{"latest"} (returns the latest available 32 | data), \code{"previous"} (the date prior to \code{"latest"}), \code{"prevyear"} 33 | (the date one year prior to \code{"latest"}) or \code{"first"} 34 | (the oldest available data for the dataset). 35 | 36 | The second style is to use or a specific date or multiple dates, in the 37 | style of the time variable codelist, which can be found using the 38 | \code{\link[=nomis_get_metadata]{nomis_get_metadata()}} function. 39 | 40 | Values for the \code{time} and \code{date} parameters should not be used 41 | at the same time. If they are, the function will retrieve data based 42 | on the the \code{date} parameter. 43 | 44 | Defaults to \code{NULL}.} 45 | 46 | \item{date}{Parameter for selecting specific dates. Accepts one or more date 47 | values. If given multiple values, only data for the given dates will be 48 | returned, but there is no limit to the number of data values. For example, 49 | \code{date=c("latest, latestMINUS3, latestMINUS6")} will return the latest 50 | data, data from three months prior to the latest data and six months prior 51 | to the latest data. There are two styles of values that can be used to 52 | query time. 53 | 54 | The first is one or more of \code{"latest"} (returns the latest available 55 | data), \code{"previous"} (the date prior to \code{"latest"}), 56 | \code{"prevyear"} (the date one year prior to \code{"latest"}) or 57 | \code{"first"} (the oldest available data for the dataset). 58 | 59 | The second style is to use or a specific date or multiple dates, in the 60 | style of the time variable codelist, which can be found using the 61 | \code{\link[=nomis_get_metadata]{nomis_get_metadata()}} function. 62 | 63 | Values for the \code{time} and \code{date} parameters should not be used at 64 | the same time. If they are, the function will retrieve data based on the 65 | the \code{date} parameter. 66 | 67 | Defaults to \code{NULL}.} 68 | 69 | \item{geography}{The code of the geographic area to return data for. If 70 | \code{NULL}, returns data for all available geographic areas, subject to 71 | other parameters. Defaults to \code{NULL}. In the rare instance that a 72 | geographic variable does not exist, if not \code{NULL}, the function 73 | will return an error.} 74 | 75 | \item{sex}{The code for sexes/genders to include in the dataset. 76 | Accepts a string or number, or a vector of strings or numbers. 77 | \code{nomisr} automatically voids any queries for sex if it is not an 78 | available code in the requested dataset. Defaults to \code{NULL} and returns 79 | all available sex/gender data. 80 | 81 | There are two different codings used for sex, depending on the dataset. For 82 | datasets using \code{"SEX"}, \code{7} will return results for males and females, \code{6} 83 | only females and \code{5} only males. Defaults to \code{NULL}, equivalent to 84 | \code{c(5,6,7)} for datasets where sex is an option. For datasets using 85 | \code{"C_SEX"}, \code{0} will return results for males and females, \code{1} only males 86 | and \code{2} only females. Some datasets use \code{"GENDER"} with the same values 87 | as \code{"SEX"}, which works with both \verb{sex = } and \verb{gender = } 88 | as a dot parameter.} 89 | 90 | \item{measures}{The code for the statistical measure(s) to include in the 91 | data. Accepts a single string or number, or a list of strings or numbers. 92 | If \code{NULL}, returns data for all available statistical measures subject 93 | to other parameters. Defaults to \code{NULL}.} 94 | 95 | \item{additional_queries}{Any other additional queries to pass to the API. 96 | See \url{https://www.nomisweb.co.uk/api/v01/help} for instructions on 97 | query structure. Defaults to \code{NULL}. Deprecated in package versions greater 98 | than 0.2.0 and will eventually be removed in a future version.} 99 | 100 | \item{exclude_missing}{If \code{TRUE}, excludes all missing values. 101 | Defaults to \code{FALSE}.} 102 | 103 | \item{select}{A character vector of one or more variables to include in 104 | the returned data, excluding all others. \code{select} is not case sensitive.} 105 | 106 | \item{tidy}{Logical parameter. If \code{TRUE}, converts variable names to 107 | \code{snake_case}, or another style as specified by the 108 | \code{tidy_style} parameter. Defaults to \code{FALSE}. The default variable name style 109 | from the API is SCREAMING_SNAKE_CASE.} 110 | 111 | \item{tidy_style}{The style to convert variable names to, if 112 | \code{tidy = TRUE}. Accepts one of \code{"snake_case"}, \code{"camelCase"} 113 | and \code{"period.case"}, or any of the \code{case} options accepted by 114 | \code{\link[snakecase:to_any_case]{snakecase::to_any_case()}}. Defaults to \code{"snake_case"}.} 115 | 116 | \item{query_id}{Results can be labelled as belonging to a certain query 117 | made to the API. \code{query_id} accepts any value as a string, and will 118 | be included in every row of the tibble returned by \code{nomis_get_data} 119 | in a column labelled "QUERY_ID" in the default SCREAMING_SNAKE_CASE 120 | used by the API. Defaults to \code{NULL}.} 121 | 122 | \item{...}{Use to pass any other parameters to the API. Useful for passing 123 | concepts that are not available through the default parameters. Only accepts 124 | concepts identified in \code{\link[=nomis_get_metadata]{nomis_get_metadata()}} and concept values 125 | identified in \code{\link[=nomis_codelist]{nomis_codelist()}}. Parameters can be quoted or 126 | unquoted. Each parameter should have a name and a value. For example, 127 | \code{CAUSE_OF_DEATH = 10300} when querying dataset \code{"NM_161_1"}. 128 | Parameters are not case sensitive. Note that R using partial matching for 129 | function variables, and so passing a parameter with the same opening 130 | characters as one of the above-named parameters can cause an error unless 131 | the value of the named parameter is specified, including as \code{NULL}. 132 | See example below:} 133 | } 134 | \value{ 135 | A tibble containing the selected dataset. By default, all tibble 136 | columns except for the \code{"OBS_VALUE"} column are parsed as characters. 137 | } 138 | \description{ 139 | To find the code options for a given dataset, use 140 | \code{\link[=nomis_get_metadata]{nomis_get_metadata()}} for specific codes, and 141 | \code{\link[=nomis_codelist]{nomis_codelist()}} for code values. 142 | 143 | This can be a slow process if querying significant amounts of 144 | data. Guest users are limited to 25,000 rows per query, although 145 | \code{nomisr} identifies queries that will return more than 25,000 rows, 146 | sending individual queries and combining the results of those queries into 147 | a single tibble. In interactive sessions, \code{nomisr} will warn you if 148 | guest users are requesting more than 350,000 rows of data, and if 149 | registered users are requesting more than 1,500,000 rows. 150 | 151 | Note the difference between the \code{time} and \code{date} 152 | parameters. The \code{time} and \code{date} parameters should not be used at the same 153 | time. If they are, the function will retrieve data based on the the 154 | \code{date} parameter. If given more than one query, \code{time} will 155 | return all data available between those queries, inclusively, while 156 | \code{date} will only return data for the exact queries specified. So 157 | \code{time = c("first", "latest")} will return all data, while 158 | \code{date = c("first", "latest")} will return only the earliest and latest 159 | data published. 160 | } 161 | \examples{ 162 | \donttest{ 163 | 164 | # Return data on Jobseekers Allowance for each country in the UK 165 | jobseekers_country <- nomis_get_data( 166 | id = "NM_1_1", time = "latest", 167 | geography = "TYPE499", 168 | measures = c(20100, 20201), sex = 5 169 | ) 170 | 171 | # Return data on Jobseekers Allowance for Wigan 172 | jobseekers_wigan <- nomis_get_data( 173 | id = "NM_1_1", time = "latest", 174 | geography = "1879048226", 175 | measures = c(20100, 20201), sex = "5" 176 | ) 177 | 178 | # annual population survey - regional - employment by occupation 179 | emp_by_occupation <- nomis_get_data( 180 | id = "NM_168_1", time = "latest", 181 | geography = "2013265925", sex = "0", 182 | select = c( 183 | "geography_code", 184 | "C_OCCPUK11H_0_NAME", "obs_vAlUE" 185 | ) 186 | ) 187 | 188 | # Deaths in 2016 and 2015 by three specified causes, 189 | # identified with nomis_get_metadata() 190 | death <- nomis_get_data("NM_161_1", 191 | date = c("2016", "2015"), 192 | geography = "TYPE480", 193 | cause_of_death = c(10300, 102088, 270) 194 | ) 195 | 196 | # All causes of death in London in 2016 197 | london_death <- nomis_get_data("NM_161_1", 198 | date = c("2016"), 199 | geography = "2013265927", sex = 1, age = 0 200 | ) 201 | } 202 | \dontrun{ 203 | # Results in an error because `measure` is mistaken for `measures` 204 | mort_data1 <- nomis_get_data( 205 | id = "NM_161_1", date = "2016", 206 | geography = "TYPE464", sex = 0, cause_of_death = "10381", 207 | age = 0, measure = 6 208 | ) 209 | 210 | # Does not error because `measures` is specified 211 | mort_data2 <- nomis_get_data( 212 | id = "NM_161_1", date = "2016", 213 | geography = "TYPE464", sex = 0, measures = NULL, 214 | cause_of_death = "10381", age = 0, measure = 6 215 | ) 216 | } 217 | 218 | } 219 | \seealso{ 220 | \code{\link[=nomis_data_info]{nomis_data_info()}} 221 | 222 | \code{\link[=nomis_get_metadata]{nomis_get_metadata()}} 223 | 224 | \code{\link[=nomis_codelist]{nomis_codelist()}} 225 | 226 | \code{\link[=nomis_overview]{nomis_overview()}} 227 | } 228 | -------------------------------------------------------------------------------- /docs/CONTRIBUTING.html: -------------------------------------------------------------------------------- 1 | 2 | Contributing to nomisr • nomisr 6 | 7 | 8 |
    9 |
    84 | 85 | 86 | 87 |
    88 |
    89 | 92 | 93 | 94 |
    95 | 96 |

    Thank you for any and all contributions! Following these guidelines 97 | will help streamline the process of contributing and make sure that 98 | we’re all on the same page. While we ask that you read this guide and 99 | follow it to the best of your abilities, we welcome contributions from 100 | all, regardless of your level of experience.

    101 |

    By participating in this project, you agree to abide by the code of 102 | conduct.

    103 |
    104 |
    105 |

    Types of contributions

    106 |

    Don’t feel that you must be a computer whiz to make meaningful 107 | contributions. Feel free to:

    108 |
    118 |
    119 |

    New to GitHub?

    120 |

    Getting ready to make your first contribution? Here are a couple of 121 | tutorials you may wish to check out:

    122 |
    132 |
    133 |

    How to contribute code

    134 |
    • Fork the repository
    • 135 |
    • Clone the repository from GitHub to your computer e.g,. 136 | git clone https://github.com/ropensci/nomisr.git 137 |
    • 138 |
    • Make sure to track progress upstream (i.e., on our version of 139 | nomisr at ropensci/nomisr) 140 |
      • git remote add upstream https://github.com/ropensci/nomisr.git
      • 141 |
      • Before making changes make sure to pull changes in from upstream 142 | with git pull upstream 143 |
      • 144 |
    • 145 |
    • Make your changes 146 |
      • For changes beyond minor typos, add an item to NEWS.md describing 147 | the changes and add yourself to the DESCRIPTION file as a 148 | contributor
      • 149 |
    • 150 |
    • Push to your GitHub account
    • 151 |
    • Submit a pull request to home base (likely master branch, but check 152 | to make sure) at ropensci/nomisr 153 |
    • 154 |
    155 |
    156 |

    Code formatting

    157 |
    • In general follow the convention of https://r-pkgs.had.co.nz/r.html#style (snake_case 158 | functions and argument names, etc.)
    • 159 |
    • Where there is conflict, default to the style of 160 | nomisr 161 |
    • 162 |
    • Use explicit package imports (i.e. package_name::package_function) 163 | and avoid @import if at all possible
    • 164 |
    165 | 166 | 167 |
    168 | 169 | 172 | 173 |
    174 | 175 | 176 | 177 |
    187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | --------------------------------------------------------------------------------