diff --git a/.Rbuildignore b/.Rbuildignore index c440a3d26..25b9f7aee 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -14,6 +14,7 @@ ^README\.md$ ^index\.md$ ^LICENSE\.md$ +^CITATION\.cff$ vignettes man/figures/ ^tests/manual_tests$ @@ -48,3 +49,4 @@ tests/testthat/test-utils_profiling.R tests/testthat/test-write_testthat_file.R tests/testthat/test-yaml.R tests/testthat/test-yaml_exec.R +^.lintr$ diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index 1de524a93..064677b49 100644 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -1,17 +1,23 @@ +# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples +# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help +# +# NOTE: This workflow is overkill for most R packages and +# check-standard.yaml is likely a better choice. +# usethis::use_github_action("check-standard") will install it. on: push: - branches: - - main + branches: [main, master] pull_request: - branches: - - main + branches: [main, master] -name: R-CMD-check +name: R-CMD-check.yaml + +permissions: read-all jobs: R-CMD-check: runs-on: ${{ matrix.config.os }} - + name: ${{ matrix.config.os }} (${{ matrix.config.r }}) strategy: @@ -21,27 +27,22 @@ jobs: - {os: macos-latest, r: 'release'} - {os: windows-latest, r: 'release'} - # # use 4.2 to check with rtools42's older compiler - - {os: windows-latest, r: '4.2'} - # # use 4.1 to check with rtools40's older compiler - - {os: windows-latest, r: '4.1'} - # # Use 3.6 to trigger usage of RTools35 - - {os: windows-latest, r: '3.6'} - - - {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'} - - {os: ubuntu-latest, r: 'release'} - - {os: ubuntu-latest, r: 'oldrel-1'} - - {os: ubuntu-latest, r: 'oldrel-2'} - - {os: ubuntu-latest, r: 'oldrel-3'} - - {os: ubuntu-latest, r: 'oldrel-4'} + # use 4.0 or 4.1 to check with rtools40's older compiler + - {os: windows-latest, r: 'oldrel-4'} + + - {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'} + - {os: ubuntu-latest, r: 'release'} + - {os: ubuntu-latest, r: 'oldrel-1'} + - {os: ubuntu-latest, r: 'oldrel-2'} + - {os: ubuntu-latest, r: 'oldrel-3'} + - {os: ubuntu-latest, r: 'oldrel-4'} env: - R_REMOTES_NO_ERRORS_FROM_WARNINGS: true - GITHUB_PAT: ${{ secrets.GHA_PAT }} + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} R_KEEP_PKG_SOURCE: yes steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: r-lib/actions/setup-pandoc@v2 @@ -58,4 +59,5 @@ jobs: - uses: r-lib/actions/check-r-package@v2 with: - upload-snapshots: true \ No newline at end of file + upload-snapshots: true + build_args: 'c("--no-manual","--compact-vignettes=gs+qpdf")' diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index fc751766b..018b8db3d 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -1,56 +1,34 @@ -on: [push, pull_request] +# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples +# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help +on: + push: + branches: [main, master] + pull_request: + branches: [main, master] -name: lint +name: lint.yaml + +permissions: read-all jobs: lint: runs-on: ubuntu-latest - env: - GITHUB_PAT: ${{ secrets.GHA_PAT }} - + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: r-lib/actions/setup-r@v2 with: use-public-rspm: true - - uses: r-lib/actions/setup-pandoc@v2 - - uses: r-lib/actions/setup-r-dependencies@v2 with: - extra-packages: any::pkgdown, local::. - needs: website - - - name: Install package - run: R CMD INSTALL . - - - name: Install dependencies - run: | - install.packages(c("remotes")) - remotes::install_deps(dependencies = TRUE) - remotes::install_cran("lintr") - shell: Rscript {0} + extra-packages: any::lintr, local::. + needs: lint - name: Lint - run: | - out <- - lintr::lint_package( - linters = lintr::linters_with_defaults( - object_usage_linter = NULL, - trailing_whitespace_linter = NULL, - cyclocomp_linter = NULL, - indentation_linter = NULL - ), - exclusions = c( - list.files("tests", recursive = TRUE, full.names = TRUE), - list.files("man", recursive = TRUE, full.names = TRUE), - list.files("vignettes", recursive = TRUE, full.names = TRUE), - list.files("data-raw", recursive = TRUE, full.names = TRUE), - list.files("inst", recursive = TRUE, full.names = TRUE) - ) - ) - print(out) - if (length(out)) stop("lints found") + run: lintr::lint_package() shell: Rscript {0} + env: + LINTR_ERROR_ON_LINT: true diff --git a/.github/workflows/pkgdown.yaml b/.github/workflows/pkgdown.yaml index 036c0e8b2..4bbce7508 100644 --- a/.github/workflows/pkgdown.yaml +++ b/.github/workflows/pkgdown.yaml @@ -1,37 +1,50 @@ +# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples +# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help on: push: - branches: main + branches: [main, master] + pull_request: + branches: [main, master] + release: + types: [published] + workflow_dispatch: -name: pkgdown +name: pkgdown.yaml + +permissions: read-all jobs: pkgdown: runs-on: ubuntu-latest # Only restrict concurrency for non-PR jobs concurrency: - group: pkgdown-${{ github.event_name != 'pull_request' || github.run_id }} + group: pkgdown-${{ github.event_name != 'pull_request' || github.run_id }} env: - GITHUB_PAT: ${{ secrets.GHA_PAT }} - + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + permissions: + contents: write steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + + - uses: r-lib/actions/setup-pandoc@v2 - uses: r-lib/actions/setup-r@v2 with: use-public-rspm: true - - - uses: r-lib/actions/setup-pandoc@v2 - uses: r-lib/actions/setup-r-dependencies@v2 with: extra-packages: any::pkgdown, local::. needs: website - - - name: Install package - run: R CMD INSTALL . - - - name: Build and deploy pkgdown site - run: | - git config --local user.email "actions@github.com" - git config --local user.name "GitHub Actions" - Rscript -e 'pkgdown::deploy_to_branch(new_process = FALSE)' + + - name: Build site + run: pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE) + shell: Rscript {0} + + - name: Deploy to GitHub pages 🚀 + if: github.event_name != 'pull_request' + uses: JamesIves/github-pages-deploy-action@v4.5.0 + with: + clean: false + branch: gh-pages + folder: docs diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml index dc30a7e81..988226098 100644 --- a/.github/workflows/test-coverage.yaml +++ b/.github/workflows/test-coverage.yaml @@ -1,21 +1,23 @@ +# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples +# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help on: push: - branches: - - main + branches: [main, master] pull_request: - branches: - - main + branches: [main, master] -name: test-coverage +name: test-coverage.yaml + +permissions: read-all jobs: test-coverage: runs-on: ubuntu-latest env: - GITHUB_PAT: ${{ secrets.GHA_PAT }} + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: r-lib/actions/setup-r@v2 with: @@ -23,9 +25,37 @@ jobs: - uses: r-lib/actions/setup-r-dependencies@v2 with: - extra-packages: any::covr + extra-packages: any::covr, any::xml2 needs: coverage - name: Test coverage - run: covr::codecov(quiet = FALSE) + run: | + cov <- covr::package_coverage( + quiet = FALSE, + clean = FALSE, + install_path = file.path(normalizePath(Sys.getenv("RUNNER_TEMP"), winslash = "/"), "package") + ) + covr::to_cobertura(cov) shell: Rscript {0} + + - uses: codecov/codecov-action@v4 + with: + fail_ci_if_error: ${{ github.event_name != 'pull_request' && true || false }} + file: ./cobertura.xml + plugin: noop + disable_search: true + token: ${{ secrets.CODECOV_TOKEN }} + + - name: Show testthat output + if: always() + run: | + ## -------------------------------------------------------------------- + find '${{ runner.temp }}/package' -name 'testthat.Rout*' -exec cat '{}' \; || true + shell: bash + + - name: Upload test results + if: failure() + uses: actions/upload-artifact@v4 + with: + name: coverage-test-failures + path: ${{ runner.temp }}/package diff --git a/.lintr b/.lintr new file mode 100644 index 000000000..1530ed4d4 --- /dev/null +++ b/.lintr @@ -0,0 +1,14 @@ +linters: linters_with_defaults( + object_usage_linter = NULL, + trailing_whitespace_linter = NULL, + # cyclocomp_linter is no longer a default linter in lintr 3.2.0 + cyclocomp_linter = NULL, + indentation_linter = NULL + ) +exclusions: list( + "tests", + "man", + "vignettes", + "data-raw", + "inst" + ) diff --git a/CITATION.cff b/CITATION.cff index 82ed469b7..301a21de1 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -3,7 +3,7 @@ message: 'If you wish to cite the "pointblank" package use:' type: software license: MIT title: 'pointblank: Data Validation and Organization of Metadata for Local and Remote Tables' -version: 0.9.0 +version: 0.12.1 abstract: Validate data in data frames, 'tibble' objects, 'Spark' 'DataFrames', and database tables. Validation pipelines can be made using easily-readable, consecutive validation steps. Upon execution of the @@ -21,7 +21,11 @@ authors: given-names: Mauricio email: mavargas11@uc.cl orcid: https://orcid.org/0000-0003-1017-7574 -repository: https://CRAN.R-project.org/package=pointblank +- family-names: Choe + given-names: June + email: jchoe001@gmail.com + orcid: https://orcid.org/0000-0002-0701-921X +repository: https://doi.org/10.32614/CRAN.package.pointblank repository-code: https://github.com/rstudio/pointblank url: https://rstudio.github.io/pointblank/ contact: diff --git a/DESCRIPTION b/DESCRIPTION index abec80d86..2a76e75dd 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Type: Package Package: pointblank -Version: 0.11.4.9000 +Version: 0.12.1.9000 Title: Data Validation and Organization of Metadata for Local and Remote Tables Description: Validate data in data frames, 'tibble' objects, 'Spark' 'DataFrames', and database tables. Validation pipelines can be made using @@ -14,7 +14,9 @@ Authors@R: c( person("Richard", "Iannone", , "rich@posit.co", c("aut", "cre"), comment = c(ORCID = "0000-0003-3925-190X")), person("Mauricio", "Vargas", , "mavargas11@uc.cl", c("aut"), - comment = c(ORCID = "0000-0003-1017-7574")) + comment = c(ORCID = "0000-0003-1017-7574")), + person("June", "Choe", , "jchoe001@gmail.com", c("aut"), + comment = c(ORCID = "0000-0002-0701-921X")) ) License: MIT + file LICENSE URL: https://rstudio.github.io/pointblank/, https://github.com/rstudio/pointblank @@ -22,7 +24,7 @@ BugReports: https://github.com/rstudio/pointblank/issues Encoding: UTF-8 LazyData: true ByteCompile: true -RoxygenNote: 7.2.3 +RoxygenNote: 7.3.1 Depends: R (>= 3.5.0) Imports: @@ -49,8 +51,6 @@ Imports: Suggests: arrow, bigrquery, - covr, - crayon, data.table, duckdb, ggforce, diff --git a/LICENSE b/LICENSE index 157d9c97e..43ec72d47 100644 --- a/LICENSE +++ b/LICENSE @@ -1,2 +1,2 @@ -YEAR: 2017-2023 -COPYRIGHT HOLDER: pointblank authors +YEAR: 2017-2024 +COPYRIGHT HOLDER: Posit Software, PBC diff --git a/LICENSE.md b/LICENSE.md index 0cd23c29f..9c97dc6a3 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ # MIT License -Copyright (c) 2017-2023 pointblank authors +Copyright (c) 2017-2024 Posit Software, PBC Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/NAMESPACE b/NAMESPACE index b7dcd56b7..24736fbf4 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -49,7 +49,6 @@ export(col_vals_null) export(col_vals_regex) export(col_vals_within_spec) export(conjointly) -export(contains) export(create_agent) export(create_informant) export(create_multiagent) @@ -62,8 +61,6 @@ export(deactivate_steps) export(draft_validation) export(email_blast) export(email_create) -export(ends_with) -export(everything) export(expect_col_count_match) export(expect_col_exists) export(expect_col_is_character) @@ -120,7 +117,6 @@ export(info_snippet) export(info_tabular) export(interrogate) export(log4r_step) -export(matches) export(read_disk_multiagent) export(remove_steps) export(row_count_match) @@ -135,7 +131,6 @@ export(snip_list) export(snip_lowest) export(snip_stats) export(specially) -export(starts_with) export(stock_msg_body) export(stock_msg_footer) export(stop_if_not) @@ -210,8 +205,3 @@ importFrom(dplyr,case_when) importFrom(dplyr,vars) importFrom(magrittr,"%>%") importFrom(rlang,expr) -importFrom(tidyselect,contains) -importFrom(tidyselect,ends_with) -importFrom(tidyselect,everything) -importFrom(tidyselect,matches) -importFrom(tidyselect,starts_with) diff --git a/NEWS.md b/NEWS.md index 12142382d..a90a987dc 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,53 @@ # pointblank (development version) +## Minor improvements and bug fixes + +- `col_vals_expr()` now shows used columns in the agent report + +- Fixed a regression in `col_vals_*()` functions, where `vars("col")` was evaluating to the string `"col"`. Behavior of `vars("col")` is now aligned back with `vars(col)` - both evaluate to the column name `col`. + +- Warnings/errors arising from comparing `columns` to a `value` of different class (for example, comparing a datetime column to a date value `Sys.Date()` instead of another datetime value `Sys.time()`) are now signalled appropriately at `interrogate()`. + +- Improved readability of error and warning messages rendered as tooltip to the agent report. + +# pointblank 0.12.1 + +- Ensured that the column string is a symbol before constructing the expression for the `col_vals_*()` functions. + +- No longer resolve columns with tidyselect when the target table cannot be materialized. + +- Relaxed tests on tidyselect error messages. + +# pointblank 0.12.0 + +## New features + +* Complete `{tidyselect}` support for the `columns` argument of *all validation functions*, as well as in `has_columns()` and `info_columns`. The `columns` argument can now take familiar column-selection expressions as one would use inside `dplyr::select()`. This also begins a process of deprecation: + - `columns = vars(...)` will continue to work, but `c()` now supersedes `vars()`. + - If passing an *external vector* of column names, it should be wrapped in `all_of()`. + +* The `label` argument of validation functions now exposes the following string variables via `{glue}` syntax: + + - `"{.step}"`: The validation step name + - `"{.col}"`: The current column name + - `"{.seg_col}"`: The current segment's column name + - `"{.seg_val}"`: The current segment's value/group + + These dynamic values may be useful for validations that get expanded into multiple steps. + +* `interrogate()` gains two new options for printing progress in the console output: + + - `progress`: Whether interrogation progress should be printed to the console (`TRUE` for interactive sessions, same as before) + - `show_step_label`: Whether each validation step's label value should be printed alongside the progress. + +## Minor improvements and bug fixes + +* Fixes issue with rendering reports in Quarto HTML documents. + +* When no columns are returned from a `{tidyselect}` expression in `columns`, the agent's report now displays the originally supplied *expression* instead of being simply blank (e.g., in `create_agent(small_table) |> col_vals_null(matches("z"))`). + +* Fixes issue with the hashing implementation to improve performance and alignment of validation steps in the multiagent. + # pointblank 0.11.4 * Fixes issue with gt `0.9.0` compatibility. diff --git a/R/action_levels.R b/R/action_levels.R index 53090490a..86ebec30f 100644 --- a/R/action_levels.R +++ b/R/action_levels.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -154,10 +154,10 @@ #' actions = al #' ) %>% #' col_vals_gt( -#' columns = vars(a), value = 2 +#' columns = a, value = 2 #' ) %>% #' col_vals_lt( -#' columns = vars(d), value = 20000 +#' columns = d, value = 20000 #' ) %>% #' interrogate() #' ``` @@ -188,11 +188,11 @@ #' actions = al #' ) %>% #' col_vals_gt( -#' columns = vars(a), value = 2, +#' columns = a, value = 2, #' actions = warn_on_fail(warn_at = 0.5) #' ) %>% #' col_vals_lt( -#' columns = vars(d), value = 20000 +#' columns = d, value = 20000 #' ) %>% #' interrogate() #' ``` @@ -220,7 +220,7 @@ #' ```r #' small_table %>% #' col_vals_gt( -#' columns = vars(a), value = 2, +#' columns = a, value = 2, #' actions = warn_on_fail(warn_at = 2) #' ) #' ``` @@ -256,7 +256,7 @@ #' #' ```r #' small_table %>% -#' col_vals_gt(columns = vars(a), value = 2) +#' col_vals_gt(columns = a, value = 2) #' ``` #' #' ``` @@ -273,7 +273,7 @@ #' ```r #' small_table %>% #' col_vals_gt( -#' columns = vars(a), value = 2, +#' columns = a, value = 2, #' actions = stop_on_fail(stop_at = 1) #' ) #' ``` diff --git a/R/all_passed.R b/R/all_passed.R index d28b3ee3f..c68e30c1d 100644 --- a/R/all_passed.R +++ b/R/all_passed.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -77,9 +77,9 @@ #' ```r #' agent <- #' create_agent(tbl = tbl) %>% -#' col_vals_gt(columns = vars(a), value = 3) %>% -#' col_vals_lte(columns = vars(a), value = 10) %>% -#' col_vals_increasing(columns = vars(a)) %>% +#' col_vals_gt(columns = a, value = 3) %>% +#' col_vals_lte(columns = a, value = 10) %>% +#' col_vals_increasing(columns = a) %>% #' interrogate() #' ``` #' diff --git a/R/col_count_match.R b/R/col_count_match.R index 2efee2074..cfcaae6b4 100644 --- a/R/col_count_match.R +++ b/R/col_count_match.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -43,9 +43,9 @@ #' against the target table in terms of column count values. If supplying a #' comparison table, it can either be a table object such as a data frame, a #' tibble, a `tbl_dbi` object, or a `tbl_spark` object. Alternatively, a -#' table-prep formula (`~ `) or a function (`function() -#'
`) can be used to lazily read in the comparison table -#' at interrogation time. +#' table-prep formula (`~ `) or a function ( +#' `function() `) can be used to lazily read in the +#' comparison table at interrogation time. #' #' @return For the validation function, the return value is either a #' `ptblank_agent` object or a table object (depending on whether an agent @@ -103,6 +103,17 @@ #' depending on the situation (the first produces a warning, the other #' `stop()`s). #' +#' @section Labels: +#' +#' `label` may be a single string or a character vector that matches the number +#' of expanded steps. `label` also supports `{glue}` syntax and exposes the +#' following dynamic variables contextualized to the current step: +#' +#' - `"{.step}"`: The validation step name +#' +#' The glue context also supports ordinary expressions for further flexibility +#' (e.g., `"{toupper(.step)}"`) as long as they return a length-1 string. +#' #' @section Briefs: #' #' Want to describe this validation step in some detail? Keep in mind that this diff --git a/R/col_exists.R b/R/col_exists.R index c6d752841..7ebc27c0b 100644 --- a/R/col_exists.R +++ b/R/col_exists.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -34,14 +34,6 @@ #' #' @inheritParams col_vals_gt #' -#' @param columns *The target columns* -#' -#' `vector|vars()`` // **required** -#' -#' One or more columns from the table in focus. This can be -#' provided as a vector of column names using `c()` or bare column names -#' enclosed in [vars()]. -#' #' @return For the validation function, the return value is either a #' `ptblank_agent` object or a table object (depending on whether an agent #' object or a table was passed to `x`). The expectation function invisibly @@ -69,12 +61,17 @@ #' #' @section Column Names: #' -#' If providing multiple column names, the result will be an expansion of -#' validation steps to that number of column names (e.g., `vars(col_a, col_b)` -#' will result in the entry of two validation steps). Aside from column names in -#' quotes and in `vars()`, **tidyselect** helper functions are available for -#' specifying columns. They are: `starts_with()`, `ends_with()`, `contains()`, -#' `matches()`, and `everything()`. +#' `columns` may be a single column (as symbol `a` or string `"a"`) or a vector +#' of columns (`c(a, b, c)` or `c("a", "b", "c")`). `{tidyselect}` helpers +#' are also supported, such as `contains("date")` and `where(is.double)`. If +#' passing an *external vector* of columns, it should be wrapped in `all_of()`. +#' +#' When multiple columns are selected by `columns`, the result will be an +#' expansion of validation steps to that number of columns (e.g., +#' `c(col_a, col_b)` will result in the entry of two validation steps). +#' +#' Previously, columns could be specified in `vars()`. This continues to work, +#' but `c()` offers the same capability and supersedes `vars()` in `columns`. #' #' @section Actions: #' @@ -89,6 +86,18 @@ #' depending on the situation (the first produces a warning, the other #' `stop()`s). #' +#' @section Labels: +#' +#' `label` may be a single string or a character vector that matches the number +#' of expanded steps. `label` also supports `{glue}` syntax and exposes the +#' following dynamic variables contextualized to the current step: +#' +#' - `"{.step}"`: The validation step name +#' - `"{.col}"`: The current column name +#' +#' The glue context also supports ordinary expressions for further flexibility +#' (e.g., `"{toupper(.step)}"`) as long as they return a length-1 string. +#' #' @section Briefs: #' #' Want to describe this validation step in some detail? Keep in mind that this @@ -113,7 +122,7 @@ #' ```r #' agent %>% #' col_exists( -#' columns = vars(a), +#' columns = a, #' actions = action_levels(warn_at = 0.1, stop_at = 0.2), #' label = "The `col_exists()` step.", #' active = FALSE @@ -125,7 +134,7 @@ #' ```yaml #' steps: #' - col_exists: -#' columns: vars(a) +#' columns: c(a) #' actions: #' warn_fraction: 0.1 #' stop_fraction: 0.2 @@ -164,7 +173,7 @@ #' ```r #' agent <- #' create_agent(tbl = tbl) %>% -#' col_exists(columns = vars(a)) %>% +#' col_exists(columns = a) %>% #' interrogate() #' ``` #' @@ -185,7 +194,7 @@ #' The behavior of side effects can be customized with the `actions` option. #' #' ```{r} -#' tbl %>% col_exists(columns = vars(a)) +#' tbl %>% col_exists(columns = a) #' ``` #' #' ## C: Using the expectation function @@ -194,7 +203,7 @@ #' time. This is primarily used in **testthat** tests. #' #' ```r -#' expect_col_exists(tbl, columns = vars(a)) +#' expect_col_exists(tbl, columns = a) #' ``` #' #' ## D: Using the test function @@ -203,7 +212,7 @@ #' us. #' #' ```{r} -#' tbl %>% test_col_exists(columns = vars(a)) +#' tbl %>% test_col_exists(columns = a) #' ``` #' #' @family validation functions @@ -218,7 +227,7 @@ NULL #' @export col_exists <- function( x, - columns, + columns = NULL, actions = NULL, step_id = NULL, label = NULL, @@ -229,21 +238,26 @@ col_exists <- function( preconditions <- NULL values <- NULL + # Capture the `columns` expression + columns <- rlang::enquo(columns) # Get `columns` as a label - columns_expr <- - rlang::as_label(rlang::quo(!!enquo(columns))) %>% - gsub("^\"|\"$", "", .) + columns_expr <- as_columns_expr(columns) - # Normalize the `columns` expression - if (inherits(columns, "quosures")) { - - columns <- - vapply( - columns, - FUN.VALUE = character(1), - USE.NAMES = FALSE, - FUN = function(x) as.character(rlang::get_expr(x)) - ) + # Resolve the columns based on the expression + ## Only for `col_exists()`: error gracefully if column not found + columns <- tryCatch( + expr = resolve_columns(x = x, var_expr = columns, preconditions = NULL, + allow_empty = FALSE), + error = function(cnd) cnd$i %||% cnd + ) + ## Missing column selection + if (rlang::is_error(columns)) { + cnd <- columns + if (inherits(cnd, "resolve_eval_err")) { + # Evaluation errors should be rethrown + rlang::cnd_signal(cnd) + } + columns <- NA_character_ } if (is_a_table_object(x)) { @@ -251,7 +265,7 @@ col_exists <- function( secret_agent <- create_agent(x, label = "::QUIET::") %>% col_exists( - columns = columns, + columns = tidyselect::all_of(columns), actions = prime_actions(actions), label = label, brief = brief, @@ -281,7 +295,8 @@ col_exists <- function( # Add one or more validation steps based on the # length of the `columns` variable - for (i in seq(columns)) { + label <- resolve_label(label, columns) + for (i in seq_along(columns)) { agent <- create_validation_step( @@ -293,7 +308,7 @@ col_exists <- function( preconditions = NULL, actions = covert_actions(actions, agent), step_id = step_id[i], - label = label, + label = label[[i]], brief = brief[i], active = active ) diff --git a/R/col_is_character.R b/R/col_is_character.R index 97afe6d62..db0ec3fd0 100644 --- a/R/col_is_character.R +++ b/R/col_is_character.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -63,12 +63,17 @@ #' #' @section Column Names: #' -#' If providing multiple column names, the result will be an expansion of -#' validation steps to that number of column names (e.g., `vars(col_a, col_b)` -#' will result in the entry of two validation steps). Aside from column names in -#' quotes and in `vars()`, **tidyselect** helper functions are available for -#' specifying columns. They are: `starts_with()`, `ends_with()`, `contains()`, -#' `matches()`, and `everything()`. +#' `columns` may be a single column (as symbol `a` or string `"a"`) or a vector +#' of columns (`c(a, b, c)` or `c("a", "b", "c")`). `{tidyselect}` helpers +#' are also supported, such as `contains("date")` and `where(is.double)`. If +#' passing an *external vector* of columns, it should be wrapped in `all_of()`. +#' +#' When multiple columns are selected by `columns`, the result will be an +#' expansion of validation steps to that number of columns (e.g., +#' `c(col_a, col_b)` will result in the entry of two validation steps). +#' +#' Previously, columns could be specified in `vars()`. This continues to work, +#' but `c()` offers the same capability and supersedes `vars()` in `columns`. #' #' @section Actions: #' @@ -84,6 +89,18 @@ #' 1)` or `action_levels(stop_at = 1)` are good choices depending on the #' situation (the first produces a warning, the other will `stop()`). #' +#' @section Labels: +#' +#' `label` may be a single string or a character vector that matches the number +#' of expanded steps. `label` also supports `{glue}` syntax and exposes the +#' following dynamic variables contextualized to the current step: +#' +#' - `"{.step}"`: The validation step name +#' - `"{.col}"`: The current column name +#' +#' The glue context also supports ordinary expressions for further flexibility +#' (e.g., `"{toupper(.step)}"`) as long as they return a length-1 string. +#' #' @section Briefs: #' #' Want to describe this validation step in some detail? Keep in mind that this @@ -108,7 +125,7 @@ #' ```r #' agent %>% #' col_is_character( -#' columns = vars(a), +#' columns = a, #' actions = action_levels(warn_at = 0.1, stop_at = 0.2), #' label = "The `col_is_character()` step.", #' active = FALSE @@ -120,7 +137,7 @@ #' ```yaml #' steps: #' - col_is_character: -#' columns: vars(a) +#' columns: c(a) #' actions: #' warn_fraction: 0.1 #' stop_fraction: 0.2 @@ -159,7 +176,7 @@ #' ```r #' agent <- #' create_agent(tbl = tbl) %>% -#' col_is_character(columns = vars(b)) %>% +#' col_is_character(columns = b) %>% #' interrogate() #' ``` #' @@ -181,7 +198,7 @@ #' #' ```{r} #' tbl %>% -#' col_is_character(columns = vars(b)) %>% +#' col_is_character(columns = b) %>% #' dplyr::slice(1:5) #' ``` #' @@ -191,7 +208,7 @@ #' time. This is primarily used in **testthat** tests. #' #' ```r -#' expect_col_is_character(tbl, columns = vars(b)) +#' expect_col_is_character(tbl, columns = b) #' ``` #' #' ## D: Using the test function @@ -200,7 +217,7 @@ #' us. #' #' ```{r} -#' tbl %>% test_col_is_character(columns = vars(b)) +#' tbl %>% test_col_is_character(columns = b) #' ``` #' #' @family validation functions @@ -226,13 +243,10 @@ col_is_character <- function( preconditions <- NULL values <- NULL - # Get `columns` as a label - columns_expr <- - rlang::as_label(rlang::quo(!!enquo(columns))) %>% - gsub("^\"|\"$", "", .) - # Capture the `columns` expression columns <- rlang::enquo(columns) + # Get `columns` as a label + columns_expr <- as_columns_expr(columns) # Resolve the columns based on the expression columns <- resolve_columns(x = x, var_expr = columns, preconditions = NULL) @@ -242,7 +256,7 @@ col_is_character <- function( secret_agent <- create_agent(x, label = "::QUIET::") %>% col_is_character( - columns = columns, + columns = tidyselect::all_of(columns), label = label, brief = brief, actions = prime_actions(actions), @@ -274,7 +288,8 @@ col_is_character <- function( # Add one or more validation steps based on the # length of the `columns` variable - for (i in seq(columns)) { + label <- resolve_label(label, columns) + for (i in seq_along(columns)) { agent <- create_validation_step( @@ -286,7 +301,7 @@ col_is_character <- function( preconditions = NULL, actions = covert_actions(actions, agent), step_id = step_id[i], - label = label, + label = label[[i]], brief = brief[i], active = active ) diff --git a/R/col_is_date.R b/R/col_is_date.R index 3181f4e3c..b19dcf910 100644 --- a/R/col_is_date.R +++ b/R/col_is_date.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -63,12 +63,17 @@ #' #' @section Column Names: #' -#' If providing multiple column names, the result will be an expansion of -#' validation steps to that number of column names (e.g., `vars(col_a, col_b)` -#' will result in the entry of two validation steps). Aside from column names in -#' quotes and in `vars()`, **tidyselect** helper functions are available for -#' specifying columns. They are: `starts_with()`, `ends_with()`, `contains()`, -#' `matches()`, and `everything()`. +#' `columns` may be a single column (as symbol `a` or string `"a"`) or a vector +#' of columns (`c(a, b, c)` or `c("a", "b", "c")`). `{tidyselect}` helpers +#' are also supported, such as `contains("date")` and `where(is.double)`. If +#' passing an *external vector* of columns, it should be wrapped in `all_of()`. +#' +#' When multiple columns are selected by `columns`, the result will be an +#' expansion of validation steps to that number of columns (e.g., +#' `c(col_a, col_b)` will result in the entry of two validation steps). +#' +#' Previously, columns could be specified in `vars()`. This continues to work, +#' but `c()` offers the same capability and supersedes `vars()` in `columns`. #' #' @section Actions: #' @@ -84,6 +89,18 @@ #' 1)` or `action_levels(stop_at = 1)` are good choices depending on the #' situation (the first produces a warning, the other will `stop()`). #' +#' @section Labels: +#' +#' `label` may be a single string or a character vector that matches the number +#' of expanded steps. `label` also supports `{glue}` syntax and exposes the +#' following dynamic variables contextualized to the current step: +#' +#' - `"{.step}"`: The validation step name +#' - `"{.col}"`: The current column name +#' +#' The glue context also supports ordinary expressions for further flexibility +#' (e.g., `"{toupper(.step)}"`) as long as they return a length-1 string. +#' #' @section Briefs: #' #' Want to describe this validation step in some detail? Keep in mind that this @@ -108,7 +125,7 @@ #' ```r #' agent %>% #' col_is_date( -#' columns = vars(a), +#' columns = a, #' actions = action_levels(warn_at = 0.1, stop_at = 0.2), #' label = "The `col_is_date()` step.", #' active = FALSE @@ -120,7 +137,7 @@ #' ```yaml #' steps: #' - col_is_date: -#' columns: vars(a) +#' columns: c(a) #' actions: #' warn_fraction: 0.1 #' stop_fraction: 0.2 @@ -151,7 +168,7 @@ #' ```r #' agent <- #' create_agent(tbl = small_table) %>% -#' col_is_date(columns = vars(date)) %>% +#' col_is_date(columns = date) %>% #' interrogate() #' ``` #' @@ -173,7 +190,7 @@ #' #' ```{r} #' small_table %>% -#' col_is_date(columns = vars(date)) %>% +#' col_is_date(columns = date) %>% #' dplyr::slice(1:5) #' ``` #' @@ -183,7 +200,7 @@ #' time. This is primarily used in **testthat** tests. #' #' ```r -#' expect_col_is_date(small_table, columns = vars(date)) +#' expect_col_is_date(small_table, columns = date) #' ``` #' #' ## D: Using the test function @@ -192,7 +209,7 @@ #' us. #' #' ```{r} -#' small_table %>% test_col_is_date(columns = vars(date)) +#' small_table %>% test_col_is_date(columns = date) #' ``` #' #' @family validation functions @@ -218,13 +235,10 @@ col_is_date <- function( preconditions <- NULL values <- NULL - # Get `columns` as a label - columns_expr <- - rlang::as_label(rlang::quo(!!enquo(columns))) %>% - gsub("^\"|\"$", "", .) - # Capture the `columns` expression columns <- rlang::enquo(columns) + # Get `columns` as a label + columns_expr <- as_columns_expr(columns) # Resolve the columns based on the expression columns <- resolve_columns(x = x, var_expr = columns, preconditions = NULL) @@ -234,7 +248,7 @@ col_is_date <- function( secret_agent <- create_agent(x, label = "::QUIET::") %>% col_is_date( - columns = columns, + columns = tidyselect::all_of(columns), label = label, brief = brief, actions = prime_actions(actions), @@ -266,7 +280,8 @@ col_is_date <- function( # Add one or more validation steps based on the # length of the `columns` variable - for (i in seq(columns)) { + label <- resolve_label(label, columns) + for (i in seq_along(columns)) { agent <- create_validation_step( @@ -278,7 +293,7 @@ col_is_date <- function( preconditions = NULL, actions = covert_actions(actions, agent), step_id = step_id[i], - label = label, + label = label[[i]], brief = brief[i], active = active ) diff --git a/R/col_is_factor.R b/R/col_is_factor.R index 7283ca6c6..cd822a31b 100644 --- a/R/col_is_factor.R +++ b/R/col_is_factor.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -63,12 +63,17 @@ #' #' @section Column Names: #' -#' If providing multiple column names, the result will be an expansion of -#' validation steps to that number of column names (e.g., `vars(col_a, col_b)` -#' will result in the entry of two validation steps). Aside from column names in -#' quotes and in `vars()`, **tidyselect** helper functions are available for -#' specifying columns. They are: `starts_with()`, `ends_with()`, `contains()`, -#' `matches()`, and `everything()`. +#' `columns` may be a single column (as symbol `a` or string `"a"`) or a vector +#' of columns (`c(a, b, c)` or `c("a", "b", "c")`). `{tidyselect}` helpers +#' are also supported, such as `contains("date")` and `where(is.double)`. If +#' passing an *external vector* of columns, it should be wrapped in `all_of()`. +#' +#' When multiple columns are selected by `columns`, the result will be an +#' expansion of validation steps to that number of columns (e.g., +#' `c(col_a, col_b)` will result in the entry of two validation steps). +#' +#' Previously, columns could be specified in `vars()`. This continues to work, +#' but `c()` offers the same capability and supersedes `vars()` in `columns`. #' #' @section Actions: #' @@ -84,6 +89,18 @@ #' 1)` or `action_levels(stop_at = 1)` are good choices depending on the #' situation (the first produces a warning, the other will `stop()`). #' +#' @section Labels: +#' +#' `label` may be a single string or a character vector that matches the number +#' of expanded steps. `label` also supports `{glue}` syntax and exposes the +#' following dynamic variables contextualized to the current step: +#' +#' - `"{.step}"`: The validation step name +#' - `"{.col}"`: The current column name +#' +#' The glue context also supports ordinary expressions for further flexibility +#' (e.g., `"{toupper(.step)}"`) as long as they return a length-1 string. +#' #' @section Briefs: #' #' Want to describe this validation step in some detail? Keep in mind that this @@ -108,7 +125,7 @@ #' ```r #' agent %>% #' col_is_factor( -#' columns = vars(a), +#' columns = a, #' actions = action_levels(warn_at = 0.1, stop_at = 0.2), #' label = "The `col_is_factor()` step.", #' active = FALSE @@ -120,7 +137,7 @@ #' ```yaml #' steps: #' - col_is_factor: -#' columns: vars(a) +#' columns: c(a) #' actions: #' warn_fraction: 0.1 #' stop_fraction: 0.2 @@ -157,7 +174,7 @@ #' ```r #' agent <- #' create_agent(tbl = tbl) %>% -#' col_is_factor(columns = vars(f)) %>% +#' col_is_factor(columns = f) %>% #' interrogate() #' ``` #' @@ -179,7 +196,7 @@ #' #' ```{r} #' tbl %>% -#' col_is_factor(columns = vars(f)) %>% +#' col_is_factor(columns = f) %>% #' dplyr::slice(1:5) #' ``` #' @@ -189,7 +206,7 @@ #' time. This is primarily used in **testthat** tests. #' #' ```r -#' expect_col_is_factor(tbl, vars(f)) +#' expect_col_is_factor(tbl, f) #' ``` #' #' ## D: Using the test function @@ -198,7 +215,7 @@ #' us. #' #' ```{r} -#' tbl %>% test_col_is_factor(columns = vars(f)) +#' tbl %>% test_col_is_factor(columns = f) #' ``` #' #' @family validation functions @@ -224,13 +241,10 @@ col_is_factor <- function( preconditions <- NULL values <- NULL - # Get `columns` as a label - columns_expr <- - rlang::as_label(rlang::quo(!!enquo(columns))) %>% - gsub("^\"|\"$", "", .) - # Capture the `columns` expression columns <- rlang::enquo(columns) + # Get `columns` as a label + columns_expr <- as_columns_expr(columns) # Resolve the columns based on the expression columns <- resolve_columns(x = x, var_expr = columns, preconditions = NULL) @@ -240,7 +254,7 @@ col_is_factor <- function( secret_agent <- create_agent(x, label = "::QUIET::") %>% col_is_factor( - columns = columns, + columns = tidyselect::all_of(columns), label = label, brief = brief, actions = prime_actions(actions), @@ -272,7 +286,8 @@ col_is_factor <- function( # Add one or more validation steps based on the # length of the `columns` variable - for (i in seq(columns)) { + label <- resolve_label(label, columns) + for (i in seq_along(columns)) { agent <- create_validation_step( @@ -284,12 +299,12 @@ col_is_factor <- function( preconditions = NULL, actions = covert_actions(actions, agent), step_id = step_id[i], - label = label, + label = label[[i]], brief = brief[i], active = active ) } - + agent } diff --git a/R/col_is_integer.R b/R/col_is_integer.R index 4247b8cfc..36eb78cf3 100644 --- a/R/col_is_integer.R +++ b/R/col_is_integer.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -63,12 +63,17 @@ #' #' @section Column Names: #' -#' If providing multiple column names, the result will be an expansion of -#' validation steps to that number of column names (e.g., `vars(col_a, col_b)` -#' will result in the entry of two validation steps). Aside from column names in -#' quotes and in `vars()`, **tidyselect** helper functions are available for -#' specifying columns. They are: `starts_with()`, `ends_with()`, `contains()`, -#' `matches()`, and `everything()`. +#' `columns` may be a single column (as symbol `a` or string `"a"`) or a vector +#' of columns (`c(a, b, c)` or `c("a", "b", "c")`). `{tidyselect}` helpers +#' are also supported, such as `contains("date")` and `where(is.double)`. If +#' passing an *external vector* of columns, it should be wrapped in `all_of()`. +#' +#' When multiple columns are selected by `columns`, the result will be an +#' expansion of validation steps to that number of columns (e.g., +#' `c(col_a, col_b)` will result in the entry of two validation steps). +#' +#' Previously, columns could be specified in `vars()`. This continues to work, +#' but `c()` offers the same capability and supersedes `vars()` in `columns`. #' #' @section Actions: #' @@ -84,6 +89,18 @@ #' 1)` or `action_levels(stop_at = 1)` are good choices depending on the #' situation (the first produces a warning, the other will `stop()`). #' +#' @section Labels: +#' +#' `label` may be a single string or a character vector that matches the number +#' of expanded steps. `label` also supports `{glue}` syntax and exposes the +#' following dynamic variables contextualized to the current step: +#' +#' - `"{.step}"`: The validation step name +#' - `"{.col}"`: The current column name +#' +#' The glue context also supports ordinary expressions for further flexibility +#' (e.g., `"{toupper(.step)}"`) as long as they return a length-1 string. +#' #' @section Briefs: #' #' Want to describe this validation step in some detail? Keep in mind that this @@ -108,7 +125,7 @@ #' ```r #' agent %>% #' col_is_integer( -#' columns = vars(a), +#' columns = a, #' actions = action_levels(warn_at = 0.1, stop_at = 0.2), #' label = "The `col_is_integer()` step.", #' active = FALSE @@ -120,7 +137,7 @@ #' ```yaml #' steps: #' - col_is_integer: -#' columns: vars(a) +#' columns: c(a) #' actions: #' warn_fraction: 0.1 #' stop_fraction: 0.2 @@ -157,7 +174,7 @@ #' ```r #' agent <- #' create_agent(tbl = tbl) %>% -#' col_is_integer(columns = vars(b)) %>% +#' col_is_integer(columns = b) %>% #' interrogate() #' ``` #' @@ -178,7 +195,7 @@ #' behavior of side effects can be customized with the `actions` option. #' #' ```{r} -#' tbl %>% col_is_integer(columns = vars(b)) +#' tbl %>% col_is_integer(columns = b) #' ``` #' #' ## C: Using the expectation function @@ -187,7 +204,7 @@ #' time. This is primarily used in **testthat** tests. #' #' ```r -#' expect_col_is_integer(tbl, columns = vars(b)) +#' expect_col_is_integer(tbl, columns = b) #' ``` #' #' ## D: Using the test function @@ -196,7 +213,7 @@ #' us. #' #' ```{r} -#' tbl %>% test_col_is_integer(columns = vars(b)) +#' tbl %>% test_col_is_integer(columns = b) #' ``` #' #' @family validation functions @@ -222,13 +239,10 @@ col_is_integer <- function( preconditions <- NULL values <- NULL - # Capture the `column` expression + # Capture the `columns` expression columns <- rlang::enquo(columns) - # Get `columns` as a label - columns_expr <- - rlang::as_label(rlang::quo(!!enquo(columns))) %>% - gsub("^\"|\"$", "", .) + columns_expr <- as_columns_expr(columns) # Resolve the columns based on the expression columns <- resolve_columns(x = x, var_expr = columns, preconditions = NULL) @@ -238,7 +252,7 @@ col_is_integer <- function( secret_agent <- create_agent(x, label = "::QUIET::") %>% col_is_integer( - columns = columns, + columns = tidyselect::all_of(columns), label = label, brief = brief, actions = prime_actions(actions), @@ -270,7 +284,8 @@ col_is_integer <- function( # Add one or more validation steps based on the # length of the `columns` variable - for (i in seq(columns)) { + label <- resolve_label(label, columns) + for (i in seq_along(columns)) { agent <- create_validation_step( @@ -282,7 +297,7 @@ col_is_integer <- function( preconditions = NULL, actions = covert_actions(actions, agent), step_id = step_id[i], - label = label, + label = label[[i]], brief = brief[i], active = active ) diff --git a/R/col_is_logical.R b/R/col_is_logical.R index a3a4c3195..c2cb4663f 100644 --- a/R/col_is_logical.R +++ b/R/col_is_logical.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -63,12 +63,17 @@ #' #' @section Column Names: #' -#' If providing multiple column names, the result will be an expansion of -#' validation steps to that number of column names (e.g., `vars(col_a, col_b)` -#' will result in the entry of two validation steps). Aside from column names in -#' quotes and in `vars()`, **tidyselect** helper functions are available for -#' specifying columns. They are: `starts_with()`, `ends_with()`, `contains()`, -#' `matches()`, and `everything()`. +#' `columns` may be a single column (as symbol `a` or string `"a"`) or a vector +#' of columns (`c(a, b, c)` or `c("a", "b", "c")`). `{tidyselect}` helpers +#' are also supported, such as `contains("date")` and `where(is.double)`. If +#' passing an *external vector* of columns, it should be wrapped in `all_of()`. +#' +#' When multiple columns are selected by `columns`, the result will be an +#' expansion of validation steps to that number of columns (e.g., +#' `c(col_a, col_b)` will result in the entry of two validation steps). +#' +#' Previously, columns could be specified in `vars()`. This continues to work, +#' but `c()` offers the same capability and supersedes `vars()` in `columns`. #' #' @section Actions: #' @@ -84,6 +89,18 @@ #' 1)` or `action_levels(stop_at = 1)` are good choices depending on the #' situation (the first produces a warning, the other will `stop()`). #' +#' @section Labels: +#' +#' `label` may be a single string or a character vector that matches the number +#' of expanded steps. `label` also supports `{glue}` syntax and exposes the +#' following dynamic variables contextualized to the current step: +#' +#' - `"{.step}"`: The validation step name +#' - `"{.col}"`: The current column name +#' +#' The glue context also supports ordinary expressions for further flexibility +#' (e.g., `"{toupper(.step)}"`) as long as they return a length-1 string. +#' #' @section Briefs: #' #' Want to describe this validation step in some detail? Keep in mind that this @@ -108,7 +125,7 @@ #' ```r #' agent %>% #' col_is_logical( -#' columns = vars(a), +#' columns = a, #' actions = action_levels(warn_at = 0.1, stop_at = 0.2), #' label = "The `col_is_logical()` step.", #' active = FALSE @@ -120,7 +137,7 @@ #' ```yaml #' steps: #' - col_is_logical: -#' columns: vars(a) +#' columns: c(a) #' actions: #' warn_fraction: 0.1 #' stop_fraction: 0.2 @@ -152,7 +169,7 @@ #' ```r #' agent <- #' create_agent(tbl = small_table) %>% -#' col_is_logical(columns = vars(e)) %>% +#' col_is_logical(columns = e) %>% #' interrogate() #' ``` #' @@ -174,7 +191,7 @@ #' #' ```{r} #' small_table %>% -#' col_is_logical(columns = vars(e)) %>% +#' col_is_logical(columns = e) %>% #' dplyr::slice(1:5) #' ``` #' @@ -184,7 +201,7 @@ #' time. This is primarily used in **testthat** tests. #' #' ```r -#' expect_col_is_logical(small_table, columns = vars(e)) +#' expect_col_is_logical(small_table, columns = e) #' ``` #' #' ## D: Using the test function @@ -193,7 +210,7 @@ #' us. #' #' ```{r} -#' small_table %>% test_col_is_logical(columns = vars(e)) +#' small_table %>% test_col_is_logical(columns = e) #' ``` #' #' @family validation functions @@ -219,13 +236,10 @@ col_is_logical <- function( preconditions <- NULL values <- NULL - # Get `columns` as a label - columns_expr <- - rlang::as_label(rlang::quo(!!enquo(columns))) %>% - gsub("^\"|\"$", "", .) - # Capture the `columns` expression columns <- rlang::enquo(columns) + # Get `columns` as a label + columns_expr <- as_columns_expr(columns) # Resolve the columns based on the expression columns <- resolve_columns(x = x, var_expr = columns, preconditions = NULL) @@ -235,7 +249,7 @@ col_is_logical <- function( secret_agent <- create_agent(x, label = "::QUIET::") %>% col_is_logical( - columns = columns, + columns = tidyselect::all_of(columns), label = label, brief = brief, actions = prime_actions(actions), @@ -267,7 +281,8 @@ col_is_logical <- function( # Add one or more validation steps based on the # length of the `columns` variable - for (i in seq(columns)) { + label <- resolve_label(label, columns) + for (i in seq_along(columns)) { agent <- create_validation_step( @@ -279,12 +294,12 @@ col_is_logical <- function( preconditions = NULL, actions = covert_actions(actions, agent), step_id = step_id[i], - label = label, + label = label[[i]], brief = brief[i], active = active ) } - + agent } diff --git a/R/col_is_numeric.R b/R/col_is_numeric.R index a92ec6675..40ecf1c9b 100644 --- a/R/col_is_numeric.R +++ b/R/col_is_numeric.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -63,12 +63,17 @@ #' #' @section Column Names: #' -#' If providing multiple column names, the result will be an expansion of -#' validation steps to that number of column names (e.g., `vars(col_a, col_b)` -#' will result in the entry of two validation steps). Aside from column names in -#' quotes and in `vars()`, **tidyselect** helper functions are available for -#' specifying columns. They are: `starts_with()`, `ends_with()`, `contains()`, -#' `matches()`, and `everything()`. +#' `columns` may be a single column (as symbol `a` or string `"a"`) or a vector +#' of columns (`c(a, b, c)` or `c("a", "b", "c")`). `{tidyselect}` helpers +#' are also supported, such as `contains("date")` and `where(is.double)`. If +#' passing an *external vector* of columns, it should be wrapped in `all_of()`. +#' +#' When multiple columns are selected by `columns`, the result will be an +#' expansion of validation steps to that number of columns (e.g., +#' `c(col_a, col_b)` will result in the entry of two validation steps). +#' +#' Previously, columns could be specified in `vars()`. This continues to work, +#' but `c()` offers the same capability and supersedes `vars()` in `columns`. #' #' @section Actions: #' @@ -84,6 +89,18 @@ #' 1)` or `action_levels(stop_at = 1)` are good choices depending on the #' situation (the first produces a warning, the other will `stop()`). #' +#' @section Labels: +#' +#' `label` may be a single string or a character vector that matches the number +#' of expanded steps. `label` also supports `{glue}` syntax and exposes the +#' following dynamic variables contextualized to the current step: +#' +#' - `"{.step}"`: The validation step name +#' - `"{.col}"`: The current column name +#' +#' The glue context also supports ordinary expressions for further flexibility +#' (e.g., `"{toupper(.step)}"`) as long as they return a length-1 string. +#' #' @section Briefs: #' #' Want to describe this validation step in some detail? Keep in mind that this @@ -108,7 +125,7 @@ #' ```r #' agent %>% #' col_is_numeric( -#' columns = vars(a), +#' columns = a, #' actions = action_levels(warn_at = 0.1, stop_at = 0.2), #' label = "The `col_is_numeric()` step.", #' active = FALSE @@ -120,7 +137,7 @@ #' ```yaml #' steps: #' - col_is_numeric: -#' columns: vars(a) +#' columns: c(a) #' actions: #' warn_fraction: 0.1 #' stop_fraction: 0.2 @@ -152,7 +169,7 @@ #' ```r #' agent <- #' create_agent(tbl = small_table) %>% -#' col_is_numeric(columns = vars(d)) %>% +#' col_is_numeric(columns = d) %>% #' interrogate() #' ``` #' @@ -174,7 +191,7 @@ #' #' ```{r} #' small_table %>% -#' col_is_numeric(columns = vars(d)) %>% +#' col_is_numeric(columns = d) %>% #' dplyr::slice(1:5) #' ``` #' @@ -184,7 +201,7 @@ #' time. This is primarily used in **testthat** tests. #' #' ```r -#' expect_col_is_numeric(small_table, columns = vars(d)) +#' expect_col_is_numeric(small_table, columns = d) #' ``` #' #' ## D: Using the test function @@ -193,7 +210,7 @@ #' us. #' #' ```{r} -#' small_table %>% test_col_is_numeric(columns = vars(d)) +#' small_table %>% test_col_is_numeric(columns = d) #' ``` #' #' @family validation functions @@ -219,13 +236,10 @@ col_is_numeric <- function( preconditions <- NULL values <- NULL - # Get `columns` as a label - columns_expr <- - rlang::as_label(rlang::quo(!!enquo(columns))) %>% - gsub("^\"|\"$", "", .) - # Capture the `columns` expression columns <- rlang::enquo(columns) + # Get `columns` as a label + columns_expr <- as_columns_expr(columns) # Resolve the columns based on the expression columns <- resolve_columns(x = x, var_expr = columns, preconditions = NULL) @@ -235,7 +249,7 @@ col_is_numeric <- function( secret_agent <- create_agent(x, label = "::QUIET::") %>% col_is_numeric( - columns = columns, + columns = tidyselect::all_of(columns), label = label, brief = brief, actions = prime_actions(actions), @@ -267,7 +281,8 @@ col_is_numeric <- function( # Add one or more validation steps based on the # length of the `columns` variable - for (i in seq(columns)) { + label <- resolve_label(label, columns) + for (i in seq_along(columns)) { agent <- create_validation_step( @@ -279,7 +294,7 @@ col_is_numeric <- function( preconditions = NULL, actions = covert_actions(actions, agent), step_id = step_id[i], - label = label, + label = label[[i]], brief = brief[i], active = active ) diff --git a/R/col_is_posix.R b/R/col_is_posix.R index 49a1b8926..368093bed 100644 --- a/R/col_is_posix.R +++ b/R/col_is_posix.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -63,12 +63,17 @@ #' #' @section Column Names: #' -#' If providing multiple column names, the result will be an expansion of -#' validation steps to that number of column names (e.g., `vars(col_a, col_b)` -#' will result in the entry of two validation steps). Aside from column names in -#' quotes and in `vars()`, **tidyselect** helper functions are available for -#' specifying columns. They are: `starts_with()`, `ends_with()`, `contains()`, -#' `matches()`, and `everything()`. +#' `columns` may be a single column (as symbol `a` or string `"a"`) or a vector +#' of columns (`c(a, b, c)` or `c("a", "b", "c")`). `{tidyselect}` helpers +#' are also supported, such as `contains("date")` and `where(is.double)`. If +#' passing an *external vector* of columns, it should be wrapped in `all_of()`. +#' +#' When multiple columns are selected by `columns`, the result will be an +#' expansion of validation steps to that number of columns (e.g., +#' `c(col_a, col_b)` will result in the entry of two validation steps). +#' +#' Previously, columns could be specified in `vars()`. This continues to work, +#' but `c()` offers the same capability and supersedes `vars()` in `columns`. #' #' @section Actions: #' @@ -84,6 +89,18 @@ #' 1)` or `action_levels(stop_at = 1)` are good choices depending on the #' situation (the first produces a warning, the other will `stop()`). #' +#' @section Labels: +#' +#' `label` may be a single string or a character vector that matches the number +#' of expanded steps. `label` also supports `{glue}` syntax and exposes the +#' following dynamic variables contextualized to the current step: +#' +#' - `"{.step}"`: The validation step name +#' - `"{.col}"`: The current column name +#' +#' The glue context also supports ordinary expressions for further flexibility +#' (e.g., `"{toupper(.step)}"`) as long as they return a length-1 string. +#' #' @section Briefs: #' #' Want to describe this validation step in some detail? Keep in mind that this @@ -108,7 +125,7 @@ #' ```r #' agent %>% #' col_is_posix( -#' columns = vars(a), +#' columns = a, #' actions = action_levels(warn_at = 0.1, stop_at = 0.2), #' label = "The `col_is_posix()` step.", #' active = FALSE @@ -120,7 +137,7 @@ #' ```yaml #' steps: #' - col_is_posix: -#' columns: vars(a) +#' columns: c(a) #' actions: #' warn_fraction: 0.1 #' stop_fraction: 0.2 @@ -152,7 +169,7 @@ #' ```r #' agent <- #' create_agent(tbl = small_table) %>% -#' col_is_posix(columns = vars(date_time)) %>% +#' col_is_posix(columns = date_time) %>% #' interrogate() #' ``` #' @@ -174,7 +191,7 @@ #' #' ```{r} #' small_table %>% -#' col_is_posix(columns = vars(date_time)) %>% +#' col_is_posix(columns = date_time) %>% #' dplyr::slice(1:5) #' ``` #' @@ -184,7 +201,7 @@ #' time. This is primarily used in **testthat** tests. #' #' ```r -#' expect_col_is_posix(small_table, columns = vars(date_time)) +#' expect_col_is_posix(small_table, columns = date_time) #' ``` #' #' ## D: Using the test function @@ -193,7 +210,7 @@ #' us. #' #' ```{r} -#' small_table %>% test_col_is_posix(columns = vars(date_time)) +#' small_table %>% test_col_is_posix(columns = date_time) #' ``` #' #' @family validation functions @@ -219,13 +236,10 @@ col_is_posix <- function( preconditions <- NULL values <- NULL - # Get `columns` as a label - columns_expr <- - rlang::as_label(rlang::quo(!!enquo(columns))) %>% - gsub("^\"|\"$", "", .) - # Capture the `columns` expression columns <- rlang::enquo(columns) + # Get `columns` as a label + columns_expr <- as_columns_expr(columns) # Resolve the columns based on the expression columns <- resolve_columns(x = x, var_expr = columns, preconditions = NULL) @@ -235,7 +249,7 @@ col_is_posix <- function( secret_agent <- create_agent(x, label = "::QUIET::") %>% col_is_posix( - columns = columns, + columns = tidyselect::all_of(columns), label = label, brief = brief, actions = prime_actions(actions), @@ -267,7 +281,8 @@ col_is_posix <- function( # Add one or more validation steps based on the # length of the `column` variable - for (i in seq(columns)) { + label <- resolve_label(label, columns) + for (i in seq_along(columns)) { agent <- create_validation_step( @@ -279,12 +294,12 @@ col_is_posix <- function( preconditions = NULL, actions = covert_actions(actions, agent), step_id = step_id[i], - label = label, + label = label[[i]], brief = brief[i], active = active ) } - + agent } diff --git a/R/col_schema_match.R b/R/col_schema_match.R index b775adea6..9e0260490 100644 --- a/R/col_schema_match.R +++ b/R/col_schema_match.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -131,6 +131,17 @@ #' depending on the situation (the first produces a warning, the other #' `stop()`s). #' +#' @section Labels: +#' +#' `label` may be a single string or a character vector that matches the number +#' of expanded steps. `label` also supports `{glue}` syntax and exposes the +#' following dynamic variables contextualized to the current step: +#' +#' - `"{.step}"`: The validation step name +#' +#' The glue context also supports ordinary expressions for further flexibility +#' (e.g., `"{toupper(.step)}"`) as long as they return a length-1 string. +#' #' @section Briefs: #' #' Want to describe this validation step in some detail? Keep in mind that this @@ -508,8 +519,8 @@ test_col_schema_match <- function( #' then any values provided to `...` will be ignored. This can either be a #' table object, a table-prep formula.This can be a table object such as a #' data frame, a tibble, a `tbl_dbi` object, or a `tbl_spark` object. -#' Alternatively, a table-prep formula (`~
`) or a -#' function (`function()
`) can be used to lazily read in +#' Alternatively, a table-prep formula (`~ `) or a +#' function (`function() `) can be used to lazily read in #' the table at interrogation time. #' #' @param .db_col_types *Use R column types or database column types?* @@ -606,7 +617,7 @@ col_schema <- function( db_col_types <- match.arg(.db_col_types) - x <- list(...) + x <- rlang::list2(...) # Transform SQL column types to lowercase to allow # both uppercase and lowercase conventions while diff --git a/R/col_vals_between.R b/R/col_vals_between.R index e4d21464f..24e264ba1 100644 --- a/R/col_vals_between.R +++ b/R/col_vals_between.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -95,12 +95,17 @@ #' #' @section Column Names: #' -#' If providing multiple column names to `columns`, the result will be an -#' expansion of validation steps to that number of column names (e.g., -#' `vars(col_a, col_b)` will result in the entry of two validation steps). Aside -#' from column names in quotes and in `vars()`, **tidyselect** helper functions -#' are available for specifying columns. They are: `starts_with()`, -#' `ends_with()`, `contains()`, `matches()`, and `everything()`. +#' `columns` may be a single column (as symbol `a` or string `"a"`) or a vector +#' of columns (`c(a, b, c)` or `c("a", "b", "c")`). `{tidyselect}` helpers +#' are also supported, such as `contains("date")` and `where(is.double)`. If +#' passing an *external vector* of columns, it should be wrapped in `all_of()`. +#' +#' When multiple columns are selected by `columns`, the result will be an +#' expansion of validation steps to that number of columns (e.g., +#' `c(col_a, col_b)` will result in the entry of two validation steps). +#' +#' Previously, columns could be specified in `vars()`. This continues to work, +#' but `c()` offers the same capability and supersedes `vars()` in `columns`. #' #' @section Missing Values: #' @@ -175,6 +180,20 @@ #' quarter of the total test units fails, the other `stop()`s at the same #' threshold level). #' +#' @section Labels: +#' +#' `label` may be a single string or a character vector that matches the number +#' of expanded steps. `label` also supports `{glue}` syntax and exposes the +#' following dynamic variables contextualized to the current step: +#' +#' - `"{.step}"`: The validation step name +#' - `"{.col}"`: The current column name +#' - `"{.seg_col}"`: The current segment's column name +#' - `"{.seg_val}"`: The current segment's value/group +#' +#' The glue context also supports ordinary expressions for further flexibility +#' (e.g., `"{toupper(.step)}"`) as long as they return a length-1 string. +#' #' @section Briefs: #' #' Want to describe this validation step in some detail? Keep in mind that this @@ -199,7 +218,7 @@ #' ```r #' agent %>% #' col_vals_between( -#' columns = vars(a), +#' columns = a, #' left = 1, #' right = 2, #' inclusive = c(TRUE, FALSE), @@ -217,7 +236,7 @@ #' ```yaml #' steps: #' - col_vals_between: -#' columns: vars(a) +#' columns: c(a) #' left: 1.0 #' right: 2.0 #' inclusive: @@ -260,7 +279,7 @@ #' agent <- #' create_agent(tbl = small_table) %>% #' col_vals_between( -#' columns = vars(c), +#' columns = c, #' left = 1, right = 9, #' na_pass = TRUE #' ) %>% @@ -286,7 +305,7 @@ #' ```{r} #' small_table %>% #' col_vals_between( -#' columns = vars(c), +#' columns = c, #' left = 1, right = 9, #' na_pass = TRUE #' ) %>% @@ -300,7 +319,7 @@ #' #' ```r #' expect_col_vals_between( -#' small_table, columns = vars(c), +#' small_table, columns = c, #' left = 1, right = 9, #' na_pass = TRUE #' ) @@ -314,7 +333,7 @@ #' ```{r} #' small_table %>% #' test_col_vals_between( -#' columns = vars(c), +#' columns = c, #' left = 1, right = 9, #' na_pass = TRUE #' ) @@ -331,7 +350,7 @@ #' ```{r} #' small_table %>% #' test_col_vals_between( -#' columns = vars(c), left = 1, right = 9, +#' columns = c, left = 1, right = 9, #' inclusive = c(TRUE, FALSE), #' na_pass = TRUE #' ) @@ -365,13 +384,10 @@ col_vals_between <- function( active = TRUE ) { - # Get `columns` as a label - columns_expr <- - rlang::as_label(rlang::quo(!!enquo(columns))) %>% - gsub("^\"|\"$", "", .) - # Capture the `columns` expression columns <- rlang::enquo(columns) + # Get `columns` as a label + columns_expr <- as_columns_expr(columns) # Resolve the columns based on the expression columns <- resolve_columns(x = x, var_expr = columns, preconditions) @@ -393,7 +409,7 @@ col_vals_between <- function( secret_agent <- create_agent(x, label = "::QUIET::") %>% col_vals_between( - columns = columns, + columns = tidyselect::all_of(columns), left = left, right = right, inclusive = inclusive, @@ -436,6 +452,7 @@ col_vals_between <- function( # Add one or more validation steps based on the # length of the `columns` variable + label <- resolve_label(label, columns, segments_list) for (i in seq_along(columns)) { for (j in seq_along(segments_list)) { @@ -457,7 +474,7 @@ col_vals_between <- function( seg_val = seg_val, actions = covert_actions(actions, agent), step_id = step_id[i], - label = label, + label = label[[i, j]], brief = brief[i], active = active ) diff --git a/R/col_vals_decreasing.R b/R/col_vals_decreasing.R index 21efe8729..9998f142f 100644 --- a/R/col_vals_decreasing.R +++ b/R/col_vals_decreasing.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -85,12 +85,17 @@ #' #' @section Column Names: #' -#' If providing multiple column names to `columns`, the result will be an -#' expansion of validation steps to that number of column names (e.g., -#' `vars(col_a, col_b)` will result in the entry of two validation steps). Aside -#' from column names in quotes and in `vars()`, **tidyselect** helper functions -#' are available for specifying columns. They are: `starts_with()`, -#' `ends_with()`, `contains()`, `matches()`, and `everything()`. +#' `columns` may be a single column (as symbol `a` or string `"a"`) or a vector +#' of columns (`c(a, b, c)` or `c("a", "b", "c")`). `{tidyselect}` helpers +#' are also supported, such as `contains("date")` and `where(is.double)`. If +#' passing an *external vector* of columns, it should be wrapped in `all_of()`. +#' +#' When multiple columns are selected by `columns`, the result will be an +#' expansion of validation steps to that number of columns (e.g., +#' `c(col_a, col_b)` will result in the entry of two validation steps). +#' +#' Previously, columns could be specified in `vars()`. This continues to work, +#' but `c()` offers the same capability and supersedes `vars()` in `columns`. #' #' @section Missing Values: #' @@ -165,6 +170,20 @@ #' quarter of the total test units fails, the other `stop()`s at the same #' threshold level). #' +#' @section Labels: +#' +#' `label` may be a single string or a character vector that matches the number +#' of expanded steps. `label` also supports `{glue}` syntax and exposes the +#' following dynamic variables contextualized to the current step: +#' +#' - `"{.step}"`: The validation step name +#' - `"{.col}"`: The current column name +#' - `"{.seg_col}"`: The current segment's column name +#' - `"{.seg_val}"`: The current segment's value/group +#' +#' The glue context also supports ordinary expressions for further flexibility +#' (e.g., `"{toupper(.step)}"`) as long as they return a length-1 string. +#' #' @section Briefs: #' #' Want to describe this validation step in some detail? Keep in mind that this @@ -189,7 +208,7 @@ #' ```r #' agent %>% #' col_vals_decreasing( -#' columns = vars(a), +#' columns = a, #' allow_stationary = TRUE, #' increasing_tol = 0.5, #' na_pass = TRUE, @@ -206,7 +225,7 @@ #' ```yaml #' steps: #' - col_vals_decreasing: -#' columns: vars(a) +#' columns: c(a) #' allow_stationary: true #' increasing_tol: 0.5 #' na_pass: true @@ -259,7 +278,7 @@ #' agent <- #' create_agent(tbl = game_revenue_2) %>% #' col_vals_decreasing( -#' columns = vars(time_left), +#' columns = time_left, #' allow_stationary = TRUE #' ) %>% #' interrogate() @@ -284,7 +303,7 @@ #' ```{r} #' game_revenue_2 %>% #' col_vals_decreasing( -#' columns = vars(time_left), +#' columns = time_left, #' allow_stationary = TRUE #' ) %>% #' dplyr::select(time_left) %>% @@ -300,7 +319,7 @@ #' ```r #' expect_col_vals_decreasing( #' game_revenue_2, -#' columns = vars(time_left), +#' columns = time_left, #' allow_stationary = TRUE #' ) #' ``` @@ -313,7 +332,7 @@ #' ```{r} #' game_revenue_2 %>% #' test_col_vals_decreasing( -#' columns = vars(time_left), +#' columns = time_left, #' allow_stationary = TRUE #' ) #' ``` @@ -346,13 +365,10 @@ col_vals_decreasing <- function( active = TRUE ) { - # Get `columns` as a label - columns_expr <- - rlang::as_label(rlang::quo(!!enquo(columns))) %>% - gsub("^\"|\"$", "", .) - # Capture the `columns` expression columns <- rlang::enquo(columns) + # Get `columns` as a label + columns_expr <- as_columns_expr(columns) # Resolve the columns based on the expression columns <- resolve_columns(x = x, var_expr = columns, preconditions) @@ -379,7 +395,7 @@ col_vals_decreasing <- function( secret_agent <- create_agent(x, label = "::QUIET::") %>% col_vals_decreasing( - columns = columns, + columns = tidyselect::all_of(columns), allow_stationary = allow_stationary, increasing_tol = increasing_tol, na_pass = na_pass, @@ -421,6 +437,7 @@ col_vals_decreasing <- function( # Add one or more validation steps based on the # length of the `columns` variable + label <- resolve_label(label, columns, segments_list) for (i in seq_along(columns)) { for (j in seq_along(segments_list)) { @@ -442,7 +459,7 @@ col_vals_decreasing <- function( seg_val = seg_val, actions = covert_actions(actions, agent), step_id = step_id[i], - label = label, + label = label[[i, j]], brief = brief[i], active = active ) diff --git a/R/col_vals_equal.R b/R/col_vals_equal.R index f8ffd8804..c2d56bfdc 100644 --- a/R/col_vals_equal.R +++ b/R/col_vals_equal.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -71,12 +71,17 @@ #' #' @section Column Names: #' -#' If providing multiple column names to `columns`, the result will be an -#' expansion of validation steps to that number of column names (e.g., -#' `vars(col_a, col_b)` will result in the entry of two validation steps). Aside -#' from column names in quotes and in `vars()`, **tidyselect** helper functions -#' are available for specifying columns. They are: `starts_with()`, -#' `ends_with()`, `contains()`, `matches()`, and `everything()`. +#' `columns` may be a single column (as symbol `a` or string `"a"`) or a vector +#' of columns (`c(a, b, c)` or `c("a", "b", "c")`). `{tidyselect}` helpers +#' are also supported, such as `contains("date")` and `where(is.double)`. If +#' passing an *external vector* of columns, it should be wrapped in `all_of()`. +#' +#' When multiple columns are selected by `columns`, the result will be an +#' expansion of validation steps to that number of columns (e.g., +#' `c(col_a, col_b)` will result in the entry of two validation steps). +#' +#' Previously, columns could be specified in `vars()`. This continues to work, +#' but `c()` offers the same capability and supersedes `vars()` in `columns`. #' #' @section Missing Values: #' @@ -151,6 +156,20 @@ #' quarter of the total test units fails, the other `stop()`s at the same #' threshold level). #' +#' @section Labels: +#' +#' `label` may be a single string or a character vector that matches the number +#' of expanded steps. `label` also supports `{glue}` syntax and exposes the +#' following dynamic variables contextualized to the current step: +#' +#' - `"{.step}"`: The validation step name +#' - `"{.col}"`: The current column name +#' - `"{.seg_col}"`: The current segment's column name +#' - `"{.seg_val}"`: The current segment's value/group +#' +#' The glue context also supports ordinary expressions for further flexibility +#' (e.g., `"{toupper(.step)}"`) as long as they return a length-1 string. +#' #' @section Briefs: #' #' Want to describe this validation step in some detail? Keep in mind that this @@ -175,7 +194,7 @@ #' ```r #' agent %>% #' col_vals_equal( -#' columns = vars(a), +#' columns = a, #' value = 1, #' na_pass = TRUE, #' preconditions = ~ . %>% dplyr::filter(a < 10), @@ -191,7 +210,7 @@ #' ```yaml #' steps: #' - col_vals_equal: -#' columns: vars(a) +#' columns: c(a) #' value: 1.0 #' na_pass: true #' preconditions: ~. %>% dplyr::filter(a < 10) @@ -238,7 +257,7 @@ #' ```r #' agent <- #' create_agent(tbl = tbl) %>% -#' col_vals_equal(columns = vars(a), value = 5) %>% +#' col_vals_equal(columns = a, value = 5) %>% #' interrogate() #' ``` #' @@ -260,7 +279,7 @@ #' #' ```{r} #' tbl %>% -#' col_vals_equal(columns = vars(a), value = 5) %>% +#' col_vals_equal(columns = a, value = 5) %>% #' dplyr::pull(a) #' ``` #' @@ -270,7 +289,7 @@ #' time. This is primarily used in **testthat** tests. #' #' ```r -#' expect_col_vals_equal(tbl, columns = vars(a), value = 5) +#' expect_col_vals_equal(tbl, columns = a, value = 5) #' ``` #' #' ## D: Using the test function @@ -279,7 +298,7 @@ #' us. #' #' ```{r} -#' test_col_vals_equal(tbl, columns = vars(a), value = 5) +#' test_col_vals_equal(tbl, columns = a, value = 5) #' ``` #' #' @family validation functions @@ -308,13 +327,10 @@ col_vals_equal <- function( active = TRUE ) { - # Get `columns` as a label - columns_expr <- - rlang::as_label(rlang::quo(!!enquo(columns))) %>% - gsub("^\"|\"$", "", .) - # Capture the `columns` expression columns <- rlang::enquo(columns) + # Get `columns` as a label + columns_expr <- as_columns_expr(columns) # Resolve the columns based on the expression columns <- resolve_columns(x = x, var_expr = columns, preconditions) @@ -332,7 +348,7 @@ col_vals_equal <- function( secret_agent <- create_agent(x, label = "::QUIET::") %>% col_vals_equal( - columns = columns, + columns = tidyselect::all_of(columns), value = value, na_pass = na_pass, preconditions = preconditions, @@ -373,6 +389,7 @@ col_vals_equal <- function( # Add one or more validation steps based on the # length of the `columns` variable + label <- resolve_label(label, columns, segments_list) for (i in seq_along(columns)) { for (j in seq_along(segments_list)) { @@ -394,7 +411,7 @@ col_vals_equal <- function( seg_val = seg_val, actions = covert_actions(actions, agent), step_id = step_id[i], - label = label, + label = label[[i, j]], brief = brief[i], active = active ) diff --git a/R/col_vals_expr.R b/R/col_vals_expr.R index ba16383cd..9d09cc0d3 100644 --- a/R/col_vals_expr.R +++ b/R/col_vals_expr.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -134,6 +134,20 @@ #' quarter of the total test units fails, the other `stop()`s at the same #' threshold level). #' +#' @section Labels: +#' +#' `label` may be a single string or a character vector that matches the number +#' of expanded steps. `label` also supports `{glue}` syntax and exposes the +#' following dynamic variables contextualized to the current step: +#' +#' - `"{.step}"`: The validation step name +#' - `"{.col}"`: The current column name +#' - `"{.seg_col}"`: The current segment's column name +#' - `"{.seg_val}"`: The current segment's value/group +#' +#' The glue context also supports ordinary expressions for further flexibility +#' (e.g., `"{toupper(.step)}"`) as long as they return a length-1 string. +#' #' @section Briefs: #' #' Want to describe this validation step in some detail? Keep in mind that this @@ -325,6 +339,10 @@ col_vals_expr <- function( } } + # Extract columns from expr + data_cols <- colnames(apply_preconditions_for_cols(x, preconditions)) + columns <- all_data_vars(expr, data_cols) + # Resolve segments into list segments_list <- resolve_segments( @@ -374,6 +392,7 @@ col_vals_expr <- function( # Add one or more validation steps based on the # length of `segments_list` + label <- resolve_label(label, segments = segments_list) for (i in seq_along(segments_list)) { seg_col <- names(segments_list[i]) @@ -385,7 +404,7 @@ col_vals_expr <- function( assertion_type = "col_vals_expr", i_o = i_o, columns_expr = NA_character_, - column = NA_character_, + column = columns, values = expr, preconditions = preconditions, seg_expr = segments, @@ -393,7 +412,7 @@ col_vals_expr <- function( seg_val = seg_val, actions = covert_actions(actions, agent), step_id = step_id, - label = label, + label = label[[i]], brief = brief, active = active ) diff --git a/R/col_vals_gt.R b/R/col_vals_gt.R index 1ebbd99e8..5f0d8a4cb 100644 --- a/R/col_vals_gt.R +++ b/R/col_vals_gt.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -53,10 +53,11 @@ #' #' @param columns *The target columns* #' -#' `` // **required** +#' `` // **required** #' -#' The column (or a set of columns, provided as a character vector) to which -#' this validation should be applied. +#' A column-selecting expression, as one would use inside `dplyr::select()`. +#' Specifies the column (or a set of columns) to which this validation should +#' be applied. See the *Column Names* section for more information. #' #' @param value *Value for comparison* #' @@ -131,12 +132,13 @@ #' means that 15 percent of failing test units results in an overall test #' failure. #' -#' @param label *An optional label for the validation step* +#' @param label *Optional label for the validation step* #' -#' `scalar` // *default:* `NULL` (`optional`) +#' `vector` // *default:* `NULL` (`optional`) #' -#' An optional label for the validation step. This label appears in the -#' *agent* report and, for the best appearance, it should be kept quite short. +#' Optional label for the validation step. This label appears in the *agent* +#' report and, for the best appearance, it should be kept quite short. See +#' the *Labels* section for more information. #' #' @param brief *Brief description for the validation step* #' @@ -164,7 +166,7 @@ #' logical value. With this approach, the **pointblank** function #' [has_columns()] can be used to determine whether to make a validation step #' active on the basis of one or more columns existing in the table -#' (e.g., `~ . %>% has_columns(vars(d, e))`). +#' (e.g., `~ . %>% has_columns(c(d, e))`). #' #' @return For the validation function, the return value is either a #' `ptblank_agent` object or a table object (depending on whether an *agent* @@ -193,12 +195,17 @@ #' #' @section Column Names: #' -#' If providing multiple column names to `columns`, the result will be an -#' expansion of validation steps to that number of column names (e.g., -#' `vars(col_a, col_b)` will result in the entry of two validation steps). Aside -#' from column names in quotes and in `vars()`, **tidyselect** helper functions -#' are available for specifying columns. They are: `starts_with()`, -#' `ends_with()`, `contains()`, `matches()`, and `everything()`. +#' `columns` may be a single column (as symbol `a` or string `"a"`) or a vector +#' of columns (`c(a, b, c)` or `c("a", "b", "c")`). `{tidyselect}` helpers +#' are also supported, such as `contains("date")` and `where(is.double)`. If +#' passing an *external vector* of columns, it should be wrapped in `all_of()`. +#' +#' When multiple columns are selected by `columns`, the result will be an +#' expansion of validation steps to that number of columns (e.g., +#' `c(col_a, col_b)` will result in the entry of two validation steps). +#' +#' Previously, columns could be specified in `vars()`. This continues to work, +#' but `c()` offers the same capability and supersedes `vars()` in `columns`. #' #' @section Missing Values: #' @@ -273,6 +280,20 @@ #' quarter of the total test units fails, the other `stop()`s at the same #' threshold level). #' +#' @section Labels: +#' +#' `label` may be a single string or a character vector that matches the number +#' of expanded steps. `label` also supports `{glue}` syntax and exposes the +#' following dynamic variables contextualized to the current step: +#' +#' - `"{.step}"`: The validation step name +#' - `"{.col}"`: The current column name +#' - `"{.seg_col}"`: The current segment's column name +#' - `"{.seg_val}"`: The current segment's value/group +#' +#' The glue context also supports ordinary expressions for further flexibility +#' (e.g., `"{toupper(.step)}"`) as long as they return a length-1 string. +#' #' @section Briefs: #' #' Want to describe this validation step in some detail? Keep in mind that this @@ -297,7 +318,7 @@ #' ```r #' agent %>% #' col_vals_gt( -#' columns = vars(a), +#' columns = a, #' value = 1, #' na_pass = TRUE, #' preconditions = ~ . %>% dplyr::filter(a < 10), @@ -313,7 +334,7 @@ #' ```yaml #' steps: #' - col_vals_gt: -#' columns: vars(a) +#' columns: c(a) #' value: 1.0 #' na_pass: true #' preconditions: ~. %>% dplyr::filter(a < 10) @@ -360,7 +381,7 @@ #' ```r #' agent <- #' create_agent(tbl = tbl) %>% -#' col_vals_gt(columns = vars(a), value = 4) %>% +#' col_vals_gt(columns = a, value = 4) %>% #' interrogate() #' ``` #' @@ -381,7 +402,7 @@ #' behavior of side effects can be customized with the `actions` option. #' #' ```{r} -#' tbl %>% col_vals_gt(columns = vars(a), value = 4) +#' tbl %>% col_vals_gt(columns = a, value = 4) #' ``` #' #' ## C: Using the expectation function @@ -390,7 +411,7 @@ #' time. This is primarily used in **testthat** tests. #' #' ```r -#' expect_col_vals_gt(tbl, columns = vars(a), value = 4) +#' expect_col_vals_gt(tbl, columns = a, value = 4) #' ``` #' #' ## D: Using the test function @@ -399,7 +420,7 @@ #' us. #' #' ```{r} -#' test_col_vals_gt(tbl, columns = vars(a), value = 4) +#' test_col_vals_gt(tbl, columns = a, value = 4) #' ``` #' #' @family validation functions @@ -428,13 +449,10 @@ col_vals_gt <- function( active = TRUE ) { - # Get `columns` as a label - columns_expr <- - rlang::as_label(rlang::quo(!!enquo(columns))) %>% - gsub("^\"|\"$", "", .) - # Capture the `columns` expression columns <- rlang::enquo(columns) + # Get `columns` as a label + columns_expr <- as_columns_expr(columns) # Resolve the columns based on the expression columns <- resolve_columns(x = x, var_expr = columns, preconditions) @@ -452,7 +470,7 @@ col_vals_gt <- function( secret_agent <- create_agent(x, label = "::QUIET::") %>% col_vals_gt( - columns = columns, + columns = tidyselect::all_of(columns), value = value, na_pass = na_pass, preconditions = preconditions, @@ -493,6 +511,7 @@ col_vals_gt <- function( # Add one or more validation steps based on the # length of the `columns` variable + label <- resolve_label(label, columns, segments_list) for (i in seq_along(columns)) { for (j in seq_along(segments_list)) { @@ -514,7 +533,7 @@ col_vals_gt <- function( seg_val = seg_val, actions = covert_actions(actions, agent), step_id = step_id[i], - label = label, + label = label[[i, j]], brief = brief[i], active = active ) diff --git a/R/col_vals_gte.R b/R/col_vals_gte.R index 5b6e14109..2498ebf7f 100644 --- a/R/col_vals_gte.R +++ b/R/col_vals_gte.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -73,12 +73,17 @@ #' #' @section Column Names: #' -#' If providing multiple column names to `columns`, the result will be an -#' expansion of validation steps to that number of column names (e.g., -#' `vars(col_a, col_b)` will result in the entry of two validation steps). Aside -#' from column names in quotes and in `vars()`, **tidyselect** helper functions -#' are available for specifying columns. They are: `starts_with()`, -#' `ends_with()`, `contains()`, `matches()`, and `everything()`. +#' `columns` may be a single column (as symbol `a` or string `"a"`) or a vector +#' of columns (`c(a, b, c)` or `c("a", "b", "c")`). `{tidyselect}` helpers +#' are also supported, such as `contains("date")` and `where(is.double)`. If +#' passing an *external vector* of columns, it should be wrapped in `all_of()`. +#' +#' When multiple columns are selected by `columns`, the result will be an +#' expansion of validation steps to that number of columns (e.g., +#' `c(col_a, col_b)` will result in the entry of two validation steps). +#' +#' Previously, columns could be specified in `vars()`. This continues to work, +#' but `c()` offers the same capability and supersedes `vars()` in `columns`. #' #' @section Missing Values: #' @@ -152,6 +157,20 @@ #' situation (the first produces a warning when a quarter of the total test #' units fails, the other `stop()`s at the same threshold level). #' +#' @section Labels: +#' +#' `label` may be a single string or a character vector that matches the number +#' of expanded steps. `label` also supports `{glue}` syntax and exposes the +#' following dynamic variables contextualized to the current step: +#' +#' - `"{.step}"`: The validation step name +#' - `"{.col}"`: The current column name +#' - `"{.seg_col}"`: The current segment's column name +#' - `"{.seg_val}"`: The current segment's value/group +#' +#' The glue context also supports ordinary expressions for further flexibility +#' (e.g., `"{toupper(.step)}"`) as long as they return a length-1 string. +#' #' @section Briefs: #' #' Want to describe this validation step in some detail? Keep in mind that this @@ -176,7 +195,7 @@ #' ```r #' agent %>% #' col_vals_gte( -#' columns = vars(a), +#' columns = a, #' value = 1, #' na_pass = TRUE, #' preconditions = ~ . %>% dplyr::filter(a < 10), @@ -192,7 +211,7 @@ #' ```yaml #' steps: #' - col_vals_gte: -#' columns: vars(a) +#' columns: c(a) #' value: 1.0 #' na_pass: true #' preconditions: ~. %>% dplyr::filter(a < 10) @@ -239,7 +258,7 @@ #' ```r #' agent <- #' create_agent(tbl = tbl) %>% -#' col_vals_gte(columns = vars(a), value = 5) %>% +#' col_vals_gte(columns = a, value = 5) %>% #' interrogate() #' ``` #' @@ -260,7 +279,7 @@ #' behavior of side effects can be customized with the `actions` option. #' #' ```{r} -#' tbl %>% col_vals_gte(columns = vars(a), value = 5) +#' tbl %>% col_vals_gte(columns = a, value = 5) #' ``` #' #' ## C: Using the expectation function @@ -269,7 +288,7 @@ #' time. This is primarily used in **testthat** tests. #' #' ```r -#' expect_col_vals_gte(tbl, columns = vars(a), value = 5) +#' expect_col_vals_gte(tbl, columns = a, value = 5) #' ``` #' #' ## D: Using the test function @@ -278,7 +297,7 @@ #' us. #' #' ```{r} -#' test_col_vals_gte(tbl, columns = vars(a), value = 5) +#' test_col_vals_gte(tbl, columns = a, value = 5) #' ``` #' #' @family validation functions @@ -307,13 +326,10 @@ col_vals_gte <- function( active = TRUE ) { - # Get `columns` as a label - columns_expr <- - rlang::as_label(rlang::quo(!!enquo(columns))) %>% - gsub("^\"|\"$", "", .) - # Capture the `columns` expression columns <- rlang::enquo(columns) + # Get `columns` as a label + columns_expr <- as_columns_expr(columns) # Resolve the columns based on the expression columns <- resolve_columns(x = x, var_expr = columns, preconditions) @@ -331,7 +347,7 @@ col_vals_gte <- function( secret_agent <- create_agent(x, label = "::QUIET::") %>% col_vals_gte( - columns = columns, + columns = tidyselect::all_of(columns), value = value, na_pass = na_pass, preconditions = preconditions, @@ -372,6 +388,7 @@ col_vals_gte <- function( # Add one or more validation steps based on the # length of the `columns` variable + label <- resolve_label(label, columns, segments_list) for (i in seq_along(columns)) { for (j in seq_along(segments_list)) { @@ -393,7 +410,7 @@ col_vals_gte <- function( seg_val = seg_val, actions = covert_actions(actions, agent), step_id = step_id[i], - label = label, + label = label[[i, j]], brief = brief[i], active = active ) diff --git a/R/col_vals_in_set.R b/R/col_vals_in_set.R index e4b7557cc..7635008f1 100644 --- a/R/col_vals_in_set.R +++ b/R/col_vals_in_set.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -69,12 +69,17 @@ #' #' @section Column Names: #' -#' If providing multiple column names, the result will be an expansion of -#' validation steps to that number of column names (e.g., `vars(col_a, col_b)` -#' will result in the entry of two validation steps). Aside from column names in -#' quotes and in `vars()`, **tidyselect** helper functions are available for -#' specifying columns. They are: `starts_with()`, `ends_with()`, `contains()`, -#' `matches()`, and `everything()`. +#' `columns` may be a single column (as symbol `a` or string `"a"`) or a vector +#' of columns (`c(a, b, c)` or `c("a", "b", "c")`). `{tidyselect}` helpers +#' are also supported, such as `contains("date")` and `where(is.double)`. If +#' passing an *external vector* of columns, it should be wrapped in `all_of()`. +#' +#' When multiple columns are selected by `columns`, the result will be an +#' expansion of validation steps to that number of columns (e.g., +#' `c(col_a, col_b)` will result in the entry of two validation steps). +#' +#' Previously, columns could be specified in `vars()`. This continues to work, +#' but `c()` offers the same capability and supersedes `vars()` in `columns`. #' #' @section Preconditions: #' @@ -142,6 +147,20 @@ #' quarter of the total test units fails, the other `stop()`s at the same #' threshold level). #' +#' @section Labels: +#' +#' `label` may be a single string or a character vector that matches the number +#' of expanded steps. `label` also supports `{glue}` syntax and exposes the +#' following dynamic variables contextualized to the current step: +#' +#' - `"{.step}"`: The validation step name +#' - `"{.col}"`: The current column name +#' - `"{.seg_col}"`: The current segment's column name +#' - `"{.seg_val}"`: The current segment's value/group +#' +#' The glue context also supports ordinary expressions for further flexibility +#' (e.g., `"{toupper(.step)}"`) as long as they return a length-1 string. +#' #' @section Briefs: #' #' Want to describe this validation step in some detail? Keep in mind that this @@ -166,7 +185,7 @@ #' ```r #' agent %>% #' col_vals_in_set( -#' columns = vars(a), +#' columns = a, #' set = c(1, 2, 3, 4), #' preconditions = ~ . %>% dplyr::filter(a < 10), #' segments = b ~ c("group_1", "group_2"), @@ -181,7 +200,7 @@ #' ```yaml #' steps: #' - col_vals_in_set: -#' columns: vars(a) +#' columns: c(a) #' set: #' - 1.0 #' - 2.0 @@ -222,7 +241,7 @@ #' agent <- #' create_agent(tbl = small_table) %>% #' col_vals_in_set( -#' columns = vars(f), set = c("low", "mid", "high") +#' columns = f, set = c("low", "mid", "high") #' ) %>% #' interrogate() #' ``` @@ -246,7 +265,7 @@ #' ```{r} #' small_table %>% #' col_vals_in_set( -#' columns = vars(f), set = c("low", "mid", "high") +#' columns = f, set = c("low", "mid", "high") #' ) %>% #' dplyr::pull(f) %>% #' unique() @@ -260,7 +279,7 @@ #' ```r #' expect_col_vals_in_set( #' small_table, -#' columns = vars(f), set = c("low", "mid", "high") +#' columns = f, set = c("low", "mid", "high") #' ) #' ``` #' @@ -272,7 +291,7 @@ #' ```{r} #' small_table %>% #' test_col_vals_in_set( -#' columns = vars(f), set = c("low", "mid", "high") +#' columns = f, set = c("low", "mid", "high") #' ) #' ``` #' @@ -301,13 +320,10 @@ col_vals_in_set <- function( active = TRUE ) { - # Get `columns` as a label - columns_expr <- - rlang::as_label(rlang::quo(!!enquo(columns))) %>% - gsub("^\"|\"$", "", .) - # Capture the `columns` expression columns <- rlang::enquo(columns) + # Get `columns` as a label + columns_expr <- as_columns_expr(columns) # Resolve the columns based on the expression columns <- resolve_columns(x = x, var_expr = columns, preconditions) @@ -325,7 +341,7 @@ col_vals_in_set <- function( secret_agent <- create_agent(x, label = "::QUIET::") %>% col_vals_in_set( - columns = columns, + columns = tidyselect::all_of(columns), set = set, preconditions = preconditions, segments = segments, @@ -365,6 +381,7 @@ col_vals_in_set <- function( # Add one or more validation steps based on the # length of the `columns` variable + label <- resolve_label(label, columns, segments_list) for (i in seq_along(columns)) { for (j in seq_along(segments_list)) { @@ -385,7 +402,7 @@ col_vals_in_set <- function( seg_val = seg_val, actions = covert_actions(actions, agent), step_id = step_id[i], - label = label, + label = label[[i, j]], brief = brief[i], active = active ) diff --git a/R/col_vals_increasing.R b/R/col_vals_increasing.R index 7d77bf6d9..44060c080 100644 --- a/R/col_vals_increasing.R +++ b/R/col_vals_increasing.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -85,12 +85,17 @@ #' #' @section Column Names: #' -#' If providing multiple column names to `columns`, the result will be an -#' expansion of validation steps to that number of column names (e.g., -#' `vars(col_a, col_b)` will result in the entry of two validation steps). Aside -#' from column names in quotes and in `vars()`, **tidyselect** helper functions -#' are available for specifying columns. They are: `starts_with()`, -#' `ends_with()`, `contains()`, `matches()`, and `everything()`. +#' `columns` may be a single column (as symbol `a` or string `"a"`) or a vector +#' of columns (`c(a, b, c)` or `c("a", "b", "c")`). `{tidyselect}` helpers +#' are also supported, such as `contains("date")` and `where(is.double)`. If +#' passing an *external vector* of columns, it should be wrapped in `all_of()`. +#' +#' When multiple columns are selected by `columns`, the result will be an +#' expansion of validation steps to that number of columns (e.g., +#' `c(col_a, col_b)` will result in the entry of two validation steps). +#' +#' Previously, columns could be specified in `vars()`. This continues to work, +#' but `c()` offers the same capability and supersedes `vars()` in `columns`. #' #' @section Missing Values: #' @@ -165,6 +170,20 @@ #' quarter of the total test units fails, the other `stop()`s at the same #' threshold level). #' +#' @section Labels: +#' +#' `label` may be a single string or a character vector that matches the number +#' of expanded steps. `label` also supports `{glue}` syntax and exposes the +#' following dynamic variables contextualized to the current step: +#' +#' - `"{.step}"`: The validation step name +#' - `"{.col}"`: The current column name +#' - `"{.seg_col}"`: The current segment's column name +#' - `"{.seg_val}"`: The current segment's value/group +#' +#' The glue context also supports ordinary expressions for further flexibility +#' (e.g., `"{toupper(.step)}"`) as long as they return a length-1 string. +#' #' @section Briefs: #' #' Want to describe this validation step in some detail? Keep in mind that this @@ -189,7 +208,7 @@ #' ```r #' agent %>% #' col_vals_increasing( -#' columns = vars(a), +#' columns = a, #' allow_stationary = TRUE, #' decreasing_tol = 0.5, #' na_pass = TRUE, @@ -206,7 +225,7 @@ #' ```yaml #' steps: #' - col_vals_increasing: -#' columns: vars(a) +#' columns: c(a) #' allow_stationary: true #' decreasing_tol: 0.5 #' na_pass: true @@ -247,7 +266,7 @@ #' agent <- #' create_agent(tbl = game_revenue) %>% #' col_vals_increasing( -#' columns = vars(session_start), +#' columns = session_start, #' allow_stationary = TRUE #' ) %>% #' interrogate() @@ -272,7 +291,7 @@ #' ```{r} #' game_revenue %>% #' col_vals_increasing( -#' columns = vars(session_start), +#' columns = session_start, #' allow_stationary = TRUE #' ) %>% #' dplyr::select(session_start) %>% @@ -288,7 +307,7 @@ #' ```r #' expect_col_vals_increasing( #' game_revenue, -#' columns = vars(session_start), +#' columns = session_start, #' allow_stationary = TRUE #' ) #' ``` @@ -301,7 +320,7 @@ #' ```{r} #' game_revenue %>% #' test_col_vals_increasing( -#' columns = vars(session_start), +#' columns = session_start, #' allow_stationary = TRUE #' ) #' ``` @@ -334,13 +353,10 @@ col_vals_increasing <- function( active = TRUE ) { - # Get `columns` as a label - columns_expr <- - rlang::as_label(rlang::quo(!!enquo(columns))) %>% - gsub("^\"|\"$", "", .) - # Capture the `columns` expression columns <- rlang::enquo(columns) + # Get `columns` as a label + columns_expr <- as_columns_expr(columns) # Resolve the columns based on the expression columns <- resolve_columns(x = x, var_expr = columns, preconditions) @@ -367,7 +383,7 @@ col_vals_increasing <- function( secret_agent <- create_agent(x, label = "::QUIET::") %>% col_vals_increasing( - columns = columns, + columns = tidyselect::all_of(columns), allow_stationary = allow_stationary, decreasing_tol = decreasing_tol, na_pass = na_pass, @@ -409,6 +425,7 @@ col_vals_increasing <- function( # Add one or more validation steps based on the # length of the `columns` variable + label <- resolve_label(label, columns, segments_list) for (i in seq_along(columns)) { for (j in seq_along(segments_list)) { @@ -430,7 +447,7 @@ col_vals_increasing <- function( seg_val = seg_val, actions = covert_actions(actions, agent), step_id = step_id[i], - label = label, + label = label[[i, j]], brief = brief[i], active = active ) diff --git a/R/col_vals_lt.R b/R/col_vals_lt.R index d8553a2b0..0e8a05b7b 100644 --- a/R/col_vals_lt.R +++ b/R/col_vals_lt.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -72,12 +72,17 @@ #' #' @section Column Names: #' -#' If providing multiple column names to `columns`, the result will be an -#' expansion of validation steps to that number of column names (e.g., -#' `vars(col_a, col_b)` will result in the entry of two validation steps). Aside -#' from column names in quotes and in `vars()`, **tidyselect** helper functions -#' are available for specifying columns. They are: `starts_with()`, -#' `ends_with()`, `contains()`, `matches()`, and `everything()`. +#' `columns` may be a single column (as symbol `a` or string `"a"`) or a vector +#' of columns (`c(a, b, c)` or `c("a", "b", "c")`). `{tidyselect}` helpers +#' are also supported, such as `contains("date")` and `where(is.double)`. If +#' passing an *external vector* of columns, it should be wrapped in `all_of()`. +#' +#' When multiple columns are selected by `columns`, the result will be an +#' expansion of validation steps to that number of columns (e.g., +#' `c(col_a, col_b)` will result in the entry of two validation steps). +#' +#' Previously, columns could be specified in `vars()`. This continues to work, +#' but `c()` offers the same capability and supersedes `vars()` in `columns`. #' #' @section Missing Values: #' @@ -152,6 +157,20 @@ #' quarter of the total test units fails, the other `stop()`s at the same #' threshold level). #' +#' @section Labels: +#' +#' `label` may be a single string or a character vector that matches the number +#' of expanded steps. `label` also supports `{glue}` syntax and exposes the +#' following dynamic variables contextualized to the current step: +#' +#' - `"{.step}"`: The validation step name +#' - `"{.col}"`: The current column name +#' - `"{.seg_col}"`: The current segment's column name +#' - `"{.seg_val}"`: The current segment's value/group +#' +#' The glue context also supports ordinary expressions for further flexibility +#' (e.g., `"{toupper(.step)}"`) as long as they return a length-1 string. +#' #' @section Briefs: #' #' Want to describe this validation step in some detail? Keep in mind that this @@ -176,7 +195,7 @@ #' ```r #' agent %>% #' col_vals_lt( -#' columns = vars(a), +#' columns = a, #' value = 1, #' na_pass = TRUE, #' preconditions = ~ . %>% dplyr::filter(a < 10), @@ -192,7 +211,7 @@ #' ```yaml #' steps: #' - col_vals_lt: -#' columns: vars(a) +#' columns: c(a) #' value: 1.0 #' na_pass: true #' preconditions: ~. %>% dplyr::filter(a < 10) @@ -239,7 +258,7 @@ #' ```r #' agent <- #' create_agent(tbl = tbl) %>% -#' col_vals_lt(columns = vars(c), value = 5) %>% +#' col_vals_lt(columns = c, value = 5) %>% #' interrogate() #' ``` #' @@ -261,7 +280,7 @@ #' #' ```{r} #' tbl %>% -#' col_vals_lt(columns = vars(c), value = 5) %>% +#' col_vals_lt(columns = c, value = 5) %>% #' dplyr::pull(c) #' ``` #' @@ -271,7 +290,7 @@ #' time. This is primarily used in **testthat** tests. #' #' ```r -#' expect_col_vals_lt(tbl, columns = vars(c), value = 5) +#' expect_col_vals_lt(tbl, columns = c, value = 5) #' ``` #' #' ## D: Using the test function @@ -280,7 +299,7 @@ #' us. #' #' ```{r} -#' test_col_vals_lt(tbl, columns = vars(c), value = 5) +#' test_col_vals_lt(tbl, columns = c, value = 5) #' ``` #' #' @family validation functions @@ -309,13 +328,10 @@ col_vals_lt <- function( active = TRUE ) { - # Get `columns` as a label - columns_expr <- - rlang::as_label(rlang::quo(!!enquo(columns))) %>% - gsub("^\"|\"$", "", .) - # Capture the `columns` expression columns <- rlang::enquo(columns) + # Get `columns` as a label + columns_expr <- as_columns_expr(columns) # Resolve the columns based on the expression columns <- resolve_columns(x = x, var_expr = columns, preconditions) @@ -333,7 +349,7 @@ col_vals_lt <- function( secret_agent <- create_agent(x, label = "::QUIET::") %>% col_vals_lt( - columns = columns, + columns = tidyselect::all_of(columns), value = value, na_pass = na_pass, preconditions = preconditions, @@ -374,6 +390,7 @@ col_vals_lt <- function( # Add one or more validation steps based on the # length of the `columns` variable + label <- resolve_label(label, columns, segments_list) for (i in seq_along(columns)) { for (j in seq_along(segments_list)) { @@ -395,7 +412,7 @@ col_vals_lt <- function( seg_val = seg_val, actions = covert_actions(actions, agent), step_id = step_id[i], - label = label, + label = label[[i, j]], brief = brief[i], active = active ) diff --git a/R/col_vals_lte.R b/R/col_vals_lte.R index 56f14b4c2..a3440d649 100644 --- a/R/col_vals_lte.R +++ b/R/col_vals_lte.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -73,12 +73,17 @@ #' #' @section Column Names: #' -#' If providing multiple column names to `columns`, the result will be an -#' expansion of validation steps to that number of column names (e.g., -#' `vars(col_a, col_b)` will result in the entry of two validation steps). Aside -#' from column names in quotes and in `vars()`, **tidyselect** helper functions -#' are available for specifying columns. They are: `starts_with()`, -#' `ends_with()`, `contains()`, `matches()`, and `everything()`. +#' `columns` may be a single column (as symbol `a` or string `"a"`) or a vector +#' of columns (`c(a, b, c)` or `c("a", "b", "c")`). `{tidyselect}` helpers +#' are also supported, such as `contains("date")` and `where(is.double)`. If +#' passing an *external vector* of columns, it should be wrapped in `all_of()`. +#' +#' When multiple columns are selected by `columns`, the result will be an +#' expansion of validation steps to that number of columns (e.g., +#' `c(col_a, col_b)` will result in the entry of two validation steps). +#' +#' Previously, columns could be specified in `vars()`. This continues to work, +#' but `c()` offers the same capability and supersedes `vars()` in `columns`. #' #' @section Missing Values: #' @@ -153,6 +158,20 @@ #' quarter of the total test units fails, the other `stop()`s at the same #' threshold level). #' +#' @section Labels: +#' +#' `label` may be a single string or a character vector that matches the number +#' of expanded steps. `label` also supports `{glue}` syntax and exposes the +#' following dynamic variables contextualized to the current step: +#' +#' - `"{.step}"`: The validation step name +#' - `"{.col}"`: The current column name +#' - `"{.seg_col}"`: The current segment's column name +#' - `"{.seg_val}"`: The current segment's value/group +#' +#' The glue context also supports ordinary expressions for further flexibility +#' (e.g., `"{toupper(.step)}"`) as long as they return a length-1 string. +#' #' @section Briefs: #' #' Want to describe this validation step in some detail? Keep in mind that this @@ -177,7 +196,7 @@ #' ```r #' agent %>% #' col_vals_lte( -#' columns = vars(a), +#' columns = a, #' value = 1, #' na_pass = TRUE, #' preconditions = ~ . %>% dplyr::filter(a < 10), @@ -193,7 +212,7 @@ #' ```yaml #' steps: #' - col_vals_lte: -#' columns: vars(a) +#' columns: c(a) #' value: 1.0 #' na_pass: true #' preconditions: ~. %>% dplyr::filter(a < 10) @@ -240,7 +259,7 @@ #' ```r #' agent <- #' create_agent(tbl = tbl) %>% -#' col_vals_lte(columns = vars(c), value = 4) %>% +#' col_vals_lte(columns = c, value = 4) %>% #' interrogate() #' ``` #' @@ -262,7 +281,7 @@ #' #' ```{r} #' tbl %>% -#' col_vals_lte(columns = vars(c), value = 4) %>% +#' col_vals_lte(columns = c, value = 4) %>% #' dplyr::pull(c) #' ``` #' @@ -272,7 +291,7 @@ #' time. This is primarily used in **testthat** tests. #' #' ```r -#' expect_col_vals_lte(tbl, columns = vars(c), value = 4) +#' expect_col_vals_lte(tbl, columns = c, value = 4) #' ``` #' #' ## D: Using the test function @@ -281,7 +300,7 @@ #' us. #' #' ```{r} -#' test_col_vals_lte(tbl, columns = vars(c), value = 4) +#' test_col_vals_lte(tbl, columns = c, value = 4) #' ``` #' #' @family validation functions @@ -310,13 +329,10 @@ col_vals_lte <- function( active = TRUE ) { - # Get `columns` as a label - columns_expr <- - rlang::as_label(rlang::quo(!!enquo(columns))) %>% - gsub("^\"|\"$", "", .) - # Capture the `columns` expression columns <- rlang::enquo(columns) + # Get `columns` as a label + columns_expr <- as_columns_expr(columns) # Resolve the columns based on the expression columns <- resolve_columns(x = x, var_expr = columns, preconditions) @@ -334,7 +350,7 @@ col_vals_lte <- function( secret_agent <- create_agent(x, label = "::QUIET::") %>% col_vals_lte( - columns = columns, + columns = tidyselect::all_of(columns), value = value, na_pass = na_pass, preconditions = preconditions, @@ -375,6 +391,7 @@ col_vals_lte <- function( # Add one or more validation steps based on the # length of the `columns` variable + label <- resolve_label(label, columns, segments_list) for (i in seq_along(columns)) { for (j in seq_along(segments_list)) { @@ -396,7 +413,7 @@ col_vals_lte <- function( seg_val = seg_val, actions = covert_actions(actions, agent), step_id = step_id[i], - label = label, + label = label[[i, j]], brief = brief[i], active = active ) diff --git a/R/col_vals_make_set.R b/R/col_vals_make_set.R index f6323ab52..ca0209e2f 100644 --- a/R/col_vals_make_set.R +++ b/R/col_vals_make_set.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -73,12 +73,17 @@ #' #' @section Column Names: #' -#' If providing multiple column names, the result will be an expansion of -#' validation steps to that number of column names (e.g., `vars(col_a, col_b)` -#' will result in the entry of two validation steps). Aside from column names in -#' quotes and in `vars()`, **tidyselect** helper functions are available for -#' specifying columns. They are: `starts_with()`, `ends_with()`, `contains()`, -#' `matches()`, and `everything()`. +#' `columns` may be a single column (as symbol `a` or string `"a"`) or a vector +#' of columns (`c(a, b, c)` or `c("a", "b", "c")`). `{tidyselect}` helpers +#' are also supported, such as `contains("date")` and `where(is.double)`. If +#' passing an *external vector* of columns, it should be wrapped in `all_of()`. +#' +#' When multiple columns are selected by `columns`, the result will be an +#' expansion of validation steps to that number of columns (e.g., +#' `c(col_a, col_b)` will result in the entry of two validation steps). +#' +#' Previously, columns could be specified in `vars()`. This continues to work, +#' but `c()` offers the same capability and supersedes `vars()` in `columns`. #' #' @section Preconditions: #' @@ -146,6 +151,20 @@ #' quarter of the total test units fails, the other `stop()`s at the same #' threshold level). #' +#' @section Labels: +#' +#' `label` may be a single string or a character vector that matches the number +#' of expanded steps. `label` also supports `{glue}` syntax and exposes the +#' following dynamic variables contextualized to the current step: +#' +#' - `"{.step}"`: The validation step name +#' - `"{.col}"`: The current column name +#' - `"{.seg_col}"`: The current segment's column name +#' - `"{.seg_val}"`: The current segment's value/group +#' +#' The glue context also supports ordinary expressions for further flexibility +#' (e.g., `"{toupper(.step)}"`) as long as they return a length-1 string. +#' #' @section Briefs: #' #' Want to describe this validation step in some detail? Keep in mind that this @@ -170,7 +189,7 @@ #' ```r #' agent %>% #' col_vals_make_set( -#' columns = vars(a), +#' columns = a, #' set = c(1, 2, 3, 4), #' preconditions = ~ . %>% dplyr::filter(a < 10), #' segments = b ~ c("group_1", "group_2"), @@ -185,7 +204,7 @@ #' ```yaml #' steps: #' - col_vals_make_set: -#' columns: vars(a) +#' columns: c(a) #' set: #' - 1.0 #' - 2.0 @@ -226,7 +245,7 @@ #' agent <- #' create_agent(tbl = small_table) %>% #' col_vals_make_set( -#' columns = vars(f), set = c("low", "mid", "high") +#' columns = f, set = c("low", "mid", "high") #' ) %>% #' interrogate() #' ``` @@ -250,7 +269,7 @@ #' ```{r} #' small_table %>% #' col_vals_make_set( -#' columns = vars(f), set = c("low", "mid", "high") +#' columns = f, set = c("low", "mid", "high") #' ) %>% #' dplyr::pull(f) %>% #' unique() @@ -264,7 +283,7 @@ #' ```r #' expect_col_vals_make_set( #' small_table, -#' columns = vars(f), set = c("low", "mid", "high") +#' columns = f, set = c("low", "mid", "high") #' ) #' ``` #' @@ -276,7 +295,7 @@ #' ```{r} #' small_table %>% #' test_col_vals_make_set( -#' columns = vars(f), set = c("low", "mid", "high") +#' columns = f, set = c("low", "mid", "high") #' ) #' ``` #' @@ -303,13 +322,10 @@ col_vals_make_set <- function( active = TRUE ) { - # Get `columns` as a label - columns_expr <- - rlang::as_label(rlang::quo(!!enquo(columns))) %>% - gsub("^\"|\"$", "", .) - # Capture the `columns` expression columns <- rlang::enquo(columns) + # Get `columns` as a label + columns_expr <- as_columns_expr(columns) # Resolve the columns based on the expression columns <- resolve_columns(x = x, var_expr = columns, preconditions) @@ -327,7 +343,7 @@ col_vals_make_set <- function( secret_agent <- create_agent(x, label = "::QUIET::") %>% col_vals_make_set( - columns = columns, + columns = tidyselect::all_of(columns), set = set, preconditions = preconditions, segments = segments, @@ -367,6 +383,7 @@ col_vals_make_set <- function( # Add one or more validation steps based on the # length of the `columns` variable + label <- resolve_label(label, columns, segments_list) for (i in seq_along(columns)) { for (j in seq_along(segments_list)) { @@ -387,7 +404,7 @@ col_vals_make_set <- function( seg_val = seg_val, actions = covert_actions(actions, agent), step_id = step_id[i], - label = label, + label = label[[i, j]], brief = brief[i], active = active ) diff --git a/R/col_vals_make_subset.R b/R/col_vals_make_subset.R index e88fbe6d3..045affd87 100644 --- a/R/col_vals_make_subset.R +++ b/R/col_vals_make_subset.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -69,12 +69,17 @@ #' #' @section Column Names: #' -#' If providing multiple column names, the result will be an expansion of -#' validation steps to that number of column names (e.g., `vars(col_a, col_b)` -#' will result in the entry of two validation steps). Aside from column names in -#' quotes and in `vars()`, **tidyselect** helper functions are available for -#' specifying columns. They are: `starts_with()`, `ends_with()`, `contains()`, -#' `matches()`, and `everything()`. +#' `columns` may be a single column (as symbol `a` or string `"a"`) or a vector +#' of columns (`c(a, b, c)` or `c("a", "b", "c")`). `{tidyselect}` helpers +#' are also supported, such as `contains("date")` and `where(is.double)`. If +#' passing an *external vector* of columns, it should be wrapped in `all_of()`. +#' +#' When multiple columns are selected by `columns`, the result will be an +#' expansion of validation steps to that number of columns (e.g., +#' `c(col_a, col_b)` will result in the entry of two validation steps). +#' +#' Previously, columns could be specified in `vars()`. This continues to work, +#' but `c()` offers the same capability and supersedes `vars()` in `columns`. #' #' @section Preconditions: #' @@ -142,6 +147,20 @@ #' quarter of the total test units fails, the other `stop()`s at the same #' threshold level). #' +#' @section Labels: +#' +#' `label` may be a single string or a character vector that matches the number +#' of expanded steps. `label` also supports `{glue}` syntax and exposes the +#' following dynamic variables contextualized to the current step: +#' +#' - `"{.step}"`: The validation step name +#' - `"{.col}"`: The current column name +#' - `"{.seg_col}"`: The current segment's column name +#' - `"{.seg_val}"`: The current segment's value/group +#' +#' The glue context also supports ordinary expressions for further flexibility +#' (e.g., `"{toupper(.step)}"`) as long as they return a length-1 string. +#' #' @section Briefs: #' #' Want to describe this validation step in some detail? Keep in mind that this @@ -166,7 +185,7 @@ #' ```r #' agent %>% #' col_vals_make_subset( -#' columns = vars(a), +#' columns = a, #' set = c(1, 2, 3, 4), #' preconditions = ~ . %>% dplyr::filter(a < 10), #' segments = b ~ c("group_1", "group_2"), @@ -181,7 +200,7 @@ #' ```yaml #' steps: #' - col_vals_make_subset: -#' columns: vars(a) +#' columns: c(a) #' set: #' - 1.0 #' - 2.0 @@ -223,7 +242,7 @@ #' agent <- #' create_agent(tbl = small_table) %>% #' col_vals_make_subset( -#' columns = vars(f), set = c("low", "high") +#' columns = f, set = c("low", "high") #' ) %>% #' interrogate() #' ``` @@ -247,7 +266,7 @@ #' ```{r} #' small_table %>% #' col_vals_make_subset( -#' columns = vars(f), set = c("low", "high") +#' columns = f, set = c("low", "high") #' ) %>% #' dplyr::pull(f) %>% #' unique() @@ -261,7 +280,7 @@ #' ```r #' expect_col_vals_make_subset( #' small_table, -#' columns = vars(f), set = c("low", "high") +#' columns = f, set = c("low", "high") #' ) #' ``` #' @@ -273,7 +292,7 @@ #' ```{r} #' small_table %>% #' test_col_vals_make_subset( -#' columns = vars(f), set = c("low", "high") +#' columns = f, set = c("low", "high") #' ) #' ``` #' @@ -300,13 +319,10 @@ col_vals_make_subset <- function( active = TRUE ) { - # Get `columns` as a label - columns_expr <- - rlang::as_label(rlang::quo(!!enquo(columns))) %>% - gsub("^\"|\"$", "", .) - # Capture the `columns` expression columns <- rlang::enquo(columns) + # Get `columns` as a label + columns_expr <- as_columns_expr(columns) # Resolve the columns based on the expression columns <- resolve_columns(x = x, var_expr = columns, preconditions) @@ -324,7 +340,7 @@ col_vals_make_subset <- function( secret_agent <- create_agent(x, label = "::QUIET::") %>% col_vals_make_subset( - columns = columns, + columns = tidyselect::all_of(columns), set = set, preconditions = preconditions, segments = segments, @@ -364,6 +380,7 @@ col_vals_make_subset <- function( # Add one or more validation steps based on the # length of the `columns` variable + label <- resolve_label(label, columns, segments_list) for (i in seq_along(columns)) { for (j in seq_along(segments_list)) { @@ -384,7 +401,7 @@ col_vals_make_subset <- function( seg_val = seg_val, actions = covert_actions(actions, agent), step_id = step_id[i], - label = label, + label = label[[i, j]], brief = brief[i], active = active ) diff --git a/R/col_vals_not_between.R b/R/col_vals_not_between.R index ccc12c229..1232882ca 100644 --- a/R/col_vals_not_between.R +++ b/R/col_vals_not_between.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -96,12 +96,17 @@ #' #' @section Column Names: #' -#' If providing multiple column names to `columns`, the result will be an -#' expansion of validation steps to that number of column names (e.g., -#' `vars(col_a, col_b)` will result in the entry of two validation steps). Aside -#' from column names in quotes and in `vars()`, **tidyselect** helper functions -#' are available for specifying columns. They are: `starts_with()`, -#' `ends_with()`, `contains()`, `matches()`, and `everything()`. +#' `columns` may be a single column (as symbol `a` or string `"a"`) or a vector +#' of columns (`c(a, b, c)` or `c("a", "b", "c")`). `{tidyselect}` helpers +#' are also supported, such as `contains("date")` and `where(is.double)`. If +#' passing an *external vector* of columns, it should be wrapped in `all_of()`. +#' +#' When multiple columns are selected by `columns`, the result will be an +#' expansion of validation steps to that number of columns (e.g., +#' `c(col_a, col_b)` will result in the entry of two validation steps). +#' +#' Previously, columns could be specified in `vars()`. This continues to work, +#' but `c()` offers the same capability and supersedes `vars()` in `columns`. #' #' @section Missing Values: #' @@ -176,6 +181,20 @@ #' quarter of the total test units fails, the other `stop()`s at the same #' threshold level). #' +#' @section Labels: +#' +#' `label` may be a single string or a character vector that matches the number +#' of expanded steps. `label` also supports `{glue}` syntax and exposes the +#' following dynamic variables contextualized to the current step: +#' +#' - `"{.step}"`: The validation step name +#' - `"{.col}"`: The current column name +#' - `"{.seg_col}"`: The current segment's column name +#' - `"{.seg_val}"`: The current segment's value/group +#' +#' The glue context also supports ordinary expressions for further flexibility +#' (e.g., `"{toupper(.step)}"`) as long as they return a length-1 string. +#' #' @section Briefs: #' #' Want to describe this validation step in some detail? Keep in mind that this @@ -200,7 +219,7 @@ #' ```r #' agent %>% #' col_vals_not_between( -#' columns = vars(a), +#' columns = a, #' left = 1, #' right = 2, #' inclusive = c(TRUE, FALSE), @@ -218,7 +237,7 @@ #' ```yaml #' steps: #' - col_vals_not_between: -#' columns: vars(a) +#' columns: c(a) #' left: 1.0 #' right: 2.0 #' inclusive: @@ -262,7 +281,7 @@ #' agent <- #' create_agent(tbl = small_table) %>% #' col_vals_not_between( -#' columns = vars(c), +#' columns = c, #' left = 10, right = 20, #' na_pass = TRUE #' ) %>% @@ -288,7 +307,7 @@ #' ```{r} #' small_table %>% #' col_vals_not_between( -#' columns = vars(c), +#' columns = c, #' left = 10, right = 20, #' na_pass = TRUE #' ) %>% @@ -302,7 +321,7 @@ #' #' ```r #' expect_col_vals_not_between( -#' small_table, columns = vars(c), +#' small_table, columns = c, #' left = 10, right = 20, #' na_pass = TRUE #' ) @@ -316,7 +335,7 @@ #' ```{r} #' small_table %>% #' test_col_vals_not_between( -#' columns = vars(c), +#' columns = c, #' left = 10, right = 20, #' na_pass = TRUE #' ) @@ -333,7 +352,7 @@ #' ```{r} #' small_table %>% #' test_col_vals_not_between( -#' columns = vars(c), +#' columns = c, #' left = 9, right = 20, #' inclusive = c(FALSE, TRUE), #' na_pass = TRUE @@ -368,13 +387,10 @@ col_vals_not_between <- function( active = TRUE ) { - # Get `columns` as a label - columns_expr <- - rlang::as_label(rlang::quo(!!enquo(columns))) %>% - gsub("^\"|\"$", "", .) - # Capture the `columns` expression columns <- rlang::enquo(columns) + # Get `columns` as a label + columns_expr <- as_columns_expr(columns) # Resolve the columns based on the expression columns <- resolve_columns(x = x, var_expr = columns, preconditions) @@ -396,7 +412,7 @@ col_vals_not_between <- function( secret_agent <- create_agent(x, label = "::QUIET::") %>% col_vals_not_between( - columns = columns, + columns = tidyselect::all_of(columns), left = left, right = right, inclusive = inclusive, @@ -439,6 +455,7 @@ col_vals_not_between <- function( # Add one or more validation steps based on the # length of the `columns` variable + label <- resolve_label(label, columns, segments_list) for (i in seq_along(columns)) { for (j in seq_along(segments_list)) { @@ -460,7 +477,7 @@ col_vals_not_between <- function( seg_val = seg_val, actions = covert_actions(actions, agent), step_id = step_id[i], - label = label, + label = label[[i, j]], brief = brief[i], active = active ) diff --git a/R/col_vals_not_equal.R b/R/col_vals_not_equal.R index 43ecef4c4..a07e1284d 100644 --- a/R/col_vals_not_equal.R +++ b/R/col_vals_not_equal.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -70,12 +70,17 @@ #' #' @section Column Names: #' -#' If providing multiple column names, the result will be an expansion of -#' validation steps to that number of column names (e.g., `vars(col_a, col_b)` -#' will result in the entry of two validation steps). Aside from column names in -#' quotes and in `vars()`, **tidyselect** helper functions are available for -#' specifying columns. They are: `starts_with()`, `ends_with()`, `contains()`, -#' `matches()`, and `everything()`. +#' `columns` may be a single column (as symbol `a` or string `"a"`) or a vector +#' of columns (`c(a, b, c)` or `c("a", "b", "c")`). `{tidyselect}` helpers +#' are also supported, such as `contains("date")` and `where(is.double)`. If +#' passing an *external vector* of columns, it should be wrapped in `all_of()`. +#' +#' When multiple columns are selected by `columns`, the result will be an +#' expansion of validation steps to that number of columns (e.g., +#' `c(col_a, col_b)` will result in the entry of two validation steps). +#' +#' Previously, columns could be specified in `vars()`. This continues to work, +#' but `c()` offers the same capability and supersedes `vars()` in `columns`. #' #' @section Missing Values: #' @@ -150,6 +155,20 @@ #' quarter of the total test units fails, the other `stop()`s at the same #' threshold level). #' +#' @section Labels: +#' +#' `label` may be a single string or a character vector that matches the number +#' of expanded steps. `label` also supports `{glue}` syntax and exposes the +#' following dynamic variables contextualized to the current step: +#' +#' - `"{.step}"`: The validation step name +#' - `"{.col}"`: The current column name +#' - `"{.seg_col}"`: The current segment's column name +#' - `"{.seg_val}"`: The current segment's value/group +#' +#' The glue context also supports ordinary expressions for further flexibility +#' (e.g., `"{toupper(.step)}"`) as long as they return a length-1 string. +#' #' @section Briefs: #' #' Want to describe this validation step in some detail? Keep in mind that this @@ -174,7 +193,7 @@ #' ```r #' agent %>% #' col_vals_not_equal( -#' columns = vars(a), +#' columns = a, #' value = 1, #' na_pass = TRUE, #' preconditions = ~ . %>% dplyr::filter(a < 10), @@ -190,7 +209,7 @@ #' ```yaml #' steps: #' - col_vals_not_equal: -#' columns: vars(a) +#' columns: c(a) #' value: 1.0 #' na_pass: true #' preconditions: ~. %>% dplyr::filter(a < 10) @@ -237,7 +256,7 @@ #' ```r #' agent <- #' create_agent(tbl = tbl) %>% -#' col_vals_not_equal(columns = vars(a), value = 6) %>% +#' col_vals_not_equal(columns = a, value = 6) %>% #' interrogate() #' ``` #' @@ -259,7 +278,7 @@ #' #' ```{r} #' tbl %>% -#' col_vals_not_equal(columns = vars(a), value = 6) %>% +#' col_vals_not_equal(columns = a, value = 6) %>% #' dplyr::pull(a) #' ``` #' @@ -269,7 +288,7 @@ #' time. This is primarily used in **testthat** tests. #' #' ```r -#' expect_col_vals_not_equal(tbl, columns = vars(a), value = 6) +#' expect_col_vals_not_equal(tbl, columns = a, value = 6) #' ``` #' #' ## D: Using the test function @@ -278,7 +297,7 @@ #' us. #' #' ```{r} -#' test_col_vals_not_equal(tbl, columns = vars(a), value = 6) +#' test_col_vals_not_equal(tbl, columns = a, value = 6) #' ``` #' #' @family validation functions @@ -307,13 +326,10 @@ col_vals_not_equal <- function( active = TRUE ) { - # Get `columns` as a label - columns_expr <- - rlang::as_label(rlang::quo(!!enquo(columns))) %>% - gsub("^\"|\"$", "", .) - # Capture the `columns` expression columns <- rlang::enquo(columns) + # Get `columns` as a label + columns_expr <- as_columns_expr(columns) # Resolve the columns based on the expression columns <- resolve_columns(x = x, var_expr = columns, preconditions) @@ -331,7 +347,7 @@ col_vals_not_equal <- function( secret_agent <- create_agent(x, label = "::QUIET::") %>% col_vals_not_equal( - columns = columns, + columns = tidyselect::all_of(columns), value = value, na_pass = na_pass, preconditions = preconditions, @@ -372,6 +388,7 @@ col_vals_not_equal <- function( # Add one or more validation steps based on the # length of the `columns` variable + label <- resolve_label(label, columns, segments_list) for (i in seq_along(columns)) { for (j in seq_along(segments_list)) { @@ -393,7 +410,7 @@ col_vals_not_equal <- function( seg_val = seg_val, actions = covert_actions(actions, agent), step_id = step_id[i], - label = label, + label = label[[i, j]], brief = brief[i], active = active ) diff --git a/R/col_vals_not_in_set.R b/R/col_vals_not_in_set.R index 6595770bf..a9d2c232e 100644 --- a/R/col_vals_not_in_set.R +++ b/R/col_vals_not_in_set.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -69,12 +69,17 @@ #' #' @section Column Names: #' -#' If providing multiple column names, the result will be an expansion of -#' validation steps to that number of column names (e.g., `vars(col_a, col_b)` -#' will result in the entry of two validation steps). Aside from column names in -#' quotes and in `vars()`, **tidyselect** helper functions are available for -#' specifying columns. They are: `starts_with()`, `ends_with()`, `contains()`, -#' `matches()`, and `everything()`. +#' `columns` may be a single column (as symbol `a` or string `"a"`) or a vector +#' of columns (`c(a, b, c)` or `c("a", "b", "c")`). `{tidyselect}` helpers +#' are also supported, such as `contains("date")` and `where(is.double)`. If +#' passing an *external vector* of columns, it should be wrapped in `all_of()`. +#' +#' When multiple columns are selected by `columns`, the result will be an +#' expansion of validation steps to that number of columns (e.g., +#' `c(col_a, col_b)` will result in the entry of two validation steps). +#' +#' Previously, columns could be specified in `vars()`. This continues to work, +#' but `c()` offers the same capability and supersedes `vars()` in `columns`. #' #' @section Preconditions: #' @@ -142,6 +147,20 @@ #' quarter of the total test units fails, the other `stop()`s at the same #' threshold level). #' +#' @section Labels: +#' +#' `label` may be a single string or a character vector that matches the number +#' of expanded steps. `label` also supports `{glue}` syntax and exposes the +#' following dynamic variables contextualized to the current step: +#' +#' - `"{.step}"`: The validation step name +#' - `"{.col}"`: The current column name +#' - `"{.seg_col}"`: The current segment's column name +#' - `"{.seg_val}"`: The current segment's value/group +#' +#' The glue context also supports ordinary expressions for further flexibility +#' (e.g., `"{toupper(.step)}"`) as long as they return a length-1 string. +#' #' @section Briefs: #' #' Want to describe this validation step in some detail? Keep in mind that this @@ -166,7 +185,7 @@ #' ```r #' agent %>% #' col_vals_not_in_set( -#' columns = vars(a), +#' columns = a, #' set = c(1, 2, 3, 4), #' preconditions = ~ . %>% dplyr::filter(a < 10), #' segments = b ~ c("group_1", "group_2"), @@ -181,7 +200,7 @@ #' ```yaml #' steps: #' - col_vals_not_in_set: -#' columns: vars(a) +#' columns: c(a) #' set: #' - 1.0 #' - 2.0 @@ -218,7 +237,7 @@ #' agent <- #' create_agent(tbl = small_table) %>% #' col_vals_not_in_set( -#' columns = vars(f), set = c("lows", "mids", "highs") +#' columns = f, set = c("lows", "mids", "highs") #' ) %>% #' interrogate() #' ``` @@ -242,7 +261,7 @@ #' ``` #' small_table %>% #' col_vals_not_in_set( -#' columns = vars(f), set = c("lows", "mids", "highs") +#' columns = f, set = c("lows", "mids", "highs") #' ) %>% #' dplyr::pull(f) %>% #' unique() @@ -256,7 +275,7 @@ #' ```r #' expect_col_vals_not_in_set( #' small_table, -#' columns = vars(f), set = c("lows", "mids", "highs") +#' columns = f, set = c("lows", "mids", "highs") #' ) #' ``` #' @@ -268,7 +287,7 @@ #' ```{r} #' small_table %>% #' test_col_vals_not_in_set( -#' columns = vars(f), set = c("lows", "mids", "highs") +#' columns = f, set = c("lows", "mids", "highs") #' ) #' ``` #' @@ -297,13 +316,10 @@ col_vals_not_in_set <- function( active = TRUE ) { - # Get `columns` as a label - columns_expr <- - rlang::as_label(rlang::quo(!!enquo(columns))) %>% - gsub("^\"|\"$", "", .) - # Capture the `columns` expression columns <- rlang::enquo(columns) + # Get `columns` as a label + columns_expr <- as_columns_expr(columns) # Resolve the columns based on the expression columns <- resolve_columns(x = x, var_expr = columns, preconditions) @@ -321,7 +337,7 @@ col_vals_not_in_set <- function( secret_agent <- create_agent(x, label = "::QUIET::") %>% col_vals_not_in_set( - columns = columns, + columns = tidyselect::all_of(columns), set = set, preconditions = preconditions, segments = segments, @@ -361,6 +377,7 @@ col_vals_not_in_set <- function( # Add one or more validation steps based on the # length of the `columns` variable + label <- resolve_label(label, columns, segments_list) for (i in seq_along(columns)) { for (j in seq_along(segments_list)) { @@ -381,7 +398,7 @@ col_vals_not_in_set <- function( seg_val = seg_val, actions = covert_actions(actions, agent), step_id = step_id[i], - label = label, + label = label[[i, j]], brief = brief[i], active = active ) diff --git a/R/col_vals_not_null.R b/R/col_vals_not_null.R index 4065aad83..d903a340a 100644 --- a/R/col_vals_not_null.R +++ b/R/col_vals_not_null.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -63,12 +63,17 @@ #' #' @section Column Names: #' -#' If providing multiple column names, the result will be an expansion of -#' validation steps to that number of column names (e.g., `vars(col_a, col_b)` -#' will result in the entry of two validation steps). Aside from column names in -#' quotes and in `vars()`, **tidyselect** helper functions are available for -#' specifying columns. They are: `starts_with()`, `ends_with()`, `contains()`, -#' `matches()`, and `everything()`. +#' `columns` may be a single column (as symbol `a` or string `"a"`) or a vector +#' of columns (`c(a, b, c)` or `c("a", "b", "c")`). `{tidyselect}` helpers +#' are also supported, such as `contains("date")` and `where(is.double)`. If +#' passing an *external vector* of columns, it should be wrapped in `all_of()`. +#' +#' When multiple columns are selected by `columns`, the result will be an +#' expansion of validation steps to that number of columns (e.g., +#' `c(col_a, col_b)` will result in the entry of two validation steps). +#' +#' Previously, columns could be specified in `vars()`. This continues to work, +#' but `c()` offers the same capability and supersedes `vars()` in `columns`. #' #' @section Preconditions: #' @@ -136,6 +141,20 @@ #' quarter of the total test units fails, the other `stop()`s at the same #' threshold level). #' +#' @section Labels: +#' +#' `label` may be a single string or a character vector that matches the number +#' of expanded steps. `label` also supports `{glue}` syntax and exposes the +#' following dynamic variables contextualized to the current step: +#' +#' - `"{.step}"`: The validation step name +#' - `"{.col}"`: The current column name +#' - `"{.seg_col}"`: The current segment's column name +#' - `"{.seg_val}"`: The current segment's value/group +#' +#' The glue context also supports ordinary expressions for further flexibility +#' (e.g., `"{toupper(.step)}"`) as long as they return a length-1 string. +#' #' @section Briefs: #' #' Want to describe this validation step in some detail? Keep in mind that this @@ -160,7 +179,7 @@ #' ```r #' agent %>% #' col_vals_not_null( -#' columns = vars(a), +#' columns = a, #' preconditions = ~ . %>% dplyr::filter(a < 10), #' segments = b ~ c("group_1", "group_2"), #' actions = action_levels(warn_at = 0.1, stop_at = 0.2), @@ -174,7 +193,7 @@ #' ```yaml #' steps: #' - col_vals_not_null: -#' columns: vars(a) +#' columns: c(a) #' preconditions: ~. %>% dplyr::filter(a < 10) #' segments: b ~ c("group_1", "group_2") #' actions: @@ -218,7 +237,7 @@ #' ```r #' agent <- #' create_agent(tbl = tbl) %>% -#' col_vals_not_null(columns = vars(b)) %>% +#' col_vals_not_null(columns = b) %>% #' interrogate() #' ``` #' @@ -240,7 +259,7 @@ #' #' ```{r} #' tbl %>% -#' col_vals_not_null(columns = vars(b)) %>% +#' col_vals_not_null(columns = b) %>% #' dplyr::pull(b) #' ``` #' @@ -250,7 +269,7 @@ #' time. This is primarily used in **testthat** tests. #' #' ```r -#' expect_col_vals_not_null(tbl, columns = vars(b)) +#' expect_col_vals_not_null(tbl, columns = b) #' ``` #' #' ## D: Using the test function @@ -259,7 +278,7 @@ #' us. #' #' ```{r} -#' tbl %>% test_col_vals_not_null(columns = vars(b)) +#' tbl %>% test_col_vals_not_null(columns = b) #' ``` #' #' @family validation functions @@ -288,13 +307,10 @@ col_vals_not_null <- function( values <- NULL - # Get `columns` as a label - columns_expr <- - rlang::as_label(rlang::quo(!!enquo(columns))) %>% - gsub("^\"|\"$", "", .) - # Capture the `columns` expression columns <- rlang::enquo(columns) + # Get `columns` as a label + columns_expr <- as_columns_expr(columns) # Resolve the columns based on the expression columns <- resolve_columns(x = x, var_expr = columns, preconditions) @@ -312,7 +328,7 @@ col_vals_not_null <- function( secret_agent <- create_agent(x, label = "::QUIET::") %>% col_vals_not_null( - columns = columns, + columns = tidyselect::all_of(columns), preconditions = preconditions, segments = segments, label = label, @@ -351,6 +367,7 @@ col_vals_not_null <- function( # Add one or more validation steps based on the # length of the `columns` variable + label <- resolve_label(label, columns, segments_list) for (i in seq_along(columns)) { for (j in seq_along(segments_list)) { @@ -370,7 +387,7 @@ col_vals_not_null <- function( seg_val = seg_val, actions = covert_actions(actions, agent), step_id = step_id[i], - label = label, + label = label[[i, j]], brief = brief[i], active = active ) diff --git a/R/col_vals_null.R b/R/col_vals_null.R index 258a436c7..167981165 100644 --- a/R/col_vals_null.R +++ b/R/col_vals_null.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -62,12 +62,17 @@ #' #' @section Column Names: #' -#' If providing multiple column names, the result will be an expansion of -#' validation steps to that number of column names (e.g., `vars(col_a, col_b)` -#' will result in the entry of two validation steps). Aside from column names in -#' quotes and in `vars()`, **tidyselect** helper functions are available for -#' specifying columns. They are: `starts_with()`, `ends_with()`, `contains()`, -#' `matches()`, and `everything()`. +#' `columns` may be a single column (as symbol `a` or string `"a"`) or a vector +#' of columns (`c(a, b, c)` or `c("a", "b", "c")`). `{tidyselect}` helpers +#' are also supported, such as `contains("date")` and `where(is.double)`. If +#' passing an *external vector* of columns, it should be wrapped in `all_of()`. +#' +#' When multiple columns are selected by `columns`, the result will be an +#' expansion of validation steps to that number of columns (e.g., +#' `c(col_a, col_b)` will result in the entry of two validation steps). +#' +#' Previously, columns could be specified in `vars()`. This continues to work, +#' but `c()` offers the same capability and supersedes `vars()` in `columns`. #' #' @section Preconditions: #' @@ -135,6 +140,20 @@ #' quarter of the total test units fails, the other `stop()`s at the same #' threshold level). #' +#' @section Labels: +#' +#' `label` may be a single string or a character vector that matches the number +#' of expanded steps. `label` also supports `{glue}` syntax and exposes the +#' following dynamic variables contextualized to the current step: +#' +#' - `"{.step}"`: The validation step name +#' - `"{.col}"`: The current column name +#' - `"{.seg_col}"`: The current segment's column name +#' - `"{.seg_val}"`: The current segment's value/group +#' +#' The glue context also supports ordinary expressions for further flexibility +#' (e.g., `"{toupper(.step)}"`) as long as they return a length-1 string. +#' #' @section Briefs: #' #' Want to describe this validation step in some detail? Keep in mind that this @@ -159,7 +178,7 @@ #' ```r #' agent %>% #' col_vals_null( -#' columns = vars(a), +#' columns = a, #' preconditions = ~ . %>% dplyr::filter(a < 10), #' segments = b ~ c("group_1", "group_2"), #' actions = action_levels(warn_at = 0.1, stop_at = 0.2), @@ -173,7 +192,7 @@ #' ```yaml #' steps: #' - col_vals_null: -#' columns: vars(a) +#' columns: c(a) #' preconditions: ~. %>% dplyr::filter(a < 10) #' segments: b ~ c("group_1", "group_2") #' actions: @@ -217,7 +236,7 @@ #' ```r #' agent <- #' create_agent(tbl = tbl) %>% -#' col_vals_null(columns = vars(c)) %>% +#' col_vals_null(columns = c) %>% #' interrogate() #' ``` #' @@ -239,7 +258,7 @@ #' #' ```{r} #' tbl %>% -#' col_vals_null(columns = vars(c)) %>% +#' col_vals_null(columns = c) %>% #' dplyr::pull(c) #' ``` #' @@ -249,7 +268,7 @@ #' time. This is primarily used in **testthat** tests. #' #' ```r -#' expect_col_vals_null(tbl, columns = vars(c)) +#' expect_col_vals_null(tbl, columns = c) #' ``` #' #' ## D: Using the test function @@ -258,7 +277,7 @@ #' us. #' #' ```{r} -#' tbl %>% test_col_vals_null(columns = vars(c)) +#' tbl %>% test_col_vals_null(columns = c) #' ``` #' #' @family validation functions @@ -287,13 +306,10 @@ col_vals_null <- function( values <- NULL - # Get `columns` as a label - columns_expr <- - rlang::as_label(rlang::quo(!!enquo(columns))) %>% - gsub("^\"|\"$", "", .) - # Capture the `columns` expression columns <- rlang::enquo(columns) + # Get `columns` as a label + columns_expr <- as_columns_expr(columns) # Resolve the columns based on the expression columns <- resolve_columns(x = x, var_expr = columns, preconditions) @@ -311,7 +327,7 @@ col_vals_null <- function( secret_agent <- create_agent(x, label = "::QUIET::") %>% col_vals_null( - columns = columns, + columns = tidyselect::all_of(columns), preconditions = preconditions, segments = segments, label = label, @@ -350,6 +366,7 @@ col_vals_null <- function( # Add one or more validation steps based on the # length of the `columns` variable + label <- resolve_label(label, columns, segments_list) for (i in seq_along(columns)) { for (j in seq_along(segments_list)) { @@ -369,7 +386,7 @@ col_vals_null <- function( seg_val = seg_val, actions = covert_actions(actions, agent), step_id = step_id[i], - label = label, + label = label[[i, j]], brief = brief[i], active = active ) diff --git a/R/col_vals_regex.R b/R/col_vals_regex.R index 80a567388..d9350f468 100644 --- a/R/col_vals_regex.R +++ b/R/col_vals_regex.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -69,12 +69,17 @@ #' #' @section Column Names: #' -#' If providing multiple column names, the result will be an expansion of -#' validation steps to that number of column names (e.g., `vars(col_a, col_b)` -#' will result in the entry of two validation steps). Aside from column names in -#' quotes and in `vars()`, **tidyselect** helper functions are available for -#' specifying columns. They are: `starts_with()`, `ends_with()`, `contains()`, -#' `matches()`, and `everything()`. +#' `columns` may be a single column (as symbol `a` or string `"a"`) or a vector +#' of columns (`c(a, b, c)` or `c("a", "b", "c")`). `{tidyselect}` helpers +#' are also supported, such as `contains("date")` and `where(is.double)`. If +#' passing an *external vector* of columns, it should be wrapped in `all_of()`. +#' +#' When multiple columns are selected by `columns`, the result will be an +#' expansion of validation steps to that number of columns (e.g., +#' `c(col_a, col_b)` will result in the entry of two validation steps). +#' +#' Previously, columns could be specified in `vars()`. This continues to work, +#' but `c()` offers the same capability and supersedes `vars()` in `columns`. #' #' @section Missing Values: #' @@ -149,6 +154,20 @@ #' quarter of the total test units fails, the other `stop()`s at the same #' threshold level). #' +#' @section Labels: +#' +#' `label` may be a single string or a character vector that matches the number +#' of expanded steps. `label` also supports `{glue}` syntax and exposes the +#' following dynamic variables contextualized to the current step: +#' +#' - `"{.step}"`: The validation step name +#' - `"{.col}"`: The current column name +#' - `"{.seg_col}"`: The current segment's column name +#' - `"{.seg_val}"`: The current segment's value/group +#' +#' The glue context also supports ordinary expressions for further flexibility +#' (e.g., `"{toupper(.step)}"`) as long as they return a length-1 string. +#' #' @section Briefs: #' #' Want to describe this validation step in some detail? Keep in mind that this @@ -173,7 +192,7 @@ #' ``` #' agent %>% #' col_vals_regex( -#' columns = vars(a), +#' columns = a, #' regex = "[0-9]-[a-z]{3}-[0-9]{3}", #' na_pass = TRUE, #' preconditions = ~ . %>% dplyr::filter(a < 10), @@ -189,7 +208,7 @@ #' ```yaml #' steps: #' - col_vals_regex: -#' columns: vars(a) +#' columns: c(a) #' regex: '[0-9]-[a-z]{3}-[0-9]{3}' #' na_pass: true #' preconditions: ~. %>% dplyr::filter(a < 10) @@ -233,7 +252,7 @@ #' ```r #' agent <- #' create_agent(tbl = small_table) %>% -#' col_vals_regex(columns = vars(b), regex = pattern) %>% +#' col_vals_regex(columns = b, regex = pattern) %>% #' interrogate() #' ``` #' @@ -255,7 +274,7 @@ #' #' ```{r} #' small_table %>% -#' col_vals_regex(columns = vars(b), regex = pattern) %>% +#' col_vals_regex(columns = b, regex = pattern) %>% #' dplyr::slice(1:5) #' ``` #' @@ -265,7 +284,7 @@ #' time. This is primarily used in **testthat** tests. #' #' ```r -#' expect_col_vals_regex(small_table, columns = vars(b), regex = pattern) +#' expect_col_vals_regex(small_table, columns = b, regex = pattern) #' ``` #' #' ## D: Using the test function @@ -274,7 +293,7 @@ #' us. #' #' ```{r} -#' small_table %>% test_col_vals_regex(columns = vars(b), regex = pattern) +#' small_table %>% test_col_vals_regex(columns = b, regex = pattern) #' ``` #' #' @family validation functions @@ -301,13 +320,10 @@ col_vals_regex <- function( active = TRUE ) { - # Get `columns` as a label - columns_expr <- - rlang::as_label(rlang::quo(!!enquo(columns))) %>% - gsub("^\"|\"$", "", .) - # Capture the `columns` expression columns <- rlang::enquo(columns) + # Get `columns` as a label + columns_expr <- as_columns_expr(columns) # Resolve the columns based on the expression columns <- resolve_columns(x = x, var_expr = columns, preconditions) @@ -325,7 +341,7 @@ col_vals_regex <- function( secret_agent <- create_agent(x, label = "::QUIET::") %>% col_vals_regex( - columns = columns, + columns = tidyselect::all_of(columns), regex = regex, na_pass = na_pass, preconditions = preconditions, @@ -366,6 +382,7 @@ col_vals_regex <- function( # Add one or more validation steps based on the # length of the `columns` variable + label <- resolve_label(label, columns, segments_list) for (i in seq_along(columns)) { for (j in seq_along(segments_list)) { @@ -387,7 +404,7 @@ col_vals_regex <- function( seg_val = seg_val, actions = covert_actions(actions, agent), step_id = step_id[i], - label = label, + label = label[[i, j]], brief = brief[i], active = active ) diff --git a/R/col_vals_within_spec.R b/R/col_vals_within_spec.R index e72167f82..3e815b418 100644 --- a/R/col_vals_within_spec.R +++ b/R/col_vals_within_spec.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -119,12 +119,17 @@ #' #' @section Column Names: #' -#' If providing multiple column names, the result will be an expansion of -#' validation steps to that number of column names (e.g., `vars(col_a, col_b)` -#' will result in the entry of two validation steps). Aside from column names in -#' quotes and in `vars()`, **tidyselect** helper functions are available for -#' specifying columns. They are: `starts_with()`, `ends_with()`, `contains()`, -#' `matches()`, and `everything()`. +#' `columns` may be a single column (as symbol `a` or string `"a"`) or a vector +#' of columns (`c(a, b, c)` or `c("a", "b", "c")`). `{tidyselect}` helpers +#' are also supported, such as `contains("date")` and `where(is.double)`. If +#' passing an *external vector* of columns, it should be wrapped in `all_of()`. +#' +#' When multiple columns are selected by `columns`, the result will be an +#' expansion of validation steps to that number of columns (e.g., +#' `c(col_a, col_b)` will result in the entry of two validation steps). +#' +#' Previously, columns could be specified in `vars()`. This continues to work, +#' but `c()` offers the same capability and supersedes `vars()` in `columns`. #' #' @section Missing Values: #' @@ -199,6 +204,20 @@ #' quarter of the total test units fails, the other `stop()`s at the same #' threshold level). #' +#' @section Labels: +#' +#' `label` may be a single string or a character vector that matches the number +#' of expanded steps. `label` also supports `{glue}` syntax and exposes the +#' following dynamic variables contextualized to the current step: +#' +#' - `"{.step}"`: The validation step name +#' - `"{.col}"`: The current column name +#' - `"{.seg_col}"`: The current segment's column name +#' - `"{.seg_val}"`: The current segment's value/group +#' +#' The glue context also supports ordinary expressions for further flexibility +#' (e.g., `"{toupper(.step)}"`) as long as they return a length-1 string. +#' #' @section Briefs: #' #' Want to describe this validation step in some detail? Keep in mind that this @@ -223,7 +242,7 @@ #' ```r #' agent %>% #' col_vals_within_spec( -#' columns = vars(a), +#' columns = a, #' spec = "email", #' na_pass = TRUE, #' preconditions = ~ . %>% dplyr::filter(b < 10), @@ -239,7 +258,7 @@ #' ```yaml #' steps: #' - col_vals_within_spec: -#' columns: vars(a) +#' columns: c(a) #' spec: email #' na_pass: true #' preconditions: ~. %>% dplyr::filter(b < 10) @@ -282,7 +301,7 @@ #' agent <- #' create_agent(tbl = spec_slice) %>% #' col_vals_within_spec( -#' columns = vars(email_addresses), +#' columns = email_addresses, #' spec = "email" #' ) %>% #' interrogate() @@ -307,7 +326,7 @@ #' ```{r} #' spec_slice %>% #' col_vals_within_spec( -#' columns = vars(email_addresses), +#' columns = email_addresses, #' spec = "email" #' ) %>% #' dplyr::select(email_addresses) @@ -321,7 +340,7 @@ #' ```r #' expect_col_vals_within_spec( #' spec_slice, -#' columns = vars(email_addresses), +#' columns = email_addresses, #' spec = "email" #' ) #' ``` @@ -334,7 +353,7 @@ #' ```{r} #' spec_slice %>% #' test_col_vals_within_spec( -#' columns = vars(email_addresses), +#' columns = email_addresses, #' spec = "email" #' ) #' ``` @@ -363,13 +382,10 @@ col_vals_within_spec <- function( active = TRUE ) { - # Get `columns` as a label - columns_expr <- - rlang::as_label(rlang::quo(!!enquo(columns))) %>% - gsub("^\"|\"$", "", .) - # Capture the `columns` expression columns <- rlang::enquo(columns) + # Get `columns` as a label + columns_expr <- as_columns_expr(columns) # Resolve the columns based on the expression columns <- resolve_columns(x = x, var_expr = columns, preconditions) @@ -390,7 +406,7 @@ col_vals_within_spec <- function( secret_agent <- create_agent(x, label = "::QUIET::") %>% col_vals_within_spec( - columns = columns, + columns = tidyselect::all_of(columns), spec = spec, na_pass = na_pass, preconditions = preconditions, @@ -431,6 +447,7 @@ col_vals_within_spec <- function( # Add one or more validation steps based on the # length of the `columns` variable + label <- resolve_label(label, columns, segments_list) for (i in seq_along(columns)) { for (j in seq_along(segments_list)) { @@ -452,7 +469,7 @@ col_vals_within_spec <- function( seg_val = seg_val, actions = covert_actions(actions, agent), step_id = step_id[i], - label = label, + label = label[[i, j]], brief = brief[i], active = active ) diff --git a/R/column_roles.R b/R/column_roles.R index 6d119d72a..a6b234d25 100644 --- a/R/column_roles.R +++ b/R/column_roles.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -805,7 +805,7 @@ get_column_role_character <- function(data_column) { } - return("string") + "string" } get_column_role_numeric <- function(data_column) { @@ -864,7 +864,7 @@ get_column_role_numeric <- function(data_column) { return(paste0(role, "numeric.continuous")) } - return(paste0(role, "numeric")) + paste0(role, "numeric") } strptime_8601_formats <- diff --git a/R/conjointly.R b/R/conjointly.R index d428bc3cd..4e4078431 100644 --- a/R/conjointly.R +++ b/R/conjointly.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -54,7 +54,7 @@ #' A collection one-sided formulas that consist of validation functions that #' validate row units (the `col_vals_*()` series), column existence #' ([col_exists()]), or column type (the `col_is_*()` series). An example of -#' this is `~ col_vals_gte(., vars(a), 5.5), ~ col_vals_not_null(., vars(b)`). +#' this is `~ col_vals_gte(., a, 5.5), ~ col_vals_not_null(., b`). #' #' @param .list *Alternative to `...`* #' @@ -89,12 +89,17 @@ #' #' @section Column Names: #' -#' If providing multiple column names in any of the supplied validation steps, -#' the result will be an expansion of sub-validation steps to that number of -#' column names. Aside from column names in quotes and in `vars()`, -#' **tidyselect** helper functions are available for specifying columns. They -#' are: `starts_with()`, `ends_with()`, `contains()`, `matches()`, and -#' `everything()`. +#' `columns` may be a single column (as symbol `a` or string `"a"`) or a vector +#' of columns (`c(a, b, c)` or `c("a", "b", "c")`). `{tidyselect}` helpers +#' are also supported, such as `contains("date")` and `where(is.double)`. If +#' passing an *external vector* of columns, it should be wrapped in `all_of()`. +#' +#' When multiple columns are selected by `columns`, the result will be an +#' expansion of validation steps to that number of columns (e.g., +#' `c(col_a, col_b)` will result in the entry of two validation steps). +#' +#' Previously, columns could be specified in `vars()`. This continues to work, +#' but `c()` offers the same capability and supersedes `vars()` in `columns`. #' #' @section Preconditions: #' @@ -162,6 +167,19 @@ #' quarter of the total test units fails, the other `stop()`s at the same #' threshold level). #' +#' @section Labels: +#' +#' `label` may be a single string or a character vector that matches the number +#' of expanded steps. `label` also supports `{glue}` syntax and exposes the +#' following dynamic variables contextualized to the current step: +#' +#' - `"{.step}"`: The validation step name +#' - `"{.seg_col}"`: The current segment's column name +#' - `"{.seg_val}"`: The current segment's value/group +#' +#' The glue context also supports ordinary expressions for further flexibility +#' (e.g., `"{toupper(.step)}"`) as long as they return a length-1 string. +#' #' @section Briefs: #' #' Want to describe this validation step in some detail? Keep in mind that this @@ -186,9 +204,9 @@ #' ```r #' agent %>% #' conjointly( -#' ~ col_vals_lt(., columns = vars(a), value = 8), -#' ~ col_vals_gt(., columns = vars(c), value = vars(a)), -#' ~ col_vals_not_null(., columns = vars(b)), +#' ~ col_vals_lt(., columns = a, value = 8), +#' ~ col_vals_gt(., columns = c, value = vars(a)), +#' ~ col_vals_not_null(., columns = b), #' preconditions = ~ . %>% dplyr::filter(a < 10), #' segments = b ~ c("group_1", "group_2"), #' actions = action_levels(warn_at = 0.1, stop_at = 0.2), @@ -203,9 +221,9 @@ #' steps: #' - conjointly: #' fns: -#' - ~col_vals_lt(., columns = vars(a), value = 8) -#' - ~col_vals_gt(., columns = vars(c), value = vars(a)) -#' - ~col_vals_not_null(., columns = vars(b)) +#' - ~col_vals_lt(., columns = a, value = 8) +#' - ~col_vals_gt(., columns = c, value = vars(a)) +#' - ~col_vals_not_null(., columns = b) #' preconditions: ~. %>% dplyr::filter(a < 10) #' segments: b ~ c("group_1", "group_2") #' actions: @@ -252,9 +270,9 @@ #' agent <- #' create_agent(tbl = tbl) %>% #' conjointly( -#' ~ col_vals_lt(., columns = vars(a), value = 8), -#' ~ col_vals_gt(., columns = vars(c), value = vars(a)), -#' ~ col_vals_not_null(., columns = vars(b)) +#' ~ col_vals_lt(., columns = a, value = 8), +#' ~ col_vals_gt(., columns = c, value = vars(a)), +#' ~ col_vals_not_null(., columns = b) #' ) %>% #' interrogate() #' ``` @@ -283,9 +301,9 @@ #' ```{r} #' tbl %>% #' conjointly( -#' ~ col_vals_lt(., columns = vars(a), value = 8), -#' ~ col_vals_gt(., columns = vars(c), value = vars(a)), -#' ~ col_vals_not_null(., columns = vars(b)) +#' ~ col_vals_lt(., columns = a, value = 8), +#' ~ col_vals_gt(., columns = c, value = vars(a)), +#' ~ col_vals_not_null(., columns = b) #' ) #' ``` #' @@ -297,9 +315,9 @@ #' ```r #' expect_conjointly( #' tbl, -#' ~ col_vals_lt(., columns = vars(a), value = 8), -#' ~ col_vals_gt(., columns = vars(c), value = vars(a)), -#' ~ col_vals_not_null(., columns = vars(b)) +#' ~ col_vals_lt(., columns = a, value = 8), +#' ~ col_vals_gt(., columns = c, value = vars(a)), +#' ~ col_vals_not_null(., columns = b) #' ) #' ``` #' @@ -311,9 +329,9 @@ #' ```{r} #' tbl %>% #' test_conjointly( -#' ~ col_vals_lt(., columns = vars(a), value = 8), -#' ~ col_vals_gt(., columns = vars(c), value = vars(a)), -#' ~ col_vals_not_null(., columns = vars(b)) +#' ~ col_vals_lt(., columns = a, value = 8), +#' ~ col_vals_gt(., columns = c, value = vars(a)), +#' ~ col_vals_not_null(., columns = b) #' ) #' ``` #' @@ -406,6 +424,7 @@ conjointly <- function( # Add one or more validation steps based on the # length of `segments_list` + label <- resolve_label(label, segments = segments_list) for (i in seq_along(segments_list)) { seg_col <- names(segments_list[i]) @@ -426,7 +445,7 @@ conjointly <- function( seg_val = seg_val, actions = covert_actions(actions, agent), step_id = step_id, - label = label, + label = label[[i]], brief = brief, active = active ) diff --git a/R/create_agent.R b/R/create_agent.R index 2caed19f3..f2ac0e0b2 100644 --- a/R/create_agent.R +++ b/R/create_agent.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -44,15 +44,15 @@ #' #' @param tbl *Table or expression for reading in one* #' -#' `obj:|
` // **required** +#' `obj:|` // **required** #' #' The input table. This can be a data frame, a tibble, a `tbl_dbi` object, or #' a `tbl_spark` object. Alternatively, an expression can be supplied to serve #' as instructions on how to retrieve the target table at interrogation-time. #' There are two ways to specify an association to a target table: (1) as a #' table-prep formula, which is a right-hand side (RHS) formula expression -#' (e.g., `~ {
}`), or (2) as a function (e.g., -#' `function() {
}`). +#' (e.g., `~ { }`), or (2) as a function (e.g., +#' `function() { }`). #' #' @param tbl_name *A table name* #' @@ -394,16 +394,16 @@ #' ```r #' agent <- #' agent %>% -#' col_exists(columns = vars(date, date_time)) %>% +#' col_exists(columns = date, date_time) %>% #' col_vals_regex( -#' columns = vars(b), +#' columns = b, #' regex = "[0-9]-[a-z]{3}-[0-9]{3}" #' ) %>% #' rows_distinct() %>% -#' col_vals_gt(columns = vars(d), value = 100) %>% -#' col_vals_lte(columns = vars(c), value = 5) %>% +#' col_vals_gt(columns = d, value = 100) %>% +#' col_vals_lte(columns = c, value = 5) %>% #' col_vals_between( -#' columns = vars(c), +#' columns = c, #' left = vars(a), right = vars(d), #' na_pass = TRUE #' ) %>% diff --git a/R/create_informant.R b/R/create_informant.R index b7f7b990d..8482ee288 100644 --- a/R/create_informant.R +++ b/R/create_informant.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -55,15 +55,15 @@ #' #' @param tbl *Table or expression for reading in one* #' -#' `obj:|
` // **required** +#' `obj:|` // **required** #' #' The input table. This can be a data frame, a tibble, a `tbl_dbi` object, or #' a `tbl_spark` object. Alternatively, an expression can be supplied to serve #' as instructions on how to retrieve the target table at incorporation-time. #' There are two ways to specify an association to a target table: (1) as a #' table-prep formula, which is a right-hand side (RHS) formula expression -#' (e.g., `~ {
}`), or (2) as a function (e.g., -#' `function() {
}`). +#' (e.g., `~ { }`), or (2) as a function (e.g., +#' `function() { }`). #' #' @param agent *The pointblank agent object* #' @@ -399,6 +399,10 @@ create_informant <- function( } } + private <- list( + col_ptypes = tbl_info$col_ptypes + ) + metadata_list <- c( list( @@ -409,7 +413,8 @@ create_informant <- function( `_type` = table_type ) ), - column_list + column_list, + list(`_private` = private) ) # Create the metadata list object diff --git a/R/create_multiagent.R b/R/create_multiagent.R index a2c225118..dfe1101b5 100644 --- a/R/create_multiagent.R +++ b/R/create_multiagent.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -107,7 +107,7 @@ #' tbl_name = "tbl_1", #' label = "Example table 1." #' ) %>% -#' col_vals_gt(columns = vars(a), value = 4) %>% +#' col_vals_gt(columns = a, value = 4) %>% #' interrogate() #' ``` #' @@ -120,7 +120,7 @@ #' tbl_name = "tbl_2", #' label = "Example table 2." #' ) %>% -#' col_is_character(columns = vars(b)) %>% +#' col_is_character(columns = b) %>% #' interrogate() #' ``` #' @@ -159,19 +159,17 @@ create_multiagent <- function( locale = NULL ) { - agent_list <- list(...) - + agent_list <- rlang::list2(...) + if (!all(sapply(agent_list, is_ptblank_agent))) { + rlang::abort("All components of `...` must be an agent") + } + agent_list <- rehash_agent_list(agent_list) agent_list <- lapply( agent_list, FUN = function(agent) { - - # TODO: Ensure that each `agent` in `agent_list` is - # actually an agent with `is_ptblank_agent()` - class(agent) <- c(setdiff(class(agent), "ptblank_agent"), "ptblank_agent_i") - agent } ) @@ -185,3 +183,50 @@ create_multiagent <- function( class(agent_series) <- "ptblank_multiagent" agent_series } + +rehash_agent_list <- function(agent_list) { + + hash_versions <- lapply(agent_list, function(x) { + gsub("^.*(-|$)", "", x$validation_set$sha1) + }) + hash_versions <- unique(unlist(hash_versions)) + + # agents using any of these hash versions are rehashed + to_rehash <- c("") + + if (any(to_rehash %in% hash_versions) || length(hash_versions) > 1) { + lapply(agent_list, rehash_agent) + } else { + agent_list + } + +} + +rehash_agent <- function(agent) { + + cur_hash_version <- get_hash_version() + vs <- agent$validation_set + + new_hash <- sapply(seq_len(nrow(vs)), function(i) { + step <- vs[i, ] + hash <- step$sha1 + hash_version <- gsub("^.*(-|$)", "", hash) + if (hash_version != cur_hash_version) { + # Rehash from validation set, extracting from list-column where necessary + hash <- hash_validation_step( + assertion_type = step$assertion_type, + column = step$column[[1]], + values = step$values[[1]], + na_pass = step$na_pass, + preconditions = step$preconditions[[1]], + seg_col = step$seg_col, + seg_val = step$seg_val + ) + } + hash + }) + + agent$validation_set$sha1 <- new_hash + agent + +} diff --git a/R/datasets.R b/R/datasets.R index 2770d07f6..665cbb1ff 100644 --- a/R/datasets.R +++ b/R/datasets.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -73,18 +73,10 @@ small_table_sqlite <- function() { # nocov start - - if (!requireNamespace("DBI", quietly = TRUE) && - !requireNamespace("RSQLite", quietly = TRUE)) { - - stop( - "Creating the SQLite table object requires both the DBI and RSQLite ", - "packages:\n", - "* Install them with `install.packages(\"DBI\")` and ", - "`install.packages(\"RSQLite\")`.", - call. = FALSE - ) - } + rlang::check_installed( + c("DBI", "RSQLite"), + "to create an SQLite table object." + ) con <- DBI::dbConnect( diff --git a/R/draft_validation.R b/R/draft_validation.R index 7a50189c1..1c65e6f51 100644 --- a/R/draft_validation.R +++ b/R/draft_validation.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -154,116 +154,116 @@ #' ) %>% #' # Expect that column `name` is of type: character #' col_is_character( -#' columns = vars(name) +#' columns = name #' ) %>% #' # Expect that column `year` is of type: numeric #' col_is_numeric( -#' columns = vars(year) +#' columns = year #' ) %>% #' # Expect that values in `year` should be between `1975` and `2020` #' col_vals_between( -#' columns = vars(year), +#' columns = year, #' left = 1975, #' right = 2020 #' ) %>% #' # Expect that column `month` is of type: numeric #' col_is_numeric( -#' columns = vars(month) +#' columns = month #' ) %>% #' # Expect that values in `month` should be between `1` and `12` #' col_vals_between( -#' columns = vars(month), +#' columns = month, #' left = 1, #' right = 12 #' ) %>% #' # Expect that column `day` is of type: integer #' col_is_integer( -#' columns = vars(day) +#' columns = day #' ) %>% #' # Expect that values in `day` should be between `1` and `31` #' col_vals_between( -#' columns = vars(day), +#' columns = day, #' left = 1, #' right = 31 #' ) %>% #' # Expect that column `hour` is of type: numeric #' col_is_numeric( -#' columns = vars(hour) +#' columns = hour #' ) %>% #' # Expect that values in `hour` should be between `0` and `23` #' col_vals_between( -#' columns = vars(hour), +#' columns = hour, #' left = 0, #' right = 23 #' ) %>% #' # Expect that column `lat` is of type: numeric #' col_is_numeric( -#' columns = vars(lat) +#' columns = lat #' ) %>% #' # Expect that values in `lat` should be between `-90` and `90` #' col_vals_between( -#' columns = vars(lat), +#' columns = lat, #' left = -90, #' right = 90 #' ) %>% #' # Expect that column `long` is of type: numeric #' col_is_numeric( -#' columns = vars(long) +#' columns = long #' ) %>% #' # Expect that values in `long` should be between `-180` and `180` #' col_vals_between( -#' columns = vars(long), +#' columns = long, #' left = -180, #' right = 180 #' ) %>% #' # Expect that column `status` is of type: character #' col_is_character( -#' columns = vars(status) +#' columns = status #' ) %>% #' # Expect that column `category` is of type: factor #' col_is_factor( -#' columns = vars(category) +#' columns = category #' ) %>% #' # Expect that column `wind` is of type: integer #' col_is_integer( -#' columns = vars(wind) +#' columns = wind #' ) %>% #' # Expect that values in `wind` should be between `10` and `160` #' col_vals_between( -#' columns = vars(wind), +#' columns = wind, #' left = 10, #' right = 160 #' ) %>% #' # Expect that column `pressure` is of type: integer #' col_is_integer( -#' columns = vars(pressure) +#' columns = pressure #' ) %>% #' # Expect that values in `pressure` should be between `882` and `1022` #' col_vals_between( -#' columns = vars(pressure), +#' columns = pressure, #' left = 882, #' right = 1022 #' ) %>% #' # Expect that column `tropicalstorm_force_diameter` is of type: integer #' col_is_integer( -#' columns = vars(tropicalstorm_force_diameter) +#' columns = tropicalstorm_force_diameter #' ) %>% #' # Expect that values in `tropicalstorm_force_diameter` should be between #' # `0` and `870` #' col_vals_between( -#' columns = vars(tropicalstorm_force_diameter), +#' columns = tropicalstorm_force_diameter, #' left = 0, #' right = 870, #' na_pass = TRUE #' ) %>% #' # Expect that column `hurricane_force_diameter` is of type: integer #' col_is_integer( -#' columns = vars(hurricane_force_diameter) +#' columns = hurricane_force_diameter #' ) %>% #' # Expect that values in `hurricane_force_diameter` should be between #' # `0` and `300` #' col_vals_between( -#' columns = vars(hurricane_force_diameter), +#' columns = hurricane_force_diameter, #' left = 0, #' right = 300, #' na_pass = TRUE diff --git a/R/emailing.R b/R/emailing.R index 0f9399a0e..182e4f910 100644 --- a/R/emailing.R +++ b/R/emailing.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -93,8 +93,8 @@ #' ) #' ) #' ) %>% -#' col_vals_gt(vars(a), 1) %>% -#' col_vals_lt(vars(a), 7) +#' col_vals_gt(a, 1) %>% +#' col_vals_lt(a, 7) #' ``` #' #' YAML representation: @@ -116,10 +116,10 @@ #' embed_report: true #' steps: #' - col_vals_gt: -#' columns: vars(a) +#' columns: c(a) #' value: 1.0 #' - col_vals_lt: -#' columns: vars(a) +#' columns: c(a) #' value: 7.0 #' ``` #' @@ -176,8 +176,8 @@ #' ) #' ) #' ) %>% -#' col_vals_gt(vars(a), value = 1) %>% -#' col_vals_lt(vars(a), value = 7) %>% +#' col_vals_gt(a, value = 1) %>% +#' col_vals_lt(a, value = 7) %>% #' interrogate() #' ``` #' @@ -294,8 +294,8 @@ email_blast <- function( #' label = "An example.", #' actions = al #' ) %>% -#' col_vals_gt(vars(a), value = 1) %>% -#' col_vals_lt(vars(a), value = 7) %>% +#' col_vals_gt(a, value = 1) %>% +#' col_vals_lt(a, value = 7) %>% #' interrogate() %>% #' email_create() #' diff --git a/R/file_naming.R b/R/file_naming.R index 4f5f07994..f27d57a1a 100644 --- a/R/file_naming.R +++ b/R/file_naming.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html diff --git a/R/get_agent_report.R b/R/get_agent_report.R index a4b247bfe..6af117258 100644 --- a/R/get_agent_report.R +++ b/R/get_agent_report.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -210,7 +210,7 @@ #' tbl_name = "small_table", #' label = "An example." #' ) %>% -#' col_vals_gt(columns = vars(a), value = 4) %>% +#' col_vals_gt(columns = a, value = 4) %>% #' interrogate() #' ``` #' @@ -333,11 +333,11 @@ get_agent_report <- function( FUN.VALUE = character(1), USE.NAMES = FALSE, FUN = function(x) { - ifelse( - is.null(x), - NA_character_, - unlist(x) - ) + if (is.null(x)) { + NA_character_ + } else { + toString(unique(x)) + } } ) @@ -448,7 +448,8 @@ get_agent_report <- function( # nocov start - validation_set <- validation_set[report_tbl$i, ] + validation_set <- validation_set %>% + dplyr::filter(.data$i %in% report_tbl$i) eval <- eval[report_tbl$i] extracts <- agent$extracts[ @@ -510,7 +511,8 @@ get_agent_report <- function( htmltools::HTML(agent_label_styled), htmltools::tags$div( style = htmltools::css( - height = "25px" + height = "25px", + `padding-top` = "10px" ), htmltools::HTML(paste0(table_type, action_levels)) ) @@ -751,16 +753,42 @@ get_agent_report <- function( } } - if ( - is.null(column_i) | - (is.list(column_i) && is.na(unlist(column_i))) - ) { - - NA_character_ - - } else if (is.na(column_i)) { - - NA_character_ + # If column missing + if (is.null(column_i) || identical(unlist(column_i), NA_character_)) { + + columns_expr <- validation_set$columns_expr[[x]] + not_interrogated <- is.na(validation_set$eval_error[[x]]) + eval_error <- isTRUE(validation_set$eval_error[[x]]) + + # If column selection attempted AND: + # - in validation planning, OR + # - the evaluation errors, OR + # - is a col_exists() step + columns_expr_exists <- !is.na(columns_expr) && columns_expr != "NULL" + show_column_expr <- columns_expr_exists && + (not_interrogated || eval_error || assertion_str == "col_exists") + # Then display the original column selection expression for debugging + if (show_column_expr) { + as.character( + htmltools::tags$p( + title = columns_expr, + style = htmltools::css( + `margin-top` = "0", + `margin-bottom` = "0", + `font-family` = "monospace", + `font-size` = "10px", + `white-space` = "nowrap", + `text-overflow` = "ellipsis", + overflow = "hidden", + color = if (eval_error) "firebrick", + `font-face` = "maroon" + ), + columns_expr + ) + ) + } else { + NA_character_ + } } else { @@ -1160,15 +1188,18 @@ get_agent_report <- function( NA_character_ } else { - + text <- - values_i %>% - tidy_gsub( - "~", - "" - ) %>% - unname() - + unname( + tidy_gsub( + values_i, + "~", + "" + ) + ) + + text <- gsub("$", "$", values_i, fixed = TRUE) + text <- paste(text, collapse = ", ") if (size == "small") { @@ -1302,6 +1333,16 @@ get_agent_report <- function( FUN.VALUE = character(1), USE.NAMES = FALSE, FUN = function(x) { + + # Reformat error/warning to string + msg_error <- pointblank_cnd_to_string( + cnd = agent$validation_set$capture_stack[[x]]$error, + pb_call = agent$validation_set$capture_stack[[x]]$pb_call + ) + msg_warning <- pointblank_cnd_to_string( + cnd = agent$validation_set$capture_stack[[x]]$warning, + pb_call = agent$validation_set$capture_stack[[x]]$pb_call + ) if (is.na(eval[x])) { @@ -1325,7 +1366,7 @@ get_agent_report <- function( text <- htmltools::htmlEscape( - agent$validation_set$capture_stack[[x]]$error %>% + msg_error %>% tidy_gsub("\"", "'") ) @@ -1351,7 +1392,7 @@ get_agent_report <- function( text <- htmltools::htmlEscape( - agent$validation_set$capture_stack[[x]]$warning %>% + msg_warning %>% tidy_gsub("\"", "'") ) @@ -1377,7 +1418,7 @@ get_agent_report <- function( text <- htmltools::htmlEscape( - agent$validation_set$capture_stack[[x]]$error %>% + msg_error %>% tidy_gsub("\"", "'") ) @@ -1870,9 +1911,7 @@ get_agent_report <- function( agent_report <- agent_report %>% gt::tab_header( - title = get_lsv(text = c( - "agent_report", "pointblank_validation_title_text" - ))[[lang]], + title = title_text, subtitle = gt::md( paste0(agent_label_styled, " ", table_type, "

") ) @@ -1926,6 +1965,7 @@ get_agent_report <- function( } #pb_agent code { font-family: 'IBM Plex Mono', monospace, courier; + color: black; background-color: transparent; padding: 0; } @@ -1940,11 +1980,15 @@ get_agent_report <- function( # nocov end + # Quarto rendering workaround + if (check_quarto()) { + agent_report <- gt::fmt(agent_report, fns = identity) + } + agent_report } -get_default_title_text <- function(report_type, - lang) { +get_default_title_text <- function(report_type, lang) { if (report_type == "informant") { title_text <- @@ -2421,3 +2465,17 @@ store_footnote <- function( ) ) } + +# Function for formatting error in `$capture_stack` +pointblank_cnd_to_string <- function(cnd, pb_call) { + if (is.null(cnd)) return(character(0)) + # Reformatting not yet implemented for warnings + if (rlang::is_warning(cnd)) return(cnd) + # Reconstruct trimmed down error and rethrow without cli + new <- rlang::error_cnd( + call = rlang::call2(":::", quote(pointblank), pb_call[1]), + message = cnd$parent$message %||% cnd$message, + use_cli_format = FALSE + ) + as.character(try(rlang::cnd_signal(new), silent = TRUE)) +} diff --git a/R/get_agent_x_list.R b/R/get_agent_x_list.R index 5f4fe1a44..23edac9d2 100644 --- a/R/get_agent_x_list.R +++ b/R/get_agent_x_list.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -145,8 +145,8 @@ #' tbl = tbl, #' actions = al #' ) %>% -#' col_vals_gt(columns = vars(a), value = 7) %>% -#' col_is_numeric(columns = vars(a)) %>% +#' col_vals_gt(columns = a, value = 7) %>% +#' col_is_numeric(columns = a) %>% #' interrogate() #' ``` #' diff --git a/R/get_data_extracts.R b/R/get_data_extracts.R index d1ce1bc39..745e6b4bc 100644 --- a/R/get_data_extracts.R +++ b/R/get_data_extracts.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -77,9 +77,9 @@ #' dplyr::select(a:f), #' label = "`get_data_extracts()`" #' ) %>% -#' col_vals_gt(vars(d), value = 1000) %>% +#' col_vals_gt(d, value = 1000) %>% #' col_vals_between( -#' columns = vars(c), +#' columns = c, #' left = vars(a), right = vars(d), #' na_pass = TRUE #' ) %>% diff --git a/R/get_informant_report.R b/R/get_informant_report.R index 0fbd42675..675d5d238 100644 --- a/R/get_informant_report.R +++ b/R/get_informant_report.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -139,6 +139,8 @@ get_informant_report <- function( y <- informant$metadata_rev } else { y <- informant$metadata + # Hide private metadata from report + y[["_private"]] <- NULL } if ("info_label" %in% names(informant)) { @@ -676,6 +678,11 @@ get_informant_report <- function( # nocov end + # Quarto rendering workaround + if (check_quarto()) { + gt_informant_report <- gt::fmt(gt_informant_report, fns = identity) + } + gt_informant_report } diff --git a/R/get_multiagent_report.R b/R/get_multiagent_report.R index eee09f8f9..8ed4d28c9 100644 --- a/R/get_multiagent_report.R +++ b/R/get_multiagent_report.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -146,32 +146,32 @@ #' actions = al #' ) %>% #' col_vals_gt( -#' columns = vars(date_time), +#' columns = date_time, #' value = vars(date), #' na_pass = TRUE #' ) %>% #' col_vals_gt( -#' columns = vars(b), +#' columns = b, #' value = vars(g), #' na_pass = TRUE #' ) %>% #' rows_distinct() %>% #' col_vals_equal( -#' columns = vars(d), +#' columns = d, #' value = vars(d), #' na_pass = TRUE #' ) %>% #' col_vals_between( -#' columns = vars(c), +#' columns = c, #' left = vars(a), right = vars(d) #' ) %>% #' col_vals_not_between( -#' columns = vars(c), +#' columns = c, #' left = 10, right = 20, #' na_pass = TRUE #' ) %>% -#' rows_distinct(columns = vars(d, e, f)) %>% -#' col_is_integer(columns = vars(a)) %>% +#' rows_distinct(columns = d, e, f) %>% +#' col_is_integer(columns = a) %>% #' interrogate() #' ``` #' @@ -181,9 +181,9 @@ #' ```r #' agent_2 <- #' agent_1 %>% -#' col_exists(columns = vars(date, date_time)) %>% +#' col_exists(columns = date, date_time) %>% #' col_vals_regex( -#' columns = vars(b), +#' columns = b, #' regex = "[0-9]-[a-z]{3}-[0-9]{3}", #' active = FALSE #' ) %>% @@ -197,7 +197,7 @@ #' agent_3 <- #' agent_2 %>% #' col_vals_in_set( -#' columns = vars(f), +#' columns = f, #' set = c("low", "mid", "high") #' ) %>% #' remove_steps(i = 5) %>% @@ -889,6 +889,7 @@ get_multiagent_report <- function( #report code { font-family: 'IBM Plex Mono', monospace, courier; font-size: 11px; + color: black; background-color: transparent; padding: 0; } @@ -914,6 +915,11 @@ get_multiagent_report <- function( class(report_tbl) <- c("ptblank_multiagent_report.wide", class(report_tbl)) + # Quarto rendering workaround + if (check_quarto()) { + report_tbl <- gt::fmt(report_tbl, fns = identity) + } + report_tbl } @@ -1504,6 +1510,6 @@ generate_cell_content <- function( return(cell_content) } - + NULL # nocov end } diff --git a/R/get_sundered_data.R b/R/get_sundered_data.R index 8c5063abf..808b742b7 100644 --- a/R/get_sundered_data.R +++ b/R/get_sundered_data.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -94,9 +94,9 @@ #' dplyr::select(a:f), #' label = "`get_sundered_data()`" #' ) %>% -#' col_vals_gt(columns = vars(d), value = 1000) %>% +#' col_vals_gt(columns = d, value = 1000) %>% #' col_vals_between( -#' columns = vars(c), +#' columns = c, #' left = vars(a), right = vars(d), #' na_pass = TRUE #' ) %>% @@ -268,6 +268,14 @@ get_sundered_data <- function( ) } + # Stop function if `tbl_checked` is not present + if (!"tbl_checked" %in% colnames(agent$validation_set)) { + stop( + "`agent` is missing `tbl_checked` information required for sundering. ", + "See `?interrogate`." + ) + } + # Get the row count of the input table row_count_input_tbl <- input_tbl %>% diff --git a/R/has_columns.R b/R/has_columns.R index e4dafa1ee..0252c79da 100644 --- a/R/has_columns.R +++ b/R/has_columns.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -27,10 +27,10 @@ #' specified name is present in a table object. This function works well enough #' on a table object but it can also be used as part of a formula in any #' validation function's `active` argument. Using `active = ~ . %>% -#' has_columns("column_1")` means that the validation step will be inactive if +#' has_columns(column_1)` means that the validation step will be inactive if #' the target table doesn't contain a column named `column_1`. We can also use -#' multiple columns in `vars()` so having `active = ~ . %>% -#' has_columns(vars(column_1, column_2))` in a validation step will make it +#' multiple columns in `c()`, so having `active = ~ . %>% +#' has_columns(c(column_1, column_2))` in a validation step will make it #' inactive at [interrogate()] time unless the columns `column_1` and `column_2` #' are both present. #' @@ -43,10 +43,10 @@ #' #' @param columns *The target columns* #' -#' `vector|vars()`` // **required** +#' `` // *required* #' -#' One or more column names that are to be checked for existence in the table -#' `x`. +#' One or more columns or column-selecting expressions. Each element is +#' checked for a match in the table `x`. #' #' @return A length-1 logical vector. #' @@ -60,11 +60,10 @@ #' ``` #' #' With `has_columns()` we can check for column existence by using it directly -#' on the table. A column name can be verified as present by using it in double -#' quotes. +#' on the table. #' #' ```r -#' small_table %>% has_columns(columns = "date") +#' small_table %>% has_columns(columns = date) #' ``` #' #' ``` @@ -75,17 +74,17 @@ #' columns are present in `small_table`. #' #' ```r -#' small_table %>% has_columns(columns = c("a", "b")) +#' small_table %>% has_columns(columns = c(a, b)) #' ``` #' #' ``` #' ## [1] TRUE #' ``` #' -#' It's possible to supply column names in `vars()` as well: +#' It's possible to use a tidyselect helper as well: #' #' ```r -#' small_table %>% has_columns(columns = vars(a, b)) +#' small_table %>% has_columns(columns = c(a, starts_with("b"))) #' ``` #' #' ``` @@ -96,13 +95,27 @@ #' need to be present to obtain `TRUE`). #' #' ```r -#' small_table %>% has_columns(columns = vars(a, h)) +#' small_table %>% has_columns(columns = c(a, h)) #' ``` #' #' ``` #' ## [1] FALSE #' ``` #' +#' The same holds in the case of tidyselect helpers. Because no columns start +#' with `"h"`, including `starts_with("h")` returns `FALSE` for the entire +#' check. +#' +#' ```r +#' small_table %>% has_columns(columns = starts_with("h")) +#' small_table %>% has_columns(columns = c(a, starts_with("h"))) +#' ``` +#' +#' ``` +#' ## [1] FALSE +#' ## [1] FALSE +#' ``` +#' #' The `has_columns()` function can be useful in expressions that involve the #' target table, especially if it is uncertain that the table will contain a #' column that's involved in a validation. @@ -119,17 +132,17 @@ #' tbl_name = "small_table" #' ) %>% #' col_vals_gt( -#' columns = vars(c), value = vars(a), -#' active = ~ . %>% has_columns(vars(a, c)) +#' columns = c, value = vars(a), +#' active = ~ . %>% has_columns(c(a, c)) #' ) %>% #' col_vals_lt( -#' columns = vars(h), value = vars(d), +#' columns = h, value = vars(d), #' preconditions = ~ . %>% dplyr::mutate(h = d - a), -#' active = ~ . %>% has_columns(vars(a, d)) +#' active = ~ . %>% has_columns(c(a, d)) #' ) %>% #' col_is_character( -#' columns = vars(j), -#' active = ~ . %>% has_columns("j") +#' columns = j, +#' active = ~ . %>% has_columns(j) #' ) %>% #' interrogate() #' ``` @@ -170,17 +183,47 @@ has_columns <- function( ) } - # Normalize the `columns` expression - if (inherits(columns, "quosures")) { + # Capture the `columns` expression + columns <- rlang::enquo(columns) + if (rlang::quo_is_missing(columns)) { + rlang::abort("Must supply a value for `columns`") + } + + # Split into quos if multi-length c()/vars() expr + if (rlang::quo_is_call(columns, c("c", "vars"))) { + columns_env <- rlang::quo_get_env(columns) + column_quos <- lapply(rlang::call_args(columns), function(x) { + rlang::new_quosure(x, env = columns_env) + }) + } else { + column_quos <- list(columns) + } + + .call <- rlang::current_env() + has_column <- function(col_expr) { + columns <- tryCatch( + expr = resolve_columns(x = x, var_expr = col_expr, + allow_empty = FALSE, call = .call), + error = function(cnd) cnd + ) + ## If error from {tidyselect}, counts as no selection + if (rlang::is_error(columns)) { + cnd <- columns + # Rethrow error if genuine evaluation error + if (inherits(cnd, "resolve_eval_err")) { + rlang::cnd_signal(cnd) + } + # Return length-0 vector if "column not found" or "0 columns" error + return(character(0L)) + } - columns <- - vapply( - columns, - FUN.VALUE = character(1), - USE.NAMES = FALSE, - FUN = function(x) as.character(rlang::get_expr(x)) - ) + ## If columns succesfully resolved to character, return only existing ones + intersect(columns, colnames(x)) } - all(columns %in% rlang::names2(x)) + # A list of columns (character vector) selected by elements of `columns` + # - Ex: `c(a, b:c)` becomes `list("a", c("b", "c"))` if data has those columns + columns_list <- lapply(column_quos, has_column) + all(lengths(columns_list) > 0L) + } diff --git a/R/incorporate.R b/R/incorporate.R index a14ec4325..c7346f49e 100644 --- a/R/incorporate.R +++ b/R/incorporate.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -75,7 +75,7 @@ #' fn = ~ . %>% ncol() #' ) %>% #' info_columns( -#' columns = vars(a), +#' columns = a, #' info = "In the range of 1 to 10. ((SIMPLE))" #' ) %>% #' info_columns( @@ -83,7 +83,7 @@ #' info = "Time-based values (e.g., `Sys.time()`)." #' ) %>% #' info_columns( -#' columns = "date", +#' columns = date, #' info = "The date part of `date_time`. ((CALC))" #' ) %>% #' info_section( @@ -207,7 +207,7 @@ incorporate <- function(informant) { # TODO: Improve the `stop()` message here stop( "The `read_fn` object must be a function or an R formula.\n", - "* A function can be made with `function()` {
}.\n", + "* A function can be made with `function()` {}.\n", "* An R formula can also be used, with the expression on the RHS.", call. = FALSE ) @@ -371,7 +371,7 @@ incorporate <- function(informant) { extra_sections <- base::setdiff( names(informant$metadata), - c("info_label", "table", "columns") + c("info_label", "table", "columns", "_private") ) metadata_extra <- informant$metadata[extra_sections] diff --git a/R/info_add.R b/R/info_add.R index ab574cd52..c0ed7af33 100644 --- a/R/info_add.R +++ b/R/info_add.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -193,7 +193,7 @@ info_tabular <- function( ... ) { - metadata_items <- list(...) + metadata_items <- rlang::list2(...) metadata <- x @@ -246,7 +246,7 @@ info_tabular <- function( #' #' @param columns *The target columns* #' -#' `vector|vars()`` // **required** +#' `vector|vars()` // **required** #' #' The column or set of columns to focus on. Can be defined as a column name #' in quotes (e.g., `""`), one or more column names in `vars()` @@ -331,19 +331,19 @@ info_tabular <- function( #' # R statement #' informant %>% #' info_columns( -#' columns = "date_time", +#' columns = date_time, #' info = "*info text* 1." #' ) %>% #' info_columns( -#' columns = "date", +#' columns = date, #' info = "*info text* 2." #' ) %>% #' info_columns( -#' columns = "item_count", +#' columns = item_count, #' info = "*info text* 3. Statistics: {snippet_1}." #' ) %>% #' info_columns( -#' columns = vars(date, date_time), +#' columns = c(date, date_time), #' info = "UTC time." #' ) #' @@ -401,7 +401,7 @@ info_tabular <- function( #' informant <- #' informant %>% #' info_columns( -#' columns = vars(a), +#' columns = a, #' info = "In the range of 1 to 10. ((SIMPLE))" #' ) %>% #' info_columns( @@ -409,7 +409,7 @@ info_tabular <- function( #' info = "Time-based values (e.g., `Sys.time()`)." #' ) %>% #' info_columns( -#' columns = "date", +#' columns = date, #' info = "The date part of `date_time`. ((CALC))" #' ) #' ``` @@ -442,17 +442,21 @@ info_columns <- function( # Capture the `columns` expression columns <- rlang::enquo(columns) - metadata_items <- list(...) + metadata_items <- rlang::list2(...) metadata <- x metadata_list <- metadata$metadata metadata_columns <- metadata_list$columns - x <- dplyr::as_tibble(metadata_columns %>% lapply(function(x) 1)) + if (is.null(x$tbl)) { + tbl <- metadata_list[["_private"]]$col_ptypes + } else { + tbl <- x$tbl + } # Resolve the columns based on the expression - columns <- resolve_columns(x = x, var_expr = columns, preconditions = NULL) + columns <- resolve_columns(x = tbl, var_expr = columns) if (length(columns) == 1 && is.na(columns)) { @@ -605,11 +609,11 @@ info_columns <- function( #' informant <- #' informant %>% #' info_columns( -#' columns = "item_revenue", +#' columns = item_revenue, #' info = "Revenue reported in USD." #' ) %>% #' info_columns( -#' columns = "acquisition", +#' columns = acquisition, #' `top list` = "{top5_aq}" #' ) %>% #' info_snippet( @@ -719,7 +723,7 @@ check_info_columns_tbl <- function(tbl) { #' #' @param section_name *The section name* #' -#' `scalar`` // **required** +#' `scalar` // **required** #' #' The name of the section for which this information pertains. #' @@ -888,7 +892,7 @@ info_section <- function( ... ) { - metadata_items <- list(...) + metadata_items <- rlang::list2(...) metadata <- x @@ -961,7 +965,7 @@ info_section <- function( #' #' @param snippet_name *The snippet name* #' -#' `scalar`` // **required** +#' `scalar` // **required** #' #' The name for snippet, which is used for interpolating the result of the #' snippet formula into *info text* defined by an `info_*()` function. @@ -1009,7 +1013,7 @@ info_section <- function( #' # R statement #' informant %>% #' info_columns( -#' columns = "date_time", +#' columns = date_time, #' `Latest Date` = "The latest date is {latest_date}." #' ) %>% #' info_snippet( @@ -1064,7 +1068,7 @@ info_section <- function( #' fn = snip_highest(column = "a") #' ) %>% #' info_columns( -#' columns = vars(a), +#' columns = a, #' info = "In the range of 1 to {max_a}. ((SIMPLE))" #' ) %>% #' info_columns( @@ -1072,7 +1076,7 @@ info_section <- function( #' info = "Time-based values (e.g., `Sys.time()`)." #' ) %>% #' info_columns( -#' columns = "date", +#' columns = date, #' info = "The date part of `date_time`. ((CALC))" #' ) %>% #' info_section( @@ -1158,7 +1162,7 @@ info_snippet <- function( #' #' @param column *The target column* #' -#' `scalar`` // **required** +#' `scalar` // **required** #' #' The name of the column that contains the target values. #' @@ -1227,6 +1231,12 @@ info_snippet <- function( #' derived from `character` or `factor` values; numbers, dates, and logical #' values won't have quotation marks. We can explicitly use quotations (or #' not) with either `TRUE` or `FALSE` here. +#' +#' @param na_rm *Remove NA values from list* +#' +#' `scalar` // *default:* `FALSE` +#' +#' An option for whether NA values should be counted as an item in the list. #' #' @param lang *Reporting language* #' @@ -1260,7 +1270,7 @@ info_snippet <- function( #' label = "An example." #' ) %>% #' info_columns( -#' columns = "f", +#' columns = f, #' `Items` = "This column contains {values_f}." #' ) %>% #' info_snippet( @@ -1297,6 +1307,7 @@ snip_list <- function( oxford = TRUE, as_code = TRUE, quot_str = NULL, + na_rm = FALSE, lang = NULL ) { @@ -1361,9 +1372,9 @@ snip_list <- function( stats::as.formula( as.character( glue::glue( - "~ . %>% dplyr::select(<>) %>%", + "~ . %>% dplyr::select(`<>`) %>%", "dplyr::distinct() %>%", - "dplyr::pull(<>) %>%", + "dplyr::pull(`<>`) %>%", ifelse(reverse, "rev() %>%", ""), "pb_str_catalog( limit = <>, @@ -1372,6 +1383,7 @@ snip_list <- function( oxford = <>, as_code = <>, quot_str = <>, + na_rm = <>, lang = <> )", .open = "<<", .close = ">>" @@ -1385,16 +1397,16 @@ snip_list <- function( stats::as.formula( as.character( glue::glue( - "~ . %>% dplyr::select(<>) %>%", - "dplyr::group_by(<>) %>%", + "~ . %>% dplyr::select(`<>`) %>%", + "dplyr::group_by(`<>`) %>%", "dplyr::summarize(`_count_` = dplyr::n(), .groups = 'keep') %>%", ifelse( reverse, "dplyr::arrange(`_count_`) %>%", "dplyr::arrange(dplyr::desc(`_count_`)) %>%" ), - "dplyr::select(<>) %>%", - "dplyr::pull(<>) %>%", + "dplyr::select(`<>`) %>%", + "dplyr::pull(`<>`) %>%", "pb_str_catalog( limit = <>, sep = <>, @@ -1402,6 +1414,7 @@ snip_list <- function( oxford = <>, as_code = <>, quot_str = <>, + na_rm = <>, lang = <> )", .open = "<<", .close = ">>" @@ -1416,9 +1429,9 @@ snip_list <- function( stats::as.formula( as.character( glue::glue( - "~ . %>% dplyr::select(<>) %>%", + "~ . %>% dplyr::select(`<>`) %>%", "dplyr::distinct() %>%", - "dplyr::pull(<>) %>%", + "dplyr::pull(`<>`) %>%", ifelse( reverse, "sort(decreasing = TRUE) %>%", @@ -1431,6 +1444,7 @@ snip_list <- function( oxford = <>, as_code = <>, quot_str = <>, + na_rm = <>, lang = <> )", .open = "<<", .close = ">>" @@ -1461,7 +1475,7 @@ snip_list <- function( #' #' @param column *The target column* #' -#' `scalar`` // **required** +#' `scalar` // **required** #' #' The name of the column that contains the target values. #' @@ -1491,7 +1505,7 @@ snip_list <- function( #' label = "An example." #' ) %>% #' info_columns( -#' columns = "d", +#' columns = d, #' `Stats` = "Stats (fivenum): {stats_d}." #' ) %>% #' info_snippet( @@ -1529,7 +1543,7 @@ snip_stats <- function( as.character( glue::glue( "~ . %>% - dplyr::select(<>) %>% + dplyr::select(`<>`) %>% pb_str_summary(type = '<>')", .open = "<<", .close = ">>" ) @@ -1548,7 +1562,7 @@ snip_stats <- function( #' #' @param column *The target column* #' -#' `scalar`` // **required** +#' `scalar` // **required** #' #' The name of the column that contains the target values. #' @@ -1570,7 +1584,7 @@ snip_stats <- function( #' label = "An example." #' ) %>% #' info_columns( -#' columns = "a", +#' columns = a, #' `Lowest Value` = "Lowest value is {lowest_a}." #' ) %>% #' info_snippet( @@ -1603,8 +1617,8 @@ snip_lowest <- function(column) { as.character( glue::glue( "~ . %>% - dplyr::select(<>) %>% dplyr::distinct() %>% - dplyr::summarize(`pb_summary` = min(<>, na.rm = TRUE)) %>% + dplyr::select(`<>`) %>% dplyr::distinct() %>% + dplyr::summarize(`pb_summary` = min(`<>`, na.rm = TRUE)) %>% dplyr::pull(`pb_summary`) %>% as.character()", .open = "<<", .close = ">>" ) @@ -1622,7 +1636,7 @@ snip_lowest <- function(column) { #' #' @param column *The target column* #' -#' `scalar`` // **required** +#' `scalar` // **required** #' #' The name of the column that contains the target values. #' @@ -1644,7 +1658,7 @@ snip_lowest <- function(column) { #' label = "An example." #' ) %>% #' info_columns( -#' columns = "a", +#' columns = a, #' `Highest Value` = "Highest value is {highest_a}." #' ) %>% #' info_snippet( @@ -1677,8 +1691,8 @@ snip_highest <- function(column) { as.character( glue::glue( "~ . %>% - dplyr::select(<>) %>% dplyr::distinct() %>% - dplyr::summarize(`pb_summary` = max(<>, na.rm = TRUE)) %>% + dplyr::select(`<>`) %>% dplyr::distinct() %>% + dplyr::summarize(`pb_summary` = max(`<>`, na.rm = TRUE)) %>% dplyr::pull(`pb_summary`) %>% as.character()", .open = "<<", .close = ">>" ) diff --git a/R/interrogate.R b/R/interrogate.R index 8cb90dc6b..22606466c 100644 --- a/R/interrogate.R +++ b/R/interrogate.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -44,6 +44,15 @@ #' The default is `TRUE` and further options allow for fine control of how #' these rows are collected. #' +#' @param extract_tbl_checked *Collect validation results from each step* +#' +#' `scalar` // *default:* `TRUE` +#' +#' An option to collect processed data frames produced by executing the +#' validation steps. This information is necessary for some functions +#' (e.g., `get_sundered_data()`), but may grow to a large size. To opt out +#' of attaching this data to the agent, set this argument to `FALSE`. +#' #' @param get_first_n *Get the first n values* #' #' `scalar` // *default:* `NULL` (`optional`) @@ -79,6 +88,19 @@ #' A value that limits the possible number of rows returned when sampling #' non-passing rows using the `sample_frac` option. #' +#' @param show_step_label *Show step labels in progress* +#' +#' `scalar` // *default:* `FALSE` +#' +#' Whether to show the `label` value of each validation step in the console. +#' +#' @param progress *Show interrogation progress* +#' +#' `scalar` // *default:* `interactive()` +#' +#' Whether to show the progress of an agent's interrogation in the console. +#' Defaults to `TRUE` in interactive sessions. +#' #' @return A `ptblank_agent` object. #' #' @section Examples: @@ -105,7 +127,7 @@ #' tbl = tbl, #' label = "`interrogate()` example" #' ) %>% -#' col_vals_gt(columns = vars(a), value = 5) %>% +#' col_vals_gt(columns = a, value = 5) %>% #' interrogate() #' ``` #' @@ -130,10 +152,13 @@ interrogate <- function( agent, extract_failed = TRUE, + extract_tbl_checked = TRUE, get_first_n = NULL, sample_n = NULL, sample_frac = NULL, - sample_limit = 5000 + sample_limit = 5000, + show_step_label = FALSE, + progress = interactive() ) { # @@ -177,7 +202,7 @@ interrogate <- function( # TODO: create a better `stop()` message stop( "The `read_fn` object must be a function or an R formula.\n", - "* A function can be made with `function()` {
}.\n", + "* A function can be made with `function()` {}.\n", "* An R formula can also be used, with the expression on the RHS.", call. = FALSE ) @@ -199,7 +224,7 @@ interrogate <- function( # Quieting of an agent's remarks either when the agent has the # special label `"::QUIET::"` or the session is non-interactive - if (agent$label == "::QUIET::" || !interactive()) { + if (agent$label == "::QUIET::" || !progress) { quiet <- TRUE } else { quiet <- FALSE @@ -251,15 +276,6 @@ interrogate <- function( agent$validation_set[[i, "eval_active"]] <- FALSE } - # Set the validation step as `active = FALSE` if there is a - # no column available as a result of a select expression - if (!is.null(agent$validation_set$column[[i]]) && - is.na(agent$validation_set$column[[i]]) && - agent$validation_set$assertion_type[[i]] %in% - column_expansion_fns_vec()) { - agent$validation_set[[i, "eval_active"]] <- FALSE - } - # Skip the validation step if `active = FALSE` if (!agent$validation_set[[i, "eval_active"]]) { @@ -710,6 +726,7 @@ interrogate <- function( agent = agent, i = i, time_diff_s = time_diff_s, + show_step_label = show_step_label, quiet = quiet ) } @@ -722,6 +739,11 @@ interrogate <- function( # all validation steps have been carried out class(agent) <- c("has_intel", "ptblank_agent") + # Drop $tbl_checked if `extract_tbl_checked = FALSE` + if (!extract_tbl_checked) { + agent$validation_set$tbl_checked <- NULL + } + # Add the ending time to the `agent` object agent$time_end <- Sys.time() @@ -804,6 +826,7 @@ create_post_step_cli_output_a <- function( agent, i, time_diff_s, + show_step_label, quiet ) { @@ -840,6 +863,13 @@ create_post_step_cli_output_a <- function( )) %>% dplyr::pull(condition) + label <- agent$validation_set[i, ]$label + if (show_step_label && !is.na(label)) { + step_label <- paste0(" - {label}") + } else { + step_label <- NULL + } + cli::cli_div( theme = list( span.green = list(color = "green"), @@ -854,26 +884,33 @@ create_post_step_cli_output_a <- function( c( "Step {.field {i}}: an evaluation issue requires attention ", "(", interrogation_evaluation, ").", - print_time(time_diff_s) + print_time(time_diff_s), + step_label ) ) } else if (validation_condition == "NONE" && notify_condition == "NONE") { cli::cli_alert_success( - c("Step {.field {i}}: {.green OK}.", print_time(time_diff_s)) + c( + "Step {.field {i}}: {.green OK}.", + print_time(time_diff_s), + step_label + ) ) } else if (validation_condition != "NONE" && notify_condition == "NONE") { if (validation_condition == "STOP") { cli::cli_alert_danger( c( "Step {.field {i}}: {.red STOP} condition met.", - print_time(time_diff_s) + print_time(time_diff_s), + step_label ) ) } else { cli::cli_alert_warning( c( "Step {.field {i}}: {.yellow WARNING} condition met.", - print_time(time_diff_s) + print_time(time_diff_s), + step_label ) ) } @@ -883,7 +920,8 @@ create_post_step_cli_output_a <- function( c( "Step {.field {i}}: {.red STOP} and ", "{.blue NOTIFY} conditions met.", - print_time(time_diff_s) + print_time(time_diff_s), + step_label ) ) } else { @@ -891,7 +929,8 @@ create_post_step_cli_output_a <- function( c( "Step {.field {i}}: {.yellow WARNING} and ", "{.blue NOTIFY} conditions met.", - print_time(time_diff_s) + print_time(time_diff_s), + step_label ) ) } @@ -899,7 +938,8 @@ create_post_step_cli_output_a <- function( cli::cli_alert_warning( c( "Step {.field {i}}: {.blue NOTIFY} condition met.", - print_time(time_diff_s) + print_time(time_diff_s), + step_label ) ) } @@ -1059,18 +1099,15 @@ interrogate_comparison <- function( value <- get_values_at_idx(agent = agent, idx = idx) # Normalize a column in `vars()` to a `name` object - if (inherits(value, "list")) { - value <- value[1][[1]] %>% rlang::get_expr() - } else { - if (is.character(value)) { - value <- paste0("'", value, "'") - } + if (inherits(value, "list") && rlang::is_quosure(value[1][[1]])) { + # Both `vars(col)` and `vars("col")` become `col` for `dplyr::mutate()` + value <- rlang::sym(rlang::quo_get_expr(value[1][[1]])) } # Obtain the target column as a label column <- get_column_as_sym_at_idx(agent = agent, idx = idx) %>% - rlang::as_label() + as.character() # Determine whether NAs should be allowed na_pass <- get_column_na_pass_at_idx(agent = agent, idx = idx) @@ -1107,20 +1144,20 @@ tbl_val_comparison <- function( ) # Construct a string-based expression for the validation - expression <- paste(column, operator, value) + expression <- call(operator, as.symbol(column), value) if (is_tbl_mssql(table)) { table %>% dplyr::mutate(pb_is_good_ = dplyr::case_when( - !!rlang::parse_expr(expression) ~ 1, + !!expression ~ 1, TRUE ~ 0 )) } else { table %>% - dplyr::mutate(pb_is_good_ = !!rlang::parse_expr(expression)) %>% + dplyr::mutate(pb_is_good_ = !!expression) %>% dplyr::mutate(pb_is_good_ = dplyr::case_when( is.na(pb_is_good_) ~ na_pass, TRUE ~ pb_is_good_ @@ -1414,10 +1451,10 @@ interrogate_set <- function( } extra_variables <- - base::setdiff(table_col_distinct_values, set) + table_col_distinct_values[!table_col_distinct_values %in% set] table_col_distinct_set <- - base::intersect(table_col_distinct_values, set) + table_col_distinct_values[table_col_distinct_values %in% set] dplyr::bind_rows( dplyr::tibble(set_element = as.character(set)) %>% @@ -1489,7 +1526,7 @@ interrogate_set <- function( } table_col_distinct_set <- - base::intersect(table_col_distinct_values, set) + table_col_distinct_values[table_col_distinct_values %in% set] dplyr::tibble(set_element = as.character(set)) %>% dplyr::left_join( @@ -2226,13 +2263,21 @@ interrogate_col_exists <- function( # Obtain the target column as a symbol column <- get_column_as_sym_at_idx(agent = agent, idx = idx) + # Get `column_expr` to signal error if user didn't supply `columns` + column_input_missing <- agent$validation_set$columns_expr[idx] == "NULL" + # Create function for validating the `col_exists()` step function tbl_col_exists <- function( table, column, - column_names + column_names, + column_input_missing ) { + if (column_input_missing) { + stop("`columns` argument must be supplied.", call. = FALSE) + } + # Ensure that the input `table` is actually a table object tbl_validity_check(table = table) @@ -2244,7 +2289,8 @@ interrogate_col_exists <- function( tbl_col_exists( table = table, column = {{ column }}, - column_names = column_names + column_names = column_names, + column_input_missing = column_input_missing ) ) } @@ -2313,31 +2359,22 @@ interrogate_distinct <- function( table ) { - # Determine if grouping columns are provided in the test - # for distinct rows and parse the column names - if (!is.na(agent$validation_set$column[idx] %>% unlist())) { - + column_names <- + get_column_as_sym_at_idx(agent = agent, idx = idx) %>% + as.character() + + if (grepl("(,|&)", column_names)) { column_names <- - get_column_as_sym_at_idx(agent = agent, idx = idx) %>% - as.character() - - if (grepl("(,|&)", column_names)) { - column_names <- - strsplit(split = "(, |,|&)", column_names) %>% - unlist() - } - - if (length(column_names) == 1 && column_names == "NA") { - if (uses_tidyselect(expr_text = agent$validation_set$columns_expr[idx])) { - column_names <- character(0) - } - } - - } else if (is.na(agent$validation_set$column[idx] %>% unlist())) { - column_names <- get_all_cols(agent = agent) + strsplit(split = "(, |,|&)", column_names) %>% + unlist() } - col_syms <- rlang::syms(column_names) + if (identical(column_names, NA_character_)) { + # If column is missing, let it get caught by `column_validity_has_columns` + col_syms <- NULL + } else { + col_syms <- rlang::syms(column_names) + } # Create function for validating the `rows_distinct()` step function tbl_rows_distinct <- function( @@ -2413,31 +2450,22 @@ interrogate_complete <- function( table ) { - # Determine if grouping columns are provided in the test - # for distinct rows and parse the column names - if (!is.na(agent$validation_set$column[idx] %>% unlist())) { - + column_names <- + get_column_as_sym_at_idx(agent = agent, idx = idx) %>% + as.character() + + if (grepl("(,|&)", column_names)) { column_names <- - get_column_as_sym_at_idx(agent = agent, idx = idx) %>% - as.character() - - if (grepl("(,|&)", column_names)) { - column_names <- - strsplit(split = "(, |,|&)", column_names) %>% - unlist() - } - - if (length(column_names) == 1 && column_names == "NA") { - if (uses_tidyselect(expr_text = agent$validation_set$columns_expr[idx])) { - column_names <- character(0) - } - } - - } else if (is.na(agent$validation_set$column[idx] %>% unlist())) { - column_names <- get_all_cols(agent = agent) + strsplit(split = "(, |,|&)", column_names) %>% + unlist() } - col_syms <- rlang::syms(column_names) + if (identical(column_names, NA_character_)) { + # If column is missing, let it get caught by `column_validity_has_columns` + col_syms <- NULL + } else { + col_syms <- rlang::syms(column_names) + } # Create function for validating the `rows_complete()` step function tbl_rows_complete <- function( @@ -2823,15 +2851,9 @@ column_validity_checks_column_value <- function( value ) { - table_colnames <- colnames(table) + column_validity_checks_column(table, column) - if (!(as.character(column) %in% table_colnames)) { - - stop( - "The value for `column` doesn't correspond to a column name.", - call. = FALSE - ) - } + table_colnames <- colnames(table) if (inherits(value, "name")) { @@ -2851,7 +2873,7 @@ column_validity_checks_column_value <- function( # Validity check for presence of columns column_validity_has_columns <- function(columns) { - if (length(columns) < 1) { + if (length(columns) < 1 || identical(columns, NA_character_)) { stop( "The column selection statement that was used yielded no columns.", call. = FALSE @@ -2865,6 +2887,8 @@ column_validity_checks_column <- function( column ) { + column_validity_has_columns(as.character(column)) + table_colnames <- colnames(table) if (!(as.character(column) %in% table_colnames)) { @@ -2884,15 +2908,9 @@ column_validity_checks_ib_nb <- function( right ) { - table_colnames <- colnames(table) + column_validity_checks_column(table, column) - if (!(as.character(column) %in% table_colnames)) { - - stop( - "The value for `column` doesn't correspond to a column name.", - call. = FALSE - ) - } + table_colnames <- colnames(table) if (inherits(left, "name")) { @@ -2921,6 +2939,8 @@ column_validity_checks_ib_nb <- function( pointblank_try_catch <- function(expr) { + call <- rlang::enexpr(expr) + warn <- err <- NULL value <- @@ -2933,7 +2953,7 @@ pointblank_try_catch <- function(expr) { invokeRestart("muffleWarning") }) - eval_list <- list(value = value, warning = warn, error = err) + eval_list <- list(value = value, warning = warn, error = err, pb_call = call) class(eval_list) <- "table_eval" eval_list @@ -2953,7 +2973,7 @@ add_reporting_data <- function( has_warnings <- !is.null(tbl_checked$warning) has_error <- !is.null(tbl_checked$error) - capture_stack <- tbl_checked[c("warning", "error")] + capture_stack <- tbl_checked[c("warning", "error", "pb_call")] agent$validation_set$eval_warning[idx] <- has_warnings agent$validation_set$eval_error[idx] <- has_error @@ -3141,7 +3161,7 @@ perform_action <- function( } } - return(NULL) + NULL } perform_end_action <- function(agent) { @@ -3238,7 +3258,7 @@ perform_end_action <- function(agent) { y %>% rlang::f_rhs() %>% rlang::eval_tidy() }) - return(NULL) + NULL } add_table_extract <- function( diff --git a/R/logging.R b/R/logging.R index cf509b267..e52252051 100644 --- a/R/logging.R +++ b/R/logging.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -144,8 +144,8 @@ #' label = "An example.", #' actions = al #' ) %>% -#' col_vals_gt(columns = vars(d), 300) %>% -#' col_vals_in_set(columns = vars(f), c("low", "high")) %>% +#' col_vals_gt(columns = d, 300) %>% +#' col_vals_in_set(columns = f, c("low", "high")) %>% #' interrogate() #' #' agent @@ -184,14 +184,7 @@ log4r_step <- function( append_to = "pb_log_file" ) { - if (!requireNamespace("log4r", quietly = TRUE)) { - - stop( - "Using the `log4r_step()` function requires the log4r package:\n", - "* It can be installed with `install.packages(\"log4r\")`.", - call. = FALSE - ) - } + rlang::check_installed("log4r", "to use the `log4r_step()` function.") type <- x$this_type warn_val <- x$warn diff --git a/R/object_ops.R b/R/object_ops.R index e8720b839..d3c0f0f39 100644 --- a/R/object_ops.R +++ b/R/object_ops.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -133,14 +133,14 @@ #' ```r #' agent <- #' agent %>% -#' col_exists(columns = vars(date, date_time)) %>% +#' col_exists(columns = c(date, date_time)) %>% #' col_vals_regex( -#' columns = vars(b), +#' columns = b, #' regex = "[0-9]-[a-z]{3}-[0-9]{3}" #' ) %>% #' rows_distinct() %>% -#' col_vals_gt(columns = vars(d), value = 100) %>% -#' col_vals_lte(columns = vars(c), value = 5) %>% +#' col_vals_gt(columns = d, value = 100) %>% +#' col_vals_lte(columns = c, value = 5) %>% #' interrogate() #' ``` #' @@ -197,7 +197,7 @@ #' fn = snip_lowest(column = "a") #' ) %>% #' info_columns( -#' columns = vars(a), +#' columns = a, #' info = "From {low_a} to {high_a}." #' ) %>% #' info_columns( @@ -205,7 +205,7 @@ #' info = "Time-based values." #' ) %>% #' info_columns( -#' columns = "date", +#' columns = date, #' info = "The date part of `date_time`." #' ) %>% #' incorporate() @@ -240,13 +240,13 @@ #' actions = al #' ) %>% #' col_vals_gt( -#' columns = vars(b), -#' value = vars(g), +#' columns = b, +#' value = g, #' na_pass = TRUE, #' label = "b > g" #' ) %>% #' col_is_character( -#' columns = vars(b, f), +#' columns = c(b, f), #' label = "Verifying character-type columns" #' ) %>% #' interrogate() @@ -611,14 +611,14 @@ x_read_disk <- function( #' ```r #' agent <- #' agent %>% -#' col_exists(columns = vars(date, date_time)) %>% +#' col_exists(columns = c(date, date_time)) %>% #' col_vals_regex( -#' columns = vars(b), +#' columns = b, #' regex = "[0-9]-[a-z]{3}-[0-9]{3}" #' ) %>% #' rows_distinct() %>% -#' col_vals_gt(columns = vars(d), value = 100) %>% -#' col_vals_lte(columns = vars(c), value = 5) %>% +#' col_vals_gt(columns = d, value = 100) %>% +#' col_vals_lte(columns = c, value = 5) %>% #' interrogate() #' ``` #' @@ -672,7 +672,7 @@ x_read_disk <- function( #' fn = snip_lowest(column = "a") #' ) %>% #' info_columns( -#' columns = vars(a), +#' columns = a, #' info = "From {low_a} to {high_a}." #' ) %>% #' info_columns( @@ -680,7 +680,7 @@ x_read_disk <- function( #' info = "Time-based values." #' ) %>% #' info_columns( -#' columns = "date", +#' columns = date, #' info = "The date part of `date_time`." #' ) %>% #' incorporate() @@ -844,7 +844,7 @@ export_report <- function( #' #' @param tbl *Table or expression for reading in one* #' -#' `obj:|
` // **required** +#' `obj:|` // **required** #' #' The input table for the *agent* or the *informant*. This can be a data #' frame, a tibble, a `tbl_dbi` object, or a `tbl_spark` object. @@ -852,8 +852,8 @@ export_report <- function( #' how to retrieve the target table at interrogation- or incorporation-time. #' There are two ways to specify an association to a target table: (1) as a #' table-prep formula, which is a right-hand side (RHS) formula expression -#' (e.g., `~ {
}`), or (2) as a function (e.g., -#' `function() {
}`). +#' (e.g., `~ { }`), or (2) as a function (e.g., +#' `function() { }`). #' #' @param tbl_name *A table name* #' @@ -895,9 +895,9 @@ export_report <- function( #' label = "An example.", #' actions = al #' ) %>% -#' col_exists(columns = vars(date, date_time)) %>% +#' col_exists(columns = c(date, date_time)) %>% #' col_vals_regex( -#' columns = vars(b), +#' columns = b, #' regex = "[0-9]-[a-z]{3}-[0-9]{3}" #' ) %>% #' rows_distinct() %>% diff --git a/R/pipe.R b/R/pipe.R index b63e636d7..081383635 100644 --- a/R/pipe.R +++ b/R/pipe.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html diff --git a/R/print.R b/R/print.R index 4cec41fb8..4d6ba6b0e 100644 --- a/R/print.R +++ b/R/print.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html diff --git a/R/read_disk_multiagent.R b/R/read_disk_multiagent.R index 1c84a02a3..787c0d893 100644 --- a/R/read_disk_multiagent.R +++ b/R/read_disk_multiagent.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html diff --git a/R/reexports.R b/R/reexports.R index 81e99bd1f..713bdae8f 100644 --- a/R/reexports.R +++ b/R/reexports.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -35,26 +35,6 @@ dplyr::between #' @export rlang::expr -#' @importFrom tidyselect starts_with -#' @export -tidyselect::starts_with - -#' @importFrom tidyselect ends_with -#' @export -tidyselect::ends_with - -#' @importFrom tidyselect contains -#' @export -tidyselect::contains - -#' @importFrom tidyselect matches -#' @export -tidyselect::matches - -#' @importFrom tidyselect everything -#' @export -tidyselect::everything - #' @importFrom blastula creds #' @export blastula::creds diff --git a/R/regex.R b/R/regex.R index 3f8f25743..0e3e7a359 100644 --- a/R/regex.R +++ b/R/regex.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html diff --git a/R/remove_deactivate.R b/R/remove_deactivate.R index 9c3b96469..31c189cd0 100644 --- a/R/remove_deactivate.R +++ b/R/remove_deactivate.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -60,11 +60,11 @@ #' label = "An example." #' ) %>% #' col_exists( -#' columns = vars(date), +#' columns = date, #' active = FALSE #' ) %>% #' col_vals_regex( -#' columns = vars(b), +#' columns = b, #' regex = "[0-9]-[a-z]{3}-[0-9]{3}", #' active = FALSE #' ) %>% @@ -146,9 +146,9 @@ activate_steps <- function( #' tbl_name = "small_table", #' label = "An example." #' ) %>% -#' col_exists(columns = vars(date)) %>% +#' col_exists(columns = date) %>% #' col_vals_regex( -#' columns = vars(b), +#' columns = b, #' regex = "[0-9]-[a-z]{3}-[0-9]" #' ) %>% #' interrogate() @@ -227,9 +227,9 @@ deactivate_steps <- function( #' tbl_name = "small_table", #' label = "An example." #' ) %>% -#' col_exists(columns = vars(date)) %>% +#' col_exists(columns = date) %>% #' col_vals_regex( -#' columns = vars(b), +#' columns = b, #' regex = "[0-9]-[a-z]{3}-[0-9]" #' ) %>% #' interrogate() diff --git a/R/row_count_match.R b/R/row_count_match.R index ff234ae64..03c6a61a0 100644 --- a/R/row_count_match.R +++ b/R/row_count_match.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -43,9 +43,9 @@ #' against the target table in terms of row count values. If supplying a #' comparison table, it can either be a table object such as a data frame, a #' tibble, a `tbl_dbi` object, or a `tbl_spark` object. Alternatively, a -#' table-prep formula (`~
`) or a function (`function() -#'
`) can be used to lazily read in the comparison table -#' at interrogation time. +#' table-prep formula (`~ `) or a function +#' (`function() `) can be used to lazily read in the +#' comparison table at interrogation time. #' #' @param tbl_compare *[Deprecated] Comparison table* #' @@ -137,6 +137,19 @@ #' depending on the situation (the first produces a warning, the other #' `stop()`s). #' +#' @section Labels: +#' +#' `label` may be a single string or a character vector that matches the number +#' of expanded steps. `label` also supports `{glue}` syntax and exposes the +#' following dynamic variables contextualized to the current step: +#' +#' - `"{.step}"`: The validation step name +#' - `"{.seg_col}"`: The current segment's column name +#' - `"{.seg_val}"`: The current segment's value/group +#' +#' The glue context also supports ordinary expressions for further flexibility +#' (e.g., `"{toupper(.step)}"`) as long as they return a length-1 string. +#' #' @section Briefs: #' #' Want to describe this validation step in some detail? Keep in mind that this @@ -371,6 +384,7 @@ row_count_match <- function( # Add one or more validation steps based on the # length of `segments` + label <- resolve_label(label, segments = segments_list) for (i in seq_along(segments_list)) { seg_col <- names(segments_list[i]) @@ -390,7 +404,7 @@ row_count_match <- function( seg_val = seg_val, actions = covert_actions(actions, agent), step_id = step_id, - label = label, + label = label[[i]], brief = brief, active = active ) diff --git a/R/rows_complete.R b/R/rows_complete.R index c7fd201c4..d497fd067 100644 --- a/R/rows_complete.R +++ b/R/rows_complete.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -32,10 +32,14 @@ #' be used with a data table. As a validation step or as an expectation, this #' will operate over the number of test units that is equal to the number of #' rows in the table (after any `preconditions` have been applied). -#' -#' We can specify the constraining column names in quotes, in `vars()`, and with -#' the following **tidyselect** helper functions: `starts_with()`, -#' `ends_with()`, `contains()`, `matches()`, and `everything()`. +#' +#' @param columns *The target columns* +#' +#' `` // *default:* `everything()` +#' +#' A column-selecting expression, as one would use inside `dplyr::select()`. +#' Specifies the set of column(s) for which the completeness of rows is +#' checked. #' #' @inheritParams col_vals_gt #' @@ -126,6 +130,20 @@ #' warning when a quarter of the total test units fails, the other `stop()`s at #' the same threshold level). #' +#' @section Labels: +#' +#' `label` may be a single string or a character vector that matches the number +#' of expanded steps. `label` also supports `{glue}` syntax and exposes the +#' following dynamic variables contextualized to the current step: +#' +#' - `"{.step}"`: The validation step name +#' - `"{.col}"`: The current column name +#' - `"{.seg_col}"`: The current segment's column name +#' - `"{.seg_val}"`: The current segment's value/group +#' +#' The glue context also supports ordinary expressions for further flexibility +#' (e.g., `"{toupper(.step)}"`) as long as they return a length-1 string. +#' #' @section Briefs: #' #' Want to describe this validation step in some detail? Keep in mind that this @@ -150,7 +168,7 @@ #' ```r #' agent %>% #' rows_complete( -#' columns = vars(a, b), +#' columns = c(a, b), #' preconditions = ~ . %>% dplyr::filter(a < 10), #' segments = b ~ c("group_1", "group_2"), #' actions = action_levels(warn_at = 0.1, stop_at = 0.2), @@ -164,7 +182,7 @@ #' ```yaml #' steps: #' - rows_complete: -#' columns: vars(a, b) +#' columns: c(a, b) #' preconditions: ~. %>% dplyr::filter(a < 10) #' segments: b ~ c("group_1", "group_2") #' actions: @@ -205,7 +223,7 @@ #' ```r #' agent <- #' create_agent(tbl = tbl) %>% -#' rows_complete(columns = vars(a, b)) %>% +#' rows_complete(columns = c(a, b)) %>% #' interrogate() #' ``` #' @@ -227,7 +245,7 @@ #' #' ```{r} #' tbl %>% -#' rows_complete(columns = vars(a, b)) %>% +#' rows_complete(columns = c(a, b)) %>% #' dplyr::pull(a) #' ``` #' @@ -237,7 +255,7 @@ #' time. This is primarily used in **testthat** tests. #' #' ```r -#' expect_rows_complete(tbl, columns = vars(a, b)) +#' expect_rows_complete(tbl, columns = c(a, b)) #' ``` #' #' ## D: Using the test function @@ -246,7 +264,7 @@ #' us. #' #' ```{r} -#' test_rows_complete(tbl, columns = vars(a, b)) +#' test_rows_complete(tbl, columns = c(a, b)) #' ``` #' #' @family validation functions @@ -261,7 +279,7 @@ NULL #' @export rows_complete <- function( x, - columns = NULL, + columns = tidyselect::everything(), preconditions = NULL, segments = NULL, actions = NULL, @@ -271,28 +289,17 @@ rows_complete <- function( active = TRUE ) { - # Get `columns` as a label - columns_expr <- - rlang::as_label(rlang::quo(!!enquo(columns))) %>% - gsub("^\"|\"$", "", .) - # Capture the `columns` expression columns <- rlang::enquo(columns) - - if (uses_tidyselect(expr_text = columns_expr)) { - - # Resolve the columns based on the expression - columns <- resolve_columns(x = x, var_expr = columns, preconditions = NULL) - - } else { - - # Resolve the columns based on the expression - if (!is.null(rlang::eval_tidy(columns)) && !is.null(columns)) { - columns <- resolve_columns(x = x, var_expr = columns, preconditions) - } else { - columns <- NULL - } + # `rows_*()` functions treat `NULL` as `everything()` + if (rlang::quo_is_null(columns) || rlang::quo_is_missing(columns)) { + columns <- rlang::quo(tidyselect::everything()) } + # Get `columns` as a label + columns_expr <- as_columns_expr(columns) + + # Resolve the columns based on the expression + columns <- resolve_columns(x = x, var_expr = columns, preconditions = NULL) # Resolve segments into list segments_list <- @@ -307,7 +314,7 @@ rows_complete <- function( secret_agent <- create_agent(x, label = "::QUIET::") %>% rows_complete( - columns = columns, + columns = tidyselect::all_of(columns), preconditions = preconditions, segments = segments, label = label, @@ -322,12 +329,8 @@ rows_complete <- function( agent <- x - if (length(columns) > 0) { + if (length(columns) > 1) { columns <- paste(columns, collapse = ", ") - } else if (length(columns) == 1) { - columns <- columns - } else { - columns <- NULL } if (is.null(brief)) { @@ -352,6 +355,7 @@ rows_complete <- function( # Add one or more validation steps based on the # length of `segments` + label <- resolve_label(label, segments = segments_list) for (i in seq_along(segments_list)) { seg_col <- names(segments_list[i]) @@ -371,7 +375,7 @@ rows_complete <- function( seg_val = seg_val, actions = covert_actions(actions, agent), step_id = step_id, - label = label, + label = label[[i]], brief = brief, active = active ) @@ -385,7 +389,7 @@ rows_complete <- function( #' @export expect_rows_complete <- function( object, - columns = NULL, + columns = tidyselect::everything(), preconditions = NULL, threshold = 1 ) { @@ -440,7 +444,7 @@ expect_rows_complete <- function( #' @export test_rows_complete <- function( object, - columns = NULL, + columns = tidyselect::everything(), preconditions = NULL, threshold = 1 ) { diff --git a/R/rows_distinct.R b/R/rows_distinct.R index 6c822a8b3..d23afe8b9 100644 --- a/R/rows_distinct.R +++ b/R/rows_distinct.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -34,9 +34,13 @@ #' test units that is equal to the number of rows in the table (after any #' `preconditions` have been applied). #' -#' We can specify the constraining column names in quotes, in `vars()`, and with -#' the following **tidyselect** helper functions: `starts_with()`, -#' `ends_with()`, `contains()`, `matches()`, and `everything()`. +#' @param columns *The target columns* +#' +#' `` // *default:* `everything()` +#' +#' A column-selecting expression, as one would use inside `dplyr::select()`. +#' Specifies the set of column(s) for which the distinctness of rows is +#' checked. #' #' @inheritParams col_vals_gt #' @@ -127,6 +131,20 @@ #' warning when a quarter of the total test units fails, the other `stop()`s at #' the same threshold level). #' +#' @section Labels: +#' +#' `label` may be a single string or a character vector that matches the number +#' of expanded steps. `label` also supports `{glue}` syntax and exposes the +#' following dynamic variables contextualized to the current step: +#' +#' - `"{.step}"`: The validation step name +#' - `"{.col}"`: The current column name +#' - `"{.seg_col}"`: The current segment's column name +#' - `"{.seg_val}"`: The current segment's value/group +#' +#' The glue context also supports ordinary expressions for further flexibility +#' (e.g., `"{toupper(.step)}"`) as long as they return a length-1 string. +#' #' @section Briefs: #' #' Want to describe this validation step in some detail? Keep in mind that this @@ -151,7 +169,7 @@ #' ```r #' agent %>% #' rows_distinct( -#' columns = vars(a, b), +#' columns = c(a, b), #' preconditions = ~ . %>% dplyr::filter(a < 10), #' segments = b ~ c("group_1", "group_2"), #' actions = action_levels(warn_at = 0.1, stop_at = 0.2), @@ -165,7 +183,7 @@ #' ``` #' steps: #' - rows_distinct: -#' columns: vars(a, b) +#' columns: c(a, b) #' preconditions: ~. %>% dplyr::filter(a < 10) #' segments: b ~ c("group_1", "group_2") #' actions: @@ -206,7 +224,7 @@ #' ```r #' agent <- #' create_agent(tbl = tbl) %>% -#' rows_distinct(columns = vars(a, b)) %>% +#' rows_distinct(columns = c(a, b)) %>% #' interrogate() #' ``` #' @@ -228,7 +246,7 @@ #' #' ```{r} #' tbl %>% -#' rows_distinct(columns = vars(a, b)) %>% +#' rows_distinct(columns = c(a, b)) %>% #' dplyr::pull(a) #' ``` #' @@ -238,7 +256,7 @@ #' time. This is primarily used in **testthat** tests. #' #' ```r -#' expect_rows_distinct(tbl, columns = vars(a, b)) +#' expect_rows_distinct(tbl, columns = c(a, b)) #' ``` #' #' ## D: Using the test function @@ -247,7 +265,7 @@ #' us. #' #' ```{r} -#' test_rows_distinct(tbl, columns = vars(a, b)) +#' test_rows_distinct(tbl, columns = c(a, b)) #' ``` #' #' @family validation functions @@ -262,7 +280,7 @@ NULL #' @export rows_distinct <- function( x, - columns = NULL, + columns = tidyselect::everything(), preconditions = NULL, segments = NULL, actions = NULL, @@ -272,28 +290,17 @@ rows_distinct <- function( active = TRUE ) { - # Get `columns` as a label - columns_expr <- - rlang::as_label(rlang::quo(!!enquo(columns))) %>% - gsub("^\"|\"$", "", .) - # Capture the `columns` expression columns <- rlang::enquo(columns) - - if (uses_tidyselect(expr_text = columns_expr)) { - - # Resolve the columns based on the expression - columns <- resolve_columns(x = x, var_expr = columns, preconditions = NULL) - - } else { - - # Resolve the columns based on the expression - if (!is.null(rlang::eval_tidy(columns)) && !is.null(columns)) { - columns <- resolve_columns(x = x, var_expr = columns, preconditions) - } else { - columns <- NULL - } + # `rows_*()` functions treat `NULL` as `everything()` + if (rlang::quo_is_null(columns) || rlang::quo_is_missing(columns)) { + columns <- rlang::quo(tidyselect::everything()) } + # Get `columns` as a label + columns_expr <- as_columns_expr(columns) + + # Resolve the columns based on the expression + columns <- resolve_columns(x = x, var_expr = columns, preconditions = NULL) # Resolve segments into list segments_list <- @@ -308,7 +315,7 @@ rows_distinct <- function( secret_agent <- create_agent(x, label = "::QUIET::") %>% rows_distinct( - columns = columns, + columns = tidyselect::all_of(columns), preconditions = preconditions, segments = segments, label = label, @@ -323,12 +330,8 @@ rows_distinct <- function( agent <- x - if (length(columns) > 0) { + if (length(columns) > 1) { columns <- paste(columns, collapse = ", ") - } else if (length(columns) == 1) { - columns <- columns - } else { - columns <- NULL } if (is.null(brief)) { @@ -353,6 +356,7 @@ rows_distinct <- function( # Add one or more validation steps based on the # length of `segments` + label <- resolve_label(label, segments = segments_list) for (i in seq_along(segments_list)) { seg_col <- names(segments_list[i]) @@ -372,7 +376,7 @@ rows_distinct <- function( seg_val = seg_val, actions = covert_actions(actions, agent), step_id = step_id, - label = label, + label = label[[i]], brief = brief, active = active ) @@ -386,7 +390,7 @@ rows_distinct <- function( #' @export expect_rows_distinct <- function( object, - columns = NULL, + columns = tidyselect::everything(), preconditions = NULL, threshold = 1 ) { @@ -441,7 +445,7 @@ expect_rows_distinct <- function( #' @export test_rows_distinct <- function( object, - columns = NULL, + columns = tidyselect::everything(), preconditions = NULL, threshold = 1 ) { diff --git a/R/scan_data.R b/R/scan_data.R index db2cb3a32..b13c6545e 100644 --- a/R/scan_data.R +++ b/R/scan_data.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -221,26 +221,10 @@ scan_data <- function( } if (any(c("interactions", "correlations") %in% sections)) { - - if (!requireNamespace("ggplot2", quietly = TRUE)) { - - stop( - "The `interactions` and `correlations` sections require ", - "the ggplot2 package:\n", - "* It can be installed with `install.packages(\"ggplot2\")`.", - call. = FALSE - ) - } - - if (!requireNamespace("ggforce", quietly = TRUE)) { - - stop( - "The `interactions` and `correlations` sections require ", - "the ggforce package:\n", - "* It can be installed with `install.packages(\"ggforce\")`.", - call. = FALSE - ) - } + rlang::check_installed( + c("ggforce", "ggplot2"), + "to use the `interactions` and `correlations` sections." + ) } # Normalize the reporting language identifier and stop if necessary @@ -1041,7 +1025,7 @@ probe_columns_numeric <- function( locale ) { - data_column <- dplyr::select(data, {{ column }}) + data_column <- dplyr::select(data, tidyselect::any_of(column)) column_description_gt <- get_column_description_gt( @@ -1133,7 +1117,7 @@ probe_columns_character <- function( locale ) { - data_column <- data %>% dplyr::select({{ column }}) + data_column <- data %>% dplyr::select(tidyselect::any_of(column)) column_description_gt <- get_column_description_gt( @@ -1184,7 +1168,7 @@ probe_columns_logical <- function( locale ) { - data_column <- data %>% dplyr::select({{ column }}) + data_column <- data %>% dplyr::select(tidyselect::any_of(column)) column_description_gt <- get_column_description_gt( @@ -1211,7 +1195,7 @@ probe_columns_factor <- function( locale ) { - data_column <- data %>% dplyr::select({{ column }}) + data_column <- data %>% dplyr::select(tidyselect::any_of(column)) column_description_gt <- get_column_description_gt( @@ -1238,7 +1222,7 @@ probe_columns_date <- function( locale ) { - data_column <- data %>% dplyr::select({{ column }}) + data_column <- data %>% dplyr::select(tidyselect::any_of(column)) column_description_gt <- get_column_description_gt( @@ -1265,7 +1249,7 @@ probe_columns_posix <- function( locale ) { - data_column <- data %>% dplyr::select({{ column }}) + data_column <- data %>% dplyr::select(tidyselect::any_of(column)) column_description_gt <- get_column_description_gt( @@ -1290,7 +1274,7 @@ probe_columns_other <- function( n_rows ) { - data_column <- data %>% dplyr::select({{ column }}) + data_column <- data %>% dplyr::select(tidyselect::any_of(column)) column_classes <- paste(class(data_column), collapse = ", ") diff --git a/R/serially.R b/R/serially.R index 02e4d80b4..698772d2d 100644 --- a/R/serially.R +++ b/R/serially.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -52,9 +52,9 @@ #' Here's an example of how to arrange expressions: #' #' ``` -#' ~ test_col_exists(., columns = vars(count)), -#' ~ test_col_is_numeric(., columns = vars(count)), -#' ~ col_vals_gt(., columns = vars(count), value = 2) +#' ~ test_col_exists(., columns = count), +#' ~ test_col_is_numeric(., columns = count), +#' ~ col_vals_gt(., columns = count, value = 2) #' ``` #' #' This series concentrates on the column called `count` and first checks @@ -83,7 +83,7 @@ #' [col_vals_increasing()], etc.) can optionally be inserted at the end of the #' series, serving as a validation step that only undergoes interrogation if #' the prior tests adequately pass. An example of this is -#' `~ test_column_exists(., vars(a)), ~ col_vals_not_null(., vars(a))`). +#' `~ test_column_exists(., a), ~ col_vals_not_null(., a)`). #' #' @param .list *Alternative to `...`* #' @@ -118,12 +118,17 @@ #' #' @section Column Names: #' -#' If providing multiple column names in any of the supplied validation steps, -#' the result will be an expansion of sub-validation steps to that number of -#' column names. Aside from column names in quotes and in `vars()`, -#' **tidyselect** helper functions are available for specifying columns. They -#' are: `starts_with()`, `ends_with()`, `contains()`, `matches()`, and -#' `everything()`. +#' `columns` may be a single column (as symbol `a` or string `"a"`) or a vector +#' of columns (`c(a, b, c)` or `c("a", "b", "c")`). `{tidyselect}` helpers +#' are also supported, such as `contains("date")` and `where(is.double)`. If +#' passing an *external vector* of columns, it should be wrapped in `all_of()`. +#' +#' When multiple columns are selected by `columns`, the result will be an +#' expansion of validation steps to that number of columns (e.g., +#' `c(col_a, col_b)` will result in the entry of two validation steps). +#' +#' Previously, columns could be specified in `vars()`. This continues to work, +#' but `c()` offers the same capability and supersedes `vars()` in `columns`. #' #' @section Preconditions: #' @@ -160,6 +165,17 @@ #' quarter of the total test units fails, the other `stop()`s at the same #' threshold level). #' +#' @section Labels: +#' +#' `label` may be a single string or a character vector that matches the number +#' of expanded steps. `label` also supports `{glue}` syntax and exposes the +#' following dynamic variables contextualized to the current step: +#' +#' - `"{.step}"`: The validation step name +#' +#' The glue context also supports ordinary expressions for further flexibility +#' (e.g., `"{toupper(.step)}"`) as long as they return a length-1 string. +#' #' @section Briefs: #' #' Want to describe this validation step in some detail? Keep in mind that this @@ -184,9 +200,9 @@ #' ```r #' agent %>% #' serially( -#' ~ col_vals_lt(., columns = vars(a), value = 8), -#' ~ col_vals_gt(., columns = vars(c), value = vars(a)), -#' ~ col_vals_not_null(., columns = vars(b)), +#' ~ test_col_vals_lt(., columns = a, value = 8), +#' ~ test_col_vals_gt(., columns = c, value = vars(a)), +#' ~ col_vals_not_null(., columns = b), #' preconditions = ~ . %>% dplyr::filter(a < 10), #' actions = action_levels(warn_at = 0.1, stop_at = 0.2), #' label = "The `serially()` step.", @@ -200,9 +216,9 @@ #' steps: #' - serially: #' fns: -#' - ~col_vals_lt(., columns = vars(a), value = 8) -#' - ~col_vals_gt(., columns = vars(c), value = vars(a)) -#' - ~col_vals_not_null(., vars(b)) +#' - ~test_col_vals_lt(., columns = a, value = 8) +#' - ~test_col_vals_gt(., columns = c, value = vars(a)) +#' - ~col_vals_not_null(., columns = b) #' preconditions: ~. %>% dplyr::filter(a < 10) #' actions: #' warn_fraction: 0.1 @@ -249,9 +265,9 @@ #' agent_1 <- #' create_agent(tbl = tbl) %>% #' serially( -#' ~ test_col_is_numeric(., columns = vars(a, b)), -#' ~ test_col_vals_not_null(., columns = vars(a, b)), -#' ~ col_vals_gt(., columns = vars(b), value = vars(a)) +#' ~ test_col_is_numeric(., columns = c(a, b)), +#' ~ test_col_vals_not_null(., columns = c(a, b)), +#' ~ col_vals_gt(., columns = b, value = vars(a)) #' ) %>% #' interrogate() #' ``` @@ -276,8 +292,8 @@ #' agent_2 <- #' create_agent(tbl = tbl) %>% #' serially( -#' ~ test_col_is_numeric(., columns = vars(a, b)), -#' ~ test_col_vals_not_null(., columns = vars(a, b)) +#' ~ test_col_is_numeric(., columns = c(a, b)), +#' ~ test_col_vals_not_null(., columns = c(a, b)) #' ) %>% #' interrogate() #' ``` @@ -299,9 +315,9 @@ #' ```{r} #' tbl %>% #' serially( -#' ~ test_col_is_numeric(., columns = vars(a, b)), -#' ~ test_col_vals_not_null(., columns = vars(a, b)), -#' ~ col_vals_gt(., columns = vars(b), value = vars(a)) +#' ~ test_col_is_numeric(., columns = c(a, b)), +#' ~ test_col_vals_not_null(., columns = c(a, b)), +#' ~ col_vals_gt(., columns = b, value = vars(a)) #' ) #' ``` #' @@ -313,9 +329,9 @@ #' ```r #' expect_serially( #' tbl, -#' ~ test_col_is_numeric(., columns = vars(a, b)), -#' ~ test_col_vals_not_null(., columns = vars(a, b)), -#' ~ col_vals_gt(., columns = vars(b), value = vars(a)) +#' ~ test_col_is_numeric(., columns = c(a, b)), +#' ~ test_col_vals_not_null(., columns = c(a, b)), +#' ~ col_vals_gt(., columns = b, value = vars(a)) #' ) #' ``` #' @@ -327,9 +343,9 @@ #' ```{r} #' tbl %>% #' test_serially( -#' ~ test_col_is_numeric(., columns = vars(a, b)), -#' ~ test_col_vals_not_null(., columns = vars(a, b)), -#' ~ col_vals_gt(., columns = vars(b), value = vars(a)) +#' ~ test_col_is_numeric(., columns = c(a, b)), +#' ~ test_col_vals_not_null(., columns = c(a, b)), +#' ~ col_vals_gt(., columns = b, value = vars(a)) #' ) #' ``` #' @@ -644,6 +660,7 @@ serially <- function( # Add one or more validation steps based on the # length of `segments_list` + label <- resolve_label(label, segments = segments_list) for (i in seq_along(segments_list)) { seg_col <- names(segments_list[i]) @@ -664,7 +681,7 @@ serially <- function( seg_val = seg_val, actions = covert_actions(actions, agent), step_id = step_id, - label = label, + label = label[[i]], brief = brief, active = active ) diff --git a/R/specially.R b/R/specially.R index 15f3c5a28..8e27ff486 100644 --- a/R/specially.R +++ b/R/specially.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -104,6 +104,17 @@ #' quarter of the total test units fails, the other `stop()`s at the same #' threshold level). #' +#' @section Labels: +#' +#' `label` may be a single string or a character vector that matches the number +#' of expanded steps. `label` also supports `{glue}` syntax and exposes the +#' following dynamic variables contextualized to the current step: +#' +#' - `"{.step}"`: The validation step name +#' +#' The glue context also supports ordinary expressions for further flexibility +#' (e.g., `"{toupper(.step)}"`) as long as they return a length-1 string. +#' #' @section Briefs: #' #' Want to describe this validation step in some detail? Keep in mind that this @@ -366,6 +377,7 @@ specially <- function( # Add one or more validation steps based on the # length of `segments_list` + label <- resolve_label(label, segments = segments_list) for (i in seq_along(segments_list)) { seg_col <- names(segments_list[i]) @@ -386,7 +398,7 @@ specially <- function( seg_val = seg_val, actions = covert_actions(actions, agent), step_id = step_id, - label = label, + label = label[[i]], brief = brief, active = active ) diff --git a/R/steps_and_briefs.R b/R/steps_and_briefs.R index 936906a74..ccb2a63c1 100644 --- a/R/steps_and_briefs.R +++ b/R/steps_and_briefs.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -35,34 +35,23 @@ create_validation_step <- function( step_id = NULL, label = NULL, brief = NULL, - active = NULL + active = NULL, + .call = rlang::caller_env(n = 2L) ) { # Get the next step number (i) i <- get_next_validation_set_row(agent) # Calculate the SHA1 hash for the validation step - sha1 <- - digest::sha1( - list( - assertion_type = assertion_type, - column = ifelse(is.null(column), list(NULL), list(column)), - values = ifelse( - is.null(values) || is_a_table_object(values), - list(NULL), list(values) - ), - na_pass = ifelse(is.null(na_pass), NA, as.logical(na_pass)), - preconditions = ifelse( - is.null(preconditions), list(NULL), list(preconditions) - ), - seg_col = ifelse( - is.null(seg_col), NA_character_, as.character(seg_col) - ), - seg_val = ifelse( - is.null(seg_val), NA_character_, as.character(seg_val) - ) - ) - ) + sha1 <- hash_validation_step( + assertion_type = assertion_type, + column = column, + values = values, + na_pass = na_pass, + preconditions = preconditions, + seg_col = seg_col, + seg_val = seg_val + ) # Create a validation step as a single-row `tbl_df` object validation_step_df <- @@ -106,6 +95,21 @@ create_validation_step <- function( f_failed = NA_real_ ) + # glue-powered labels + if (!is.na(validation_step_df$label)) { + glue_mask <- rlang::new_environment( + data = list( + .step = assertion_type, + .col = column, + .seg_col = seg_col, + .seg_val = seg_val + ), + parent = .call + ) + label <- glue::glue_data(glue_mask, validation_step_df$label, .envir = NULL) + validation_step_df$label <- as.character(label) + } + # Append `validation_step` to `validation_set` agent$validation_set <- dplyr::bind_rows(agent$validation_set, validation_step_df) @@ -113,6 +117,54 @@ create_validation_step <- function( agent } +get_hash_version <- function() { + "v0.12" +} + +hash_validation_step <- function(assertion_type, + column = NULL, + values = NULL, + na_pass = NULL, + preconditions = NULL, + seg_col = NULL, + seg_val = NULL) { + + # pkg version that introduced the current hash implementation + hash_version <- get_hash_version() + + values <- if (is.null(values) || is_a_table_object(values)) { + NA_character_ + } else if (is.list(values)) { + # Resolve `vars()` to scalar string + toString(vapply(values, deparse_expr, character(1))) + } else { + deparse_expr(values) + } + + preconditions <- if (inherits(preconditions, "fseq")) { + # Spell out components of magrittr anonymous function + magrittr_fn_seq <- environment(preconditions)[["_function_list"]] + deparse_expr(magrittr_fn_seq) + } else { + deparse_expr(preconditions) + } + + step_chr <- c( + assertion_type = assertion_type, + column = as.character(column %||% NA_character_), + values = values, + na_pass = as.character(na_pass %||% NA_character_), + preconditions = preconditions, + seg_col = as.character(seg_col %||% NA_character_), + seg_val = as.character(seg_val %||% NA_character_) + ) + + step_hash <- digest::sha1(step_chr) + + paste(step_hash, hash_version, sep = "-") + +} + apply_preconditions_to_tbl <- function(agent, idx, tbl) { preconditions <- agent$validation_set$preconditions[[idx]] @@ -135,9 +187,10 @@ apply_segments_to_tbl <- function(agent, idx, tbl) { } # Generate a second set of 'preconditions' to filter the table + seg_val <- gsub("'", "\\\\'", seg_val) preconditions <- stats::as.formula( - glue::glue("~ . %>% dplyr::filter({seg_col} == '{seg_val}')") + glue::glue("~ . %>% dplyr::filter(`{seg_col}` == '{seg_val}')") ) tbl <- apply_preconditions(tbl = tbl, preconditions = preconditions) diff --git a/R/table_transformers.R b/R/table_transformers.R index 66cd2dce7..0c47d898d 100644 --- a/R/table_transformers.R +++ b/R/table_transformers.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -67,7 +67,7 @@ #' ```{r} #' tt_summary_stats(tbl = game_revenue) %>% #' col_vals_lt( -#' columns = vars(item_revenue), +#' columns = item_revenue, #' value = 150, #' segments = .param. ~ "max" #' ) @@ -83,7 +83,7 @@ #' dplyr::filter(item_type == "iap") %>% #' tt_summary_stats() %>% #' col_vals_between( -#' columns = vars(item_revenue), +#' columns = item_revenue, #' left = 8, right = 12, #' segments = .param. ~ "med" #' ) @@ -112,7 +112,7 @@ #' rows_complete() %>% #' rows_distinct() %>% #' col_vals_between( -#' columns = vars(item_revenue), +#' columns = item_revenue, #' left = 8, right = 12, #' preconditions = ~ . %>% #' dplyr::filter(item_type == "iap") %>% @@ -161,7 +161,7 @@ tt_summary_stats <- function(tbl) { if (r_col_types[i] %in% c("integer", "numeric")) { - data_col <- dplyr::select(tbl, col_names[i]) + data_col <- dplyr::select(tbl, tidyselect::all_of(col_names[i])) # nocov start @@ -238,11 +238,11 @@ tt_summary_stats <- function(tbl) { #' ```{r} #' tt_string_info(tbl = game_revenue) %>% #' col_vals_equal( -#' columns = vars(player_id), +#' columns = player_id, #' value = 15 #' ) %>% #' col_vals_equal( -#' columns = vars(session_id), +#' columns = session_id, #' value = 24 #' ) #' ``` @@ -256,7 +256,7 @@ tt_summary_stats <- function(tbl) { #' ```{r} #' tt_string_info(tbl = small_table) %>% #' test_col_vals_lte( -#' columns = vars(f), +#' columns = f, #' value = 4 #' ) #' ``` @@ -286,7 +286,7 @@ tt_string_info <- function(tbl) { if (r_col_types[i] == "character") { - data_col <- dplyr::select(tbl, col_names[i]) + data_col <- dplyr::select(tbl, tidyselect::all_of(col_names[i])) suppressWarnings({ info_list <- get_table_column_nchar_stats(data_column = data_col) @@ -343,7 +343,7 @@ tt_string_info <- function(tbl) { #' tt_tbl_dims(tbl = game_revenue) %>% #' dplyr::filter(.param. == "rows") %>% #' test_col_vals_gt( -#' columns = vars(value), +#' columns = value, #' value = 1500 #' ) #' ``` @@ -355,7 +355,7 @@ tt_string_info <- function(tbl) { #' tt_tbl_dims(tbl = small_table) %>% #' dplyr::filter(.param. == "columns") %>% #' test_col_vals_lt( -#' columns = vars(value), +#' columns = value, #' value = 10 #' ) #' ``` @@ -421,7 +421,7 @@ tt_tbl_dims <- function(tbl) { #' ```{r} #' tt_tbl_colnames(tbl = game_revenue) %>% #' test_col_vals_make_subset( -#' columns = vars(value), +#' columns = value, #' set = c("acquisition", "country") #' ) #' ``` @@ -436,7 +436,7 @@ tt_tbl_dims <- function(tbl) { #' tt_tbl_colnames() %>% #' tt_string_info() %>% #' test_col_vals_lt( -#' columns = vars(value), +#' columns = value, #' value = 15 #' ) #' ``` @@ -546,18 +546,7 @@ tt_time_shift <- function( time_shift = "0y 0m 0d 0H 0M 0S" ) { - # nocov start - - if (!requireNamespace("lubridate", quietly = TRUE)) { - - stop( - "The `tt_time_shift()` function requires the lubridate package:\n", - "* It can be installed with `install.packages(\"lubridate\")`.", - call. = FALSE - ) - } - - # nocov end + rlang::check_installed("lubridate", "to use the `tt_time_shift()` function.") # Determine whether the `tbl` object is acceptable here check_is_a_table_object(tbl = tbl) @@ -585,7 +574,7 @@ tt_time_shift <- function( tbl %>% dplyr::mutate( dplyr::across( - .cols = time_columns, + .cols = tidyselect::all_of(time_columns), .fns = ~ lubridate::days(n_days) + . ) ) @@ -596,7 +585,7 @@ tt_time_shift <- function( tbl %>% dplyr::mutate( dplyr::across( - .cols = time_columns, + .cols = tidyselect::all_of(time_columns), .fns = ~ time_shift + . ) ) @@ -645,7 +634,7 @@ tt_time_shift <- function( tbl %>% dplyr::mutate( dplyr::across( - .cols = time_columns, + .cols = tidyselect::all_of(time_columns), .fns = ~ fn_time(time_value * direction_val) + .) ) } @@ -760,18 +749,7 @@ tt_time_slice <- function( arrange = FALSE ) { - # nocov start - - if (!requireNamespace("lubridate", quietly = TRUE)) { - - stop( - "The `tt_time_shift()` function requires the lubridate package:\n", - "* It can be installed with `install.packages(\"lubridate\")`.", - call. = FALSE - ) - } - - # nocov end + rlang::check_installed("lubridate", "to use the `tt_time_slice()` function.") keep <- match.arg(keep) @@ -953,7 +931,7 @@ tt_time_slice <- function( #' keep = "right" #' ) %>% #' test_col_vals_lte( -#' columns = vars(session_duration), +#' columns = session_duration, #' value = get_tt_param( #' tbl = stats_tbl, #' param = "max", @@ -1058,9 +1036,9 @@ get_tt_param <- function( # Obtain the value from the `tbl` through a `select()`, `filter()`, `pull()` param_value <- tbl %>% - dplyr::select(.param., .env$column) %>% + dplyr::select(.param., tidyselect::all_of(column)) %>% dplyr::filter(.param. == .env$param) %>% - dplyr::pull(.env$column) + dplyr::pull(tidyselect::all_of(column)) } else if (tt_type == "tbl_dims") { diff --git a/R/tbl_from_db.R b/R/tbl_from_db.R index f6d1c6779..12e836074 100644 --- a/R/tbl_from_db.R +++ b/R/tbl_from_db.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -368,14 +368,7 @@ db_tbl <- function( dbname <- bq_project } - if (!requireNamespace("DBI", quietly = TRUE)) { - - stop( - "Accessing a database table requires the DBI package:\n", - "* It can be installed with `install.packages(\"DBI\")`.", - call. = FALSE - ) - } + rlang::check_installed("DBI", "to access a database table.") if (is.character(dbtype)) { @@ -523,72 +516,27 @@ db_tbl <- function( # nolint start RPostgres_driver <- function() { - - if (!requireNamespace("RPostgres", quietly = TRUE)) { - - stop( - "Accessing a PostgreSQL table requires the RPostgres package:\n", - "* It can be installed with `install.packages(\"RPostgres\")`.", - call. = FALSE - ) - } - + rlang::check_installed("RPostgres", "to access a PostgreSQL table.") RPostgres::Postgres() } RMySQL_driver <- function() { - - if (!requireNamespace("RMySQL", quietly = TRUE)) { - - stop( - "Accessing a MariaDB or MySQL table requires the RMySQL package:\n", - "* It can be installed with `install.packages(\"RMySQL\")`.", - call. = FALSE - ) - } - + rlang::check_installed("RMySQL", "to access a MariaDB or MySQL table.") RMySQL::MySQL() } bigrquery_driver <- function() { - - if (!requireNamespace("bigrquery", quietly = TRUE)) { - - stop( - "Accessing a BigQuery table requires the bigrquery package:\n", - "* It can be installed with `install.packages(\"bigrquery\")`.", - call. = FALSE - ) - } - + rlang::check_installed("bigquery", "to access a BigQuery table.") bigrquery::bigquery() } DuckDB_driver <- function() { - - if (!requireNamespace("duckdb", quietly = TRUE)) { - - stop( - "Accessing a DuckDB table requires the duckdb package:\n", - "* It can be installed with `install.packages(\"duckdb\")`.", - call. = FALSE - ) - } - + rlang::check_installed("duckdb", "to access a DuckDB table.") duckdb::duckdb() } RSQLite_driver <- function() { - - if (!requireNamespace("RSQLite", quietly = TRUE)) { - - stop( - "Accessing a SQLite table requires the RSQLite package:\n", - "* It can be installed with `install.packages(\"RSQLite\")`.", - call. = FALSE - ) - } - + rlang::check_installed("RSQLite", "to access a SQLite table.") RSQLite::SQLite() } diff --git a/R/tbl_from_file.R b/R/tbl_from_file.R index 7e96bae10..4829d8222 100644 --- a/R/tbl_from_file.R +++ b/R/tbl_from_file.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -135,7 +135,7 @@ #' col_types = "TDdcddlc" #' ) #' ) %>% -#' col_vals_gt(columns = vars(a), value = 0) +#' col_vals_gt(columns = a, value = 0) #' ``` #' #' All of the file-reading instructions are encapsulated in the `tbl` expression @@ -162,7 +162,7 @@ #' tbl_name = "small_table", #' label = "`file_tbl()` example.", #' ) %>% -#' col_vals_gt(columns = vars(a), value = 0) %>% +#' col_vals_gt(columns = a, value = 0) %>% #' interrogate() #' ``` #' @@ -285,13 +285,7 @@ file_tbl <- function( verify = TRUE ) { - if (!requireNamespace("readr", quietly = TRUE)) { - stop( - "Reading a table from a file requires the readr package:\n", - " * It can be installed with `install.packages(\"readr\")`.", - call. = FALSE - ) - } + rlang::check_installed("readr", "to read a table from a file.") file_extension <- tolower(tools::file_ext(file)) file_name <- basename(file) @@ -463,7 +457,7 @@ file_tbl <- function( #' # col_types = "TDdcddlc" #' # ) #' # ) %>% -#' # col_vals_gt(vars(a), 0) %>% +#' # col_vals_gt(a, 0) %>% #' # interrogate() #' #' # The `from_github()` helper function is @@ -529,13 +523,7 @@ from_github <- function( } else if (grepl("#", repo, fixed = TRUE)) { - if (!requireNamespace("jsonlite", quietly = TRUE)) { - stop( - "Getting a table from a file in a PR requires the jsonlite package:\n", - " * It can be installed with `install.packages(\"jsonlite\")`.", - call. = FALSE - ) - } + rlang::check_installed("jsonlite", "to get a table from a file in a PR.") pr_number <- unlist(strsplit(repo, "#"))[2] pulls_doc_tempfile <- tempfile(pattern = "pulls", fileext = ".json") diff --git a/R/tbl_match.R b/R/tbl_match.R index d9029772b..261453f73 100644 --- a/R/tbl_match.R +++ b/R/tbl_match.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -43,8 +43,8 @@ #' A table to compare against the target table. This can either be a table #' object, a table-prep formula. This can be a table object such as a data #' frame, a tibble, a `tbl_dbi` object, or a `tbl_spark` object. -#' Alternatively, a table-prep formula (`~
`) or a -#' function (`function()
`) can be used to lazily read in +#' Alternatively, a table-prep formula (`~ `) or a +#' function (`function() `) can be used to lazily read in #' the table at interrogation time. #' #' @return For the validation function, the return value is either a @@ -126,6 +126,19 @@ #' depending on the situation (the first produces a warning, the other #' `stop()`s). #' +#' @section Labels: +#' +#' `label` may be a single string or a character vector that matches the number +#' of expanded steps. `label` also supports `{glue}` syntax and exposes the +#' following dynamic variables contextualized to the current step: +#' +#' - `"{.step}"`: The validation step name +#' - `"{.seg_col}"`: The current segment's column name +#' - `"{.seg_val}"`: The current segment's value/group +#' +#' The glue context also supports ordinary expressions for further flexibility +#' (e.g., `"{toupper(.step)}"`) as long as they return a length-1 string. +#' #' @section Briefs: #' #' Want to describe this validation step in some detail? Keep in mind that this diff --git a/R/tbl_store.R b/R/tbl_store.R index ed772da17..21707cedc 100644 --- a/R/tbl_store.R +++ b/R/tbl_store.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -107,7 +107,7 @@ #' label = "An example that uses a table store.", #' actions = action_levels(warn_at = 0.10) #' ) %>% -#' col_exists(vars(date, date_time)) %>% +#' col_exists(c(date, date_time)) %>% #' write_yaml() #' ``` #' @@ -122,7 +122,7 @@ #' locale: en #' steps: #' - col_exists: -#' columns: vars(date, date_time) +#' columns: c(date, date_time) #' ``` #' #' Now, whenever the `sml_table_high` table needs to be validated, it can be @@ -620,7 +620,7 @@ add_to_name_list <- function( #' label = "`tbl_source()` example", #' actions = action_levels(warn_at = 0.10) #' ) %>% -#' col_exists(columns = vars(date, date_time)) %>% +#' col_exists(columns = c(date, date_time)) %>% #' interrogate() #' ``` #' diff --git a/R/utils-output.R b/R/utils-output.R index 83d38943d..6240ff211 100644 --- a/R/utils-output.R +++ b/R/utils-output.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -165,4 +165,8 @@ get_rds_tbl_info_files_tbl <- function(rds_tbl, tbl_name) { rds_tbl[rds_tbl$tbl_name == tbl_name, "information_files"][[1]][[1]] } +check_quarto <- function() { + Sys.getenv("QUARTO_BIN_PATH") != "" +} + # nocov end diff --git a/R/utils-profiling.R b/R/utils-profiling.R index 8ee3b72ad..fdb6dbb1a 100644 --- a/R/utils-profiling.R +++ b/R/utils-profiling.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html diff --git a/R/utils-specifications.R b/R/utils-specifications.R index 87975e590..be20e8578 100644 --- a/R/utils-specifications.R +++ b/R/utils-specifications.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html diff --git a/R/utils-tidyselect.R b/R/utils-tidyselect.R new file mode 100644 index 000000000..ae61a36d0 --- /dev/null +++ b/R/utils-tidyselect.R @@ -0,0 +1,142 @@ +resolve_columns <- function(x, var_expr, preconditions = NULL, ..., + call = rlang::caller_env()) { + + # If columns is just character vector, pass it through + if (rlang::is_character(rlang::quo_get_expr(var_expr))) { + return(rlang::eval_tidy(var_expr)) + } + + # Materialize table and apply preconditions for tidyselect + tbl <- apply_preconditions_for_cols(x, preconditions) + + # If tbl cannot (yet) materialize, don't attempt tidyselect and return early + if (rlang::is_error(tbl)) { + return(resolve_columns_notidyselect(var_expr, tbl, call = call)) + } + + # Attempt tidyselect + out <- tryCatch( + expr = resolve_columns_internal(tbl, var_expr, ..., call = call), + error = function(cnd) cnd + ) + + if (rlang::is_error(out)) { + # If error is a genuine evaluation error, throw that error + if (!is_subscript_error(out)) { + rlang::cnd_signal(rlang::error_cnd("resolve_eval_err", parent = out)) + } + # If not in validation-planning context (assert/expect/test), rethrow + if (is_a_table_object(x) || is_secret_agent(x)) { + rlang::cnd_signal(out) + } else { + # Else (mid-planning): grab columns attempted to subset + fail <- out$i %||% out$parent$i + # If failure is due to scoping a bad object in the env, re-throw error + if (!is.character(fail) && !rlang::is_integerish(fail)) { + rlang::cnd_signal(out) + } + success <- resolve_columns_possible(tbl, var_expr) + out <- c(success, fail) %||% NA_character_ + } + } + + out + +} + +resolve_columns_notidyselect <- function(var_expr, parent, call) { + # Error if attempting to tidyselect on a lazy tbl that cannot materialize + var_str <- rlang::expr_deparse(rlang::quo_get_expr(var_expr)) + if (any(sapply(names(tidyselect::vars_select_helpers), grepl, var_str))) { + rlang::abort( + "Cannot use tidyselect helpers for an undefined lazy tbl.", + parent = parent, + call = call + ) + } + + # Force column selection to character vector + if (rlang::quo_is_symbol(var_expr)) { + var_expr <- rlang::as_name(var_expr) + } else if (rlang::quo_is_call(var_expr, c("vars", "c"))) { + var_expr <- rlang::quo_set_expr(var_expr, vars_to_c(var_expr)) + } + rlang::eval_tidy(var_expr) +} + +# Apply the preconditions function and resolve to data frame for tidyselect +apply_preconditions_for_cols <- function(x, preconditions) { + # Extract tbl + tbl <- if (is_ptblank_agent(x)) { + tryCatch(get_tbl_object(x), error = function(cnd) cnd) + } else if (is_a_table_object(x)) { + x + } + # Apply preconditions + if (!rlang::is_error(tbl) && !is.null(preconditions)) { + tbl <- apply_preconditions(tbl = tbl, preconditions = preconditions) + } + tbl +} + +# Determines whether the error from a tidyselect expression is from attempting +# to select a non-existing column (i.e., a "subscript error") +is_subscript_error <- function(cnd) { + is.null(cnd$parent) || inherits(cnd$parent, "vctrs_error_subscript") +} + +# If selection gets short-circuited by error, re-run with `strict = FALSE` +# to safely get the possible column selections +resolve_columns_possible <- function(tbl, var_expr) { + success <- tryCatch( + names(tidyselect::eval_select(var_expr, tbl, + strict = FALSE, allow_empty = FALSE)), + error = function(cnd) NULL + ) + success +} + +# Resolve column selections to integer +resolve_columns_internal <- function(tbl, var_expr, ..., call) { + + # Return NA if the expr is NULL + if (rlang::quo_is_null(var_expr)) { + return(NA_character_) + } + + # Special case `serially()`: just deparse elements and bypass tidyselect + if (rlang::is_empty(tbl)) { + var_expr <- rlang::quo_get_expr(var_expr) + if (rlang::is_symbol(var_expr) || rlang::is_scalar_character(var_expr)) { + column <- rlang::as_name(var_expr) + } else { + cols <- rlang::call_args(var_expr) + column <- vapply(cols, rlang::as_name, character(1), USE.NAMES = FALSE) + } + return(column) + } + # Special case `vars()`-expression for backwards compatibility + if (rlang::quo_is_call(var_expr, "vars")) { + var_expr <- rlang::quo_set_expr(var_expr, vars_to_c(var_expr)) + } + + # Proceed with tidyselect + column <- tidyselect::eval_select(var_expr, tbl, error_call = call, ...) + column <- names(column) + + if (length(column) < 1) { + column <- NA_character_ + } + + column +} + +# Convert to the idiomatic `c()`-expr before passing off to tidyselect +# + ensure that vars() always scopes symbols to data (vars(a) -> c("a")) +vars_to_c <- function(var_expr) { + var_args <- lapply(rlang::call_args(var_expr), function(var_arg) { + if (rlang::is_symbol(var_arg)) rlang::as_name(var_arg) else var_arg + }) + c_expr <- rlang::call2("c", !!!var_args) + c_expr +} diff --git a/R/utils-translations.R b/R/utils-translations.R index b960f2c76..51fa07a50 100644 --- a/R/utils-translations.R +++ b/R/utils-translations.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html diff --git a/R/utils.R b/R/utils.R index 68fa851ee..a7e1f9dc4 100644 --- a/R/utils.R +++ b/R/utils.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -148,15 +148,8 @@ get_next_validation_set_row <- function(agent) { step } -exported_tidyselect_fns <- function() { - c("starts_with", "ends_with", "contains", "matches", "everything") -} - -uses_tidyselect <- function(expr_text) { - grepl( - "^starts_with\\(|^ends_with\\(|^contains\\(|^matches\\(|^everything\\(", - expr_text - ) +tidyselect_helpers <- function() { + names(tidyselect::vars_select_helpers) } get_assertion_type_at_idx <- function(agent, idx) { @@ -164,15 +157,29 @@ get_assertion_type_at_idx <- function(agent, idx) { } get_column_as_sym_at_idx <- function(agent, idx) { - rlang::sym( - agent$validation_set[[idx, "column"]] %>% - unlist() %>% - gsub("'", "", .) - ) + column <- unlist(agent$validation_set[[idx, "column"]]) + if (!is.na(column)) { + column <- rlang::sym(gsub("'", "", column)) + } + column } get_values_at_idx <- function(agent, idx) { - agent$validation_set[[idx, "values"]] %>% unlist(recursive = FALSE) + + # Get list-column element (`values` is always a length-1 list) + values <- agent$validation_set[[idx, "values"]] + + # Expressions (via `col_vals_expr()`) and functions (via `specially()`) + # can get the old `unlist()` treatment + if (rlang::is_expression(values[[1]]) || rlang::is_function(values[[1]])) { + values <- unlist(values, recursive = FALSE) + } else { + # In other cases (e.g., `values`, `left`, `right`), flatten with subsetting + # to preserve class + values <- values[[1]] + } + + values } get_column_na_pass_at_idx <- function(agent, idx) { @@ -206,7 +213,7 @@ materialize_table <- function(tbl, check = TRUE) { stop( "The `tbl` object must either be a table, a function, or a formula.\n", "* A table-prep formula can be used (with the expression on the RHS).\n", - "* A function can be made with `function()` {
}.", + "* A function can be made with `function()` {}.", call. = FALSE ) } @@ -218,75 +225,45 @@ materialize_table <- function(tbl, check = TRUE) { tbl } -resolve_expr_to_cols <- function(tbl, var_expr) { - - var_expr <- enquo(var_expr) - - if ((var_expr %>% rlang::get_expr() %>% as.character())[1] == "vars") { - - cols <- (var_expr %>% rlang::get_expr() %>% as.character())[-1] - return(cols) +as_columns_expr <- function(columns) { + columns_expr <- gsub("^\"|\"$", "", rlang::as_label(columns)) + # Treat NULL and missing `columns` as the same + if (columns_expr == "") { + columns_expr <- "NULL" } - - tidyselect::vars_select(.vars = colnames(tbl), {{ var_expr }}) %>% unname() + columns_expr } -resolve_columns <- function(x, var_expr, preconditions) { - - # If getting a character vector as `var_expr`, simply return the vector - # since this should already be a vector of column names and it's not necessary - # to resolve this against the target table - if (is.character(var_expr)) { - return(var_expr) +is_secret_agent <- function(x) { + is_ptblank_agent(x) && (x$label == "::QUIET::") +} + +resolve_label <- function(label, columns = "", segments = "") { + n_columns <- length(columns) + n_segments <- length(segments) + n_combinations <- n_columns * n_segments + # If label is NULL, turn into NA for vector storage + if (is.null(label)) { + label <- NA_character_ } - - # nocov start - - # Return an empty character vector if the expr is NULL - if (inherits(var_expr, "quosure") && - var_expr %>% rlang::as_label() == "NULL") { - - return(character(NA_character_)) + # If length-1, match length of col-x-seg combination + if (length(label) == 1) { + label <- rep_len(label, n_combinations) } - - # nocov end - - # Get the column names from a non-NULL, non-character expression - if (is.null(preconditions)) { - - if (inherits(x, c("data.frame", "tbl_df", "tbl_dbi"))) { - - column <- resolve_expr_to_cols(tbl = x, var_expr = !!var_expr) - - } else if (inherits(x, ("ptblank_agent"))) { - - tbl <- get_tbl_object(agent = x) - column <- resolve_expr_to_cols(tbl = tbl, var_expr = !!var_expr) - } - - } else { - - if (inherits(x, c("data.frame", "tbl_df", "tbl_dbi"))) { - - tbl <- apply_preconditions(tbl = x, preconditions = preconditions) - - column <- resolve_expr_to_cols(tbl = tbl, var_expr = !!var_expr) - - } else if (inherits(x, ("ptblank_agent"))) { - - tbl <- get_tbl_object(agent = x) - - tbl <- apply_preconditions(tbl = tbl, preconditions = preconditions) - - column <- resolve_expr_to_cols(tbl = tbl, var_expr = !!var_expr) - } + # Check for length match + if (length(label) != n_combinations) { + rlang::abort(paste0("`label` must be length 1 or ", n_combinations, + ", not ", length(label))) } - - if (length(column) < 1) { - column <- NA_character_ + # Create a columns * segments matrix of the (recycled) label vector + # - Fill by row to preserve order (for loops iterate the j before the i) + out <- matrix(label, nrow = n_columns, ncol = n_segments, byrow = TRUE) + # If missing columns and/or segments, collapse to vector/scalar + if (missing(columns) || missing(segments)) { + out <- as.vector(out) } - - column + # A matrix/vector subsettable via `out[col]`, `out[seg]`, or `out[col,seg]` + out } #' The `resolve_segments()` function works with input from the `segments` @@ -322,7 +299,7 @@ resolve_segments <- function(x, seg_expr, preconditions) { } segments_list <- list() - + # Process each `seg_expr` element for (i in seq_along(seg_expr)) { @@ -344,7 +321,7 @@ resolve_segments <- function(x, seg_expr, preconditions) { col_seg_vals <- tbl %>% - dplyr::select(.env$column_name) %>% + dplyr::select(tidyselect::all_of(column_name)) %>% dplyr::distinct() %>% dplyr::pull() @@ -578,6 +555,64 @@ get_threshold_type <- function(threshold) { } } +# nocov start + +all_data_vars <- function(x, data_cols) { + deparsed <- paste(deparse(x, width.cutoff = 500L), collapse = " ") + reparsed <- parse(text = deparsed, keep.source = TRUE) + x <- utils::getParseData(reparsed) + if (is.null(x)) return(NA_character_) + + .data_vars <- pronoun_vars(x, ".data") + .env_vars <- pronoun_vars(x, ".env") + + bare_syms <- x[ + x$token == "SYMBOL" & + !x$text %in% c(".data", ".env") & + !x$id %in% c(names(.data_vars), names(.env_vars)), + c("id", "text") + ] + if (nrow(bare_syms) == 0) { + all_cols <- unique(.data_vars) + } else { + unscoped_vars <- bare_syms$text + names(unscoped_vars) <- bare_syms$id + all_cols <- c(unscoped_vars, .data_vars) + all_cols <- all_cols[order(as.integer(names(all_cols)))] + all_cols <- unique(all_cols) + } + + all_cols <- all_cols[all_cols %in% data_cols] + + if (length(all_cols) == 0) { + NA_character_ + } else { + sort(all_cols) + } + +} + +pronoun_vars <- function(x, pronoun = c(".data", ".env")) { + pronoun <- match.arg(pronoun) + if (!any(x$text == pronoun)) return(character(0)) + conseq_pronoun <- rle(x$text == pronoun) + x$dotdata <- rep(seq_along(conseq_pronoun$values), conseq_pronoun$lengths) + x$dotdata <- ifelse(x$text == pronoun, x$dotdata + 1, x$dotdata) + dotdata <- lapply(split(x, x$dotdata), function(g) { + if (g$text[1] == pronoun && g$token[3] %in% c("'$'", "LBB")) { + var <- g$text[4] + names(var) <- g$id[4] + if (g$token[4] == "STR_CONST") gsub('"', "", var) else var + } else { + character(0) + } + }) + allvars <- unlist(unname(dotdata)) + allvars +} + +# nocov end + all_validations_fns_vec <- function() { c( @@ -692,19 +727,18 @@ get_tbl_dbi_src_details <- function(tbl) { get_r_column_names_types <- function(tbl) { suppressWarnings( - column_names_types <- + column_header <- tbl %>% utils::head(1) %>% - dplyr::collect() %>% - vapply( - FUN.VALUE = character(1), - FUN = function(x) class(x)[1] - ) + dplyr::collect() ) + column_names_types <- + vapply(column_header, function(x) class(x)[1], character(1)) list( col_names = names(column_names_types), - r_col_types = unname(unlist(column_names_types)) + r_col_types = unname(unlist(column_names_types)), + col_ptypes = utils::head(column_header, 0) ) } @@ -759,7 +793,8 @@ get_tbl_information_df <- function(tbl) { db_tbl_name = NA_character_, col_names = r_column_names_types$col_names, r_col_types = r_column_names_types$r_col_types, - db_col_types = NA_character_ + db_col_types = NA_character_, + col_ptypes = r_column_names_types$col_ptypes ) } @@ -783,7 +818,8 @@ get_tbl_information_spark <- function(tbl) { db_tbl_name = NA_character_, col_names = r_column_names_types$col_names, r_col_types = r_column_names_types$r_col_types, - db_col_types = db_col_types + db_col_types = db_col_types, + col_ptypes = r_column_names_types$col_ptypes ) } @@ -927,7 +963,7 @@ get_tbl_information_dbi <- function(tbl) { DBI::dbDataType( tbl_connection, tbl %>% - dplyr::select(x) %>% + dplyr::select(tidyselect::all_of(x)) %>% utils::head(1) %>% dplyr::collect() %>% dplyr::pull(x) @@ -964,7 +1000,8 @@ get_tbl_information_dbi <- function(tbl) { db_tbl_name = db_tbl_name, col_names = r_column_names_types$col_names, r_col_types = r_column_names_types$r_col_types, - db_col_types = db_col_types + db_col_types = db_col_types, + col_ptypes = r_column_names_types$col_ptypes ) } @@ -1008,7 +1045,8 @@ get_tbl_information_arrow <- function(tbl) { db_tbl_name = NA_character_, col_names = col_names, r_col_types = r_col_types, - db_col_types = db_col_types + db_col_types = db_col_types, + col_ptypes = dplyr::collect(utils::head(tbl, 0)) ) } @@ -1183,11 +1221,16 @@ pb_str_catalog <- function( oxford = TRUE, as_code = TRUE, quot_str = NULL, + na_rm = FALSE, lang = NULL ) { if (is.null(lang)) lang <- "en" + if (na_rm) { + item_vector <- item_vector[!is.na(item_vector)] + } + item_count <- length(item_vector) # If there is nothing in the `item_vector`, return @@ -1568,8 +1611,8 @@ cli_bullet_msg <- function( msg <- glue::glue_collapse(msg, "\n") msg <- glue::glue(msg, .envir = .envir) - if (!is.null(color) && requireNamespace("crayon", quietly = TRUE)) { - color_style <- crayon::make_style(color) + if (!is.null(color)) { + color_style <- cli::make_ansi_style(color) bullet <- color_style(bullet) } @@ -1590,16 +1633,14 @@ print_time <- function(time_diff_s) { if (time_diff_s < 1) { return("") - } else { - return( - paste0( - " {.time_taken (", - round(time_diff_s, 1) %>% - formatC(format = "f", drop0trailing = FALSE, digits = 1), - " s)}" - ) - ) } + + paste0( + " {.time_taken (", + round(time_diff_s, 1) %>% + formatC(format = "f", drop0trailing = FALSE, digits = 1), + " s)}" + ) } gt_missing <- @@ -1646,3 +1687,12 @@ pb_get_image_tag <- function(file, dir = "images") { "style=\"width:100\\%;\">" ) } + +deparse_expr <- function(expr, collapse = " ", ...) { + if (rlang::is_scalar_atomic(expr)) { + as.character(expr) + } else { + deparsed <- paste(deparse(expr, ...), collapse = collapse) + paste("", deparsed) + } +} diff --git a/R/validate_rmd.R b/R/validate_rmd.R index acd409ed9..62addb9ea 100644 --- a/R/validate_rmd.R +++ b/R/validate_rmd.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -116,14 +116,7 @@ validate_rmd <- function( if (test_options$perform_logging) { - if (!requireNamespace("log4r", quietly = TRUE)) { - - stop( - "Using the `log4r_step()` function requires the log4r package:\n", - "* It can be installed with `install.packages(\"log4r\")`.", - call. = FALSE - ) - } + rlang::check_installed("log4r", "to use the `log4r_step()` function.") # Create a log4r `logger` object and store it in `test_options` test_options$logger <- @@ -641,7 +634,7 @@ knitr_chunk_hook <- function(x, options) { #' @export stop_if_not <- function(...) { - res <- list(...) + res <- rlang::list2(...) n <- length(res) @@ -681,8 +674,7 @@ stop_if_not <- function(...) { return(TRUE) - } else { - - return() } + + NULL } diff --git a/R/write_testthat_file.R b/R/write_testthat_file.R index dec9e6fb7..eae53a986 100644 --- a/R/write_testthat_file.R +++ b/R/write_testthat_file.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -79,7 +79,7 @@ #' #' expect_col_exists( #' tbl, -#' columns = vars(date_time), +#' columns = date_time, #' threshold = 1 #' ) #' }) @@ -88,7 +88,7 @@ #' #' expect_col_vals_lte( #' tbl, -#' columns = vars(c), +#' columns = c, #' value = 5, #' threshold = 0.25 #' ) @@ -106,8 +106,8 @@ #' tbl = ~ small_table, #' actions = action_levels(stop_at = 0.25) #' ) %>% -#' col_exists(vars(date_time)) %>% -#' col_vals_lte(vars(c), value = 5) +#' col_exists(date_time) %>% +#' col_vals_lte(c, value = 5) #' #' write_testthat_file( #' agent = agent, @@ -206,13 +206,13 @@ #' label = "An example.", #' actions = al #' ) %>% -#' col_exists(vars(date, date_time)) %>% +#' col_exists(c(date, date_time)) %>% #' col_vals_regex( -#' vars(b), +#' b, #' regex = "[0-9]-[a-z]{3}-[0-9]{3}" #' ) %>% -#' col_vals_gt(vars(d), value = 100) %>% -#' col_vals_lte(vars(c), value = 5) %>% +#' col_vals_gt(d, value = 100) %>% +#' col_vals_lte(c, value = 5) %>% #' interrogate() #' ``` #' @@ -245,7 +245,7 @@ #' #' expect_col_exists( #' tbl, -#' columns = vars(date), +#' columns = date, #' threshold = 1 #' ) #' }) @@ -254,7 +254,7 @@ #' #' expect_col_exists( #' tbl, -#' columns = vars(date_time), +#' columns = date_time, #' threshold = 1 #' ) #' }) @@ -264,7 +264,7 @@ #' #' expect_col_vals_regex( #' tbl, -#' columns = vars(b), +#' columns = b, #' regex = "[0-9]-[a-z]{3}-[0-9]{3}", #' threshold = 0.25 #' ) @@ -274,7 +274,7 @@ #' #' expect_col_vals_gt( #' tbl, -#' columns = vars(d), +#' columns = d, #' value = 100, #' threshold = 0.25 #' ) @@ -284,7 +284,7 @@ #' #' expect_col_vals_lte( #' tbl, -#' columns = vars(c), +#' columns = c, #' value = 5, #' threshold = 0.25 #' ) diff --git a/R/yaml_exec.R b/R/yaml_exec.R index 2222d6aba..777d61970 100644 --- a/R/yaml_exec.R +++ b/R/yaml_exec.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html diff --git a/R/yaml_read_agent.R b/R/yaml_read_agent.R index 8718ff36f..22042952e 100644 --- a/R/yaml_read_agent.R +++ b/R/yaml_read_agent.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -304,14 +304,14 @@ yaml_agent_interrogate <- function( #' notify_at = 0.35 #' ) #' ) %>% -#' col_exists(columns = vars(date, date_time)) %>% +#' col_exists(columns = c(date, date_time)) %>% #' col_vals_regex( -#' columns = vars(b), +#' columns = b, #' regex = "[0-9]-[a-z]{3}-[0-9]{3}" #' ) %>% #' rows_distinct() %>% -#' col_vals_gt(columns = vars(d), value = 100) %>% -#' col_vals_lte(columns = vars(c), value = 5) +#' col_vals_gt(columns = d, value = 100) %>% +#' col_vals_lte(columns = c, value = 5) #' ``` #' #' The agent can be written to a **pointblank** YAML file with [yaml_write()]. @@ -357,19 +357,19 @@ yaml_agent_interrogate <- function( #' label = "A simple example with the `small_table`." #' ) %>% #' col_exists( -#' columns = vars(date, date_time) +#' columns = c(date, date_time) #' ) %>% #' col_vals_regex( -#' columns = vars(b), +#' columns = b, #' regex = "[0-9]-[a-z]{3}-[0-9]{3}" #' ) %>% #' rows_distinct() %>% #' col_vals_gt( -#' columns = vars(d), +#' columns = d, #' value = 100 #' ) %>% #' col_vals_lte( -#' columns = vars(c), +#' columns = c, #' value = 5 #' ) #' ``` @@ -539,7 +539,7 @@ make_validation_steps <- function(steps) { tidyselect_regex <- paste0( "^(", - paste(c("vars", exported_tidyselect_fns()), collapse = "|"), + paste(c("vars", "c", tidyselect_helpers()), collapse = "|"), ")\\(.*?\\)$" ) diff --git a/R/yaml_read_informant.R b/R/yaml_read_informant.R index 3f40ad3b9..ac72714c2 100644 --- a/R/yaml_read_informant.R +++ b/R/yaml_read_informant.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html diff --git a/R/yaml_write.R b/R/yaml_write.R index f5668d1e3..e8479979e 100644 --- a/R/yaml_write.R +++ b/R/yaml_write.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html @@ -81,9 +81,9 @@ #' `scalar` // *default:* `FALSE` #' #' Should the written validation expressions for an *agent* be expanded such -#' that **tidyselect** and [vars()] expressions for columns are evaluated, -#' yielding a validation function per column? By default, this is `FALSE` so -#' expressions as written will be retained in the YAML representation. +#' that **tidyselect** expressions for columns are evaluated, yielding a +#' validation function per column? By default, this is `FALSE` so expressions +#' as written will be retained in the YAML representation. #' #' @param quiet *Inform (or not) upon file writing* #' @@ -139,14 +139,14 @@ #' ```r #' agent <- #' agent %>% -#' col_exists(columns = vars(date, date_time)) %>% +#' col_exists(columns = c(date, date_time)) %>% #' col_vals_regex( -#' columns = vars(b), +#' columns = b, #' regex = "[0-9]-[a-z]{3}-[0-9]{3}" #' ) %>% #' rows_distinct() %>% -#' col_vals_gt(columns = vars(d), value = 100) %>% -#' col_vals_lte(columns = vars(c), value = 5) +#' col_vals_gt(columns = d, value = 100) %>% +#' col_vals_lte(columns = c, value = 5) #' ``` #' #' The agent can be written to a **pointblank**-readable YAML file with the @@ -178,17 +178,17 @@ #' notify_fraction: 0.35 #' steps: #' - col_exists: -#' columns: vars(date, date_time) +#' columns: c(date, date_time) #' - col_vals_regex: -#' columns: vars(b) +#' columns: c(b) #' regex: '[0-9]-[a-z]{3}-[0-9]{3}' #' - rows_distinct: #' columns: ~ #' - col_vals_gt: -#' columns: vars(d) +#' columns: c(d) #' value: 100.0 #' - col_vals_lte: -#' columns: vars(c) +#' columns: c(c) #' value: 5.0 #' ``` #' @@ -282,7 +282,7 @@ #' informant <- #' informant %>% #' info_columns( -#' columns = vars(a), +#' columns = a, #' info = "In the range of 1 to 10. (SIMPLE)" #' ) %>% #' info_columns( @@ -290,7 +290,7 @@ #' info = "Time-based values (e.g., `Sys.time()`)." #' ) %>% #' info_columns( -#' columns = "date", +#' columns = date, #' info = "The date part of `date_time`. (CALC)" #' ) #' ``` @@ -576,10 +576,9 @@ yaml_write <- function( #' @param path An optional path to the YAML file (combined with `filename`). #' #' @param expanded Should the written validation expressions for an *agent* be -#' expanded such that **tidyselect** and [vars()] expressions for columns are -#' evaluated, yielding a validation function per column? By default, this is -#' `FALSE` so expressions as written will be retained in the YAML -#' representation. +#' expanded such that **tidyselect** expressions for columns are evaluated, +#' yielding a validation function per column? By default, this is `FALSE` +#' so expressions as written will be retained in the YAML representation. #' #' @return Nothing is returned. Instead, text is printed to the console. #' @@ -649,56 +648,47 @@ yaml_agent_string <- function( expanded = FALSE ) { - if (is.null(agent) && is.null(filename)) { - stop( - "An `agent` object or a `filename` for a YAML file must be specified.", - call. = FALSE - ) - } - - if (!is.null(agent) && !is.null(filename)) { - stop( - "Only `agent` or `filename` should be specified (not both).", - call. = FALSE - ) - } - - if (!is.null(agent)) { - - # Display the agent's YAML as a nicely formatted string by - # generating the YAML (`as_agent_yaml_list() %>% as.yaml()`) and - # then emitting it to the console via `message()` - message( - as_agent_yaml_list( - agent = agent, - expanded = expanded - ) %>% - yaml::as.yaml( - handlers = list( - logical = function(x) { - result <- ifelse(x, "true", "false") - class(result) <- "verbatim" - result - } + switch( + rlang::check_exclusive(agent, filename), + agent = { + # Display the agent's YAML as a nicely formatted string by + # generating the YAML (`as_agent_yaml_list() %>% as.yaml()`) and + # then emitting it to the console via `message()` + message( + as_agent_yaml_list( + agent = agent, + expanded = expanded + ) %>% + yaml::as.yaml( + handlers = list( + logical = function(x) { + result <- ifelse(x, "true", "false") + class(result) <- "verbatim" + result + } + ) ) - ) - ) - - } else { - - if (!is.null(path)) { - filename <- file.path(path, filename) + ) + }, + filename = { + # Display the agent's YAML as a nicely formatted string by + # reading the YAML file specified by `file` (and perhaps `path`) + # and then emitting it to the console via `message()` + if (!is.null(path)) { + filename <- file.path(path, filename) + } + message( + readLines(filename) %>% + paste(collapse = "\n") + ) } - - # Display the agent's YAML as a nicely formatted string by - # reading the YAML file specified by `file` (and perhaps `path`) - # and then emitting it to the console via `message()` - message(readLines(filename) %>% paste(collapse = "\n")) - } + ) + } -as_vars_fn <- function(columns) { - paste0("vars(", columns, ")") +as_c_fn <- function(columns) { + columns <- strsplit(unlist(columns), ", ")[[1]] + paste0("c(", paste0('"', columns, '"', collapse = ", "), ")") } as_list_preconditions <- function(preconditions) { @@ -714,9 +704,9 @@ as_list_preconditions <- function(preconditions) { gsub("function (x) \n{", "function(x) {", ., fixed = TRUE) ) - } else { - return(as.character(preconditions)) } + + as.character(preconditions) } as_list_segments <- function(segments) { @@ -751,9 +741,9 @@ as_list_active <- function(active) { if (is.logical(active[[1]])) { return(active[[1]]) - } else { - return(as.character(active)) } + + as.character(active) } to_list_action_levels <- function(actions) { @@ -1038,6 +1028,14 @@ as_agent_yaml_list <- function(agent, expanded) { dplyr::filter(dplyr::row_number() == 1) %>% dplyr::ungroup() %>% dplyr::rename(i = i_o) + + # Temporary conversion of `$label` to list-column + step_labels <- split(agent$validation_set$label, agent$validation_set$i_o) + step_labels_collapsed <- lapply(step_labels, function(label) { + # Collapse `label` when possible + if (all(is.na(label)) || all(label == label[1])) label[1] else label + }) + agent_validation_set$label <- unname(step_labels_collapsed) } else { @@ -1329,16 +1327,16 @@ as_agent_yaml_list <- function(agent, expanded) { } else if (validation_fn %in% c("rows_distinct", "rows_complete")) { - if (is.na(step_list$column[[1]][[1]])) { - vars_cols <- NULL - } else { - vars_cols <- as_vars_fn(step_list$column[[1]]) - } + column_text <- + get_column_text( + step_list = step_list, + expanded = expanded + ) lst_step <- list( validation_fn = list( - columns = vars_cols, + columns = column_text, preconditions = as_list_preconditions(step_list$preconditions), segments = as_list_segments(step_list$seg_expr), actions = as_action_levels( @@ -1526,6 +1524,9 @@ as_agent_yaml_list <- function(agent, expanded) { # Remove list elements that are representative of defaults lst_step <- prune_lst_step(lst_step) + + # Unlist labels as character vector/scalar + lst_step$validation_fn$label <- lst_step$validation_fn$label[[1]] # Set the top level list-element name to that of # the validation function @@ -1554,15 +1555,18 @@ get_column_text <- function(step_list, expanded) { if (!is.na(step_list$column[[1]]) && step_list$column[[1]] == step_list$columns_expr) { - column_text <- as_vars_fn(step_list$column[[1]]) + column_text <- as_c_fn(step_list$column[[1]]) } else { column_text <- step_list$columns_expr } + # Strip tidyselect namespacing for leaner yaml writing + column_text <- gsub("\\btidyselect::", "", column_text) + } else { - column_text <- as_vars_fn(columns = step_list$column[[1]]) + column_text <- as_c_fn(columns = step_list$column[[1]]) } column_text @@ -1609,6 +1613,9 @@ as_informant_yaml_list <- function(informant) { lst_locale <- list(locale = informant$locale) } + # Hide private field + metadata <- informant$metadata[names(informant$metadata) != "_private"] + c( type = "informant", # YAML type: `informant` lst_read_fn, # table-prep formula (stored in key `tbl`) @@ -1617,7 +1624,7 @@ as_informant_yaml_list <- function(informant) { lst_lang, # informant language lst_locale, # informant locale lst_meta_snippets, # informant metadata snippet statements - informant$metadata # informant metadata entries + metadata # informant metadata entries ) } diff --git a/R/zzz.R b/R/zzz.R index 4859d1363..4ff9393e4 100644 --- a/R/zzz.R +++ b/R/zzz.R @@ -11,7 +11,7 @@ # # This file is part of the 'rstudio/pointblank' project. # -# Copyright (c) 2017-2023 pointblank authors +# Copyright (c) 2017-2024 pointblank authors # # For full copyright and license information, please look at # https://rstudio.github.io/pointblank/LICENSE.html diff --git a/README.md b/README.md index 081f63d69..79020cd95 100644 --- a/README.md +++ b/README.md @@ -4,21 +4,19 @@ -CRAN status -License: MIT -R build status -Linting -Coverage status - -Best Practices -The project has reached a stable, usable state and is being actively developed. -Monthly Downloads -Total Downloads - +[![CRAN status](https://www.r-pkg.org/badges/version/pointblank)](https://CRAN.R-project.org/package=pointblank) +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/license/mit/) +[![R-CMD-check](https://github.com/rstudio/pointblank/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/rstudio/pointblank/actions/workflows/R-CMD-check.yaml) +[![Linting](https://github.com/rstudio/pointblank/actions/workflows/lint.yaml/badge.svg)](https://github.com/rstudio/pointblank/actions/workflows/lint.yaml) +[![Codecov test coverage](https://codecov.io/gh/rstudio/pointblank/graph/badge.svg)](https://app.codecov.io/gh/rstudio/pointblank) +[![Best Practices](https://bestpractices.coreinfrastructure.org/projects/4310/badge)](https://bestpractices.coreinfrastructure.org/projects/4310) +[![The project has reached a stable, usable state and is being actively developed.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active) +[![Monthly Downloads](https://cranlogs.r-pkg.org/badges/pointblank)](https://CRAN.R-project.org/package=pointblank) +[![Total Downloads](https://cranlogs.r-pkg.org/badges/grand-total/pointblank)](https://CRAN.R-project.org/package=pointblank) [![Posit Cloud](https://img.shields.io/badge/Posit%20Cloud-pointblank%20Test%20Drive-blue?style=social&logo=rstudio&logoColor=75AADB)](https://rstudio.cloud/project/3411822) - -Contributor Covenant +[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-v2.1%20adopted-ff69b4.svg)](https://www.contributor-covenant.org/version/2/1/code_of_conduct.html) +

@@ -48,7 +46,7 @@ metadata updated so that this important documentation doesn't become stale. ## TABLE VALIDATIONS WITH AN AGENT AND DATA QUALITY REPORTING Data validation can be carried out in *Data Quality Reporting* workflow, -ultimately resulting in the production of of a data quality analysis report. +ultimately resulting in the production of a data quality analysis report. This is most useful in a non-interactive mode where data quality for database tables and on-disk data files must be periodically checked. The **pointblank** *agent* is given a collection of validation functions to define validation @@ -141,14 +139,14 @@ dplyr::tibble( b = c(6, 1, 0, 6, 0, 7) ) %>% col_vals_between( - vars(a), 1, 9, + a, 1, 9, na_pass = TRUE ) %>% col_vals_lt( - vars(c), 12, + c, 12, preconditions = ~ . %>% dplyr::mutate(c = a + b) ) %>% - col_is_numeric(vars(a, b)) + col_is_numeric(c(a, b)) ``` Error: Exceedance of failed test units where values in `c` should have been < `12`. @@ -169,17 +167,17 @@ dplyr::tibble( b = c(6, 1, 0, 6, 0, 7) ) %>% col_vals_between( - vars(a), 1, 9, + a, 1, 9, na_pass = TRUE, actions = warn_on_fail() ) %>% col_vals_lt( - vars(c), 12, + c, 12, preconditions = ~ . %>% dplyr::mutate(c = a + b), actions = warn_on_fail() ) %>% col_is_numeric( - vars(a, b), + c(a, b), actions = warn_on_fail() ) ``` @@ -267,19 +265,19 @@ informant <- `README` pages. Column names are `a` and `b`. ((Cool stuff))" ) %>% info_columns( - columns = "a", + columns = a, info = "This column has an `NA` value. [[Watch out!]]<>" ) %>% info_columns( - columns = "a", + columns = a, info = "Mean value is `{a_mean}`." ) %>% info_columns( - columns = "b", + columns = b, info = "Like column `a`. The lowest value is `{b_lowest}`." ) %>% info_columns( - columns = "b", + columns = b, info = "The highest value is `{b_highest}`." ) %>% info_snippet( diff --git a/data-raw/translations_source.yml b/data-raw/translations_source.yml index 263d135ce..c1baa01ab 100644 --- a/data-raw/translations_source.yml +++ b/data-raw/translations_source.yml @@ -1782,19 +1782,19 @@ table_scan: sv: "Andra värden" nl: "Andere waarden" footer_text_fragment: - en: "Table scan generated with pointblank." - fr: "Scan de tableau généré avec pointblank." - de: "Mit pointblank generierter Scan der Tabelle." - it: "Scansione della tabella generata con pointblank." - es: "Escaneo de Tabla generado con pointblank." - pt: "Examen da tabela gerada com pointblank." - tr: "pointblank ile oluşturulan tablo taraması." - zh: "通过 pointblank建立表扫描。" - ru: "Сканирование таблиц, сгенерированное с помощью pointblank." - pl: "Skan tabeli wygenerowany za pomoca pointblank." - da: "Scan af tabel genereret med pointblank." - sv: "Genomsökning av tabellen genereras med pointblank." - nl: "Scan van tabel gegenereerd met pointblank." + en: "Table scan generated with pointblank." + fr: "Scan de tableau généré avec pointblank." + de: "Mit pointblank generierter Scan der Tabelle." + it: "Scansione della tabella generata con pointblank." + es: "Escaneo de Tabla generado con pointblank." + pt: "Examen da tabela gerada com pointblank." + tr: "pointblank ile oluşturulan tablo taraması." + zh: "通过 pointblank建立表扫描。" + ru: "Сканирование таблиц, сгенерированное с помощью pointblank." + pl: "Skan tabeli wygenerowany za pomoca pointblank." + da: "Scan af tabel genereret med pointblank." + sv: "Genomsökning av tabellen genereras med pointblank." + nl: "Scan van tabel gegenereerd met pointblank." multiagent_report: pointblank_multiagent_title_text: en: "Pointblank Validation Series" diff --git a/images/pointblank_hex_logo.png b/images/pointblank_hex_logo.png new file mode 100644 index 000000000..dbc5fa81e Binary files /dev/null and b/images/pointblank_hex_logo.png differ diff --git a/man/action_levels.Rd b/man/action_levels.Rd index 680175b3d..e33cbbda9 100644 --- a/man/action_levels.Rd +++ b/man/action_levels.Rd @@ -161,10 +161,10 @@ validation steps and interrogate the \code{small_table}. actions = al ) \%>\% col_vals_gt( - columns = vars(a), value = 2 + columns = a, value = 2 ) \%>\% col_vals_lt( - columns = vars(d), value = 20000 + columns = d, value = 20000 ) \%>\% interrogate() }\if{html}{\out{}} @@ -192,11 +192,11 @@ another such object to the validation step instead (this time using the actions = al ) \%>\% col_vals_gt( - columns = vars(a), value = 2, + columns = a, value = 2, actions = warn_on_fail(warn_at = 0.5) ) \%>\% col_vals_lt( - columns = vars(d), value = 20000 + columns = d, value = 20000 ) \%>\% interrogate() }\if{html}{\out{}} @@ -221,7 +221,7 @@ data). \if{html}{\out{
}}\preformatted{small_table \%>\% col_vals_gt( - columns = vars(a), value = 2, + columns = a, value = 2, actions = warn_on_fail(warn_at = 2) ) }\if{html}{\out{
}} @@ -256,7 +256,7 @@ With the same pipeline, not supplying anything for \code{actions} (it's \code{NU default) will have the same effect as using \code{stop_on_fail(stop_at = 1)}. \if{html}{\out{
}}\preformatted{small_table \%>\% - col_vals_gt(columns = vars(a), value = 2) + col_vals_gt(columns = a, value = 2) }\if{html}{\out{
}} \if{html}{\out{
}}\preformatted{## Error: Exceedance of failed test units where values in `a` should have @@ -270,7 +270,7 @@ Here's the equivalent set of statements: \if{html}{\out{
}}\preformatted{small_table \%>\% col_vals_gt( - columns = vars(a), value = 2, + columns = a, value = 2, actions = stop_on_fail(stop_at = 1) ) }\if{html}{\out{
}} diff --git a/man/activate_steps.Rd b/man/activate_steps.Rd index ca41ab711..31db1cd35 100644 --- a/man/activate_steps.Rd +++ b/man/activate_steps.Rd @@ -51,11 +51,11 @@ agent_1 <- label = "An example." ) \%>\% col_exists( - columns = vars(date), + columns = date, active = FALSE ) \%>\% col_vals_regex( - columns = vars(b), + columns = b, regex = "[0-9]-[a-z]{3}-[0-9]{3}", active = FALSE ) \%>\% diff --git a/man/all_passed.Rd b/man/all_passed.Rd index 601e2c263..3db914035 100644 --- a/man/all_passed.Rd +++ b/man/all_passed.Rd @@ -68,9 +68,9 @@ Validate that values in column \code{a} are always greater than 4. \if{html}{\out{
}}\preformatted{agent <- create_agent(tbl = tbl) \%>\% - col_vals_gt(columns = vars(a), value = 3) \%>\% - col_vals_lte(columns = vars(a), value = 10) \%>\% - col_vals_increasing(columns = vars(a)) \%>\% + col_vals_gt(columns = a, value = 3) \%>\% + col_vals_lte(columns = a, value = 10) \%>\% + col_vals_increasing(columns = a) \%>\% interrogate() }\if{html}{\out{
}} diff --git a/man/col_count_match.Rd b/man/col_count_match.Rd index 4c06835f6..88c8c6581 100644 --- a/man/col_count_match.Rd +++ b/man/col_count_match.Rd @@ -38,10 +38,9 @@ Either a literal value for the number of columns, or, a table to compare against the target table in terms of column count values. If supplying a comparison table, it can either be a table object such as a data frame, a tibble, a \code{tbl_dbi} object, or a \code{tbl_spark} object. Alternatively, a -table-prep formula (\verb{~
}) or a function (`function()\if{html}{\out{ -
`) can be used to lazily read in the comparison table - at interrogation time. -}}} +table-prep formula (\verb{~ }) or a function ( +\verb{function() }) can be used to lazily read in the +comparison table at interrogation time.} \item{preconditions}{\emph{Input table modification prior to validation} @@ -77,12 +76,13 @@ produce (influenced by the number of \code{columns} provided), (2) be an ID string not used in any previous validation step, and (3) be a vector with unique values.} -\item{label}{\emph{An optional label for the validation step} +\item{label}{\emph{Optional label for the validation step} -\verb{scalar} // \emph{default:} \code{NULL} (\code{optional}) +\verb{vector} // \emph{default:} \code{NULL} (\code{optional}) -An optional label for the validation step. This label appears in the -\emph{agent} report and, for the best appearance, it should be kept quite short.} +Optional label for the validation step. This label appears in the \emph{agent} +report and, for the best appearance, it should be kept quite short. See +the \emph{Labels} section for more information.} \item{brief}{\emph{Brief description for the validation step} @@ -109,7 +109,7 @@ be used with \code{.} (serving as the input data table) to evaluate to a single logical value. With this approach, the \strong{pointblank} function \code{\link[=has_columns]{has_columns()}} can be used to determine whether to make a validation step active on the basis of one or more columns existing in the table -(e.g., \code{~ . \%>\% has_columns(vars(d, e))}).} +(e.g., \code{~ . \%>\% has_columns(c(d, e))}).} \item{object}{\emph{A data table for expectations or tests} @@ -210,6 +210,20 @@ depending on the situation (the first produces a warning, the other \code{stop()}s). } +\section{Labels}{ + + +\code{label} may be a single string or a character vector that matches the number +of expanded steps. \code{label} also supports \code{{glue}} syntax and exposes the +following dynamic variables contextualized to the current step: +\itemize{ +\item \code{"{.step}"}: The validation step name +} + +The glue context also supports ordinary expressions for further flexibility +(e.g., \code{"{toupper(.step)}"}) as long as they return a length-1 string. +} + \section{Briefs}{ @@ -397,12 +411,12 @@ Other validation functions: \code{\link{col_vals_decreasing}()}, \code{\link{col_vals_equal}()}, \code{\link{col_vals_expr}()}, -\code{\link{col_vals_gte}()}, \code{\link{col_vals_gt}()}, +\code{\link{col_vals_gte}()}, \code{\link{col_vals_in_set}()}, \code{\link{col_vals_increasing}()}, -\code{\link{col_vals_lte}()}, \code{\link{col_vals_lt}()}, +\code{\link{col_vals_lte}()}, \code{\link{col_vals_make_set}()}, \code{\link{col_vals_make_subset}()}, \code{\link{col_vals_not_between}()}, diff --git a/man/col_exists.Rd b/man/col_exists.Rd index eabadc70c..20c3ca6de 100644 --- a/man/col_exists.Rd +++ b/man/col_exists.Rd @@ -8,7 +8,7 @@ \usage{ col_exists( x, - columns, + columns = NULL, actions = NULL, step_id = NULL, label = NULL, @@ -31,11 +31,11 @@ commonly created with \code{\link[=create_agent]{create_agent()}}.} \item{columns}{\emph{The target columns} -`vector\if{html}{\out{}}|vars(\if{html}{\out{}})`` // \strong{required} +\verb{} // \strong{required} -One or more columns from the table in focus. This can be -provided as a vector of column names using \code{c()} or bare column names -enclosed in \code{\link[=vars]{vars()}}.} +A column-selecting expression, as one would use inside \code{dplyr::select()}. +Specifies the column (or a set of columns) to which this validation should +be applied. See the \emph{Column Names} section for more information.} \item{actions}{\emph{Thresholds and actions for different states} @@ -61,12 +61,13 @@ produce (influenced by the number of \code{columns} provided), (2) be an ID string not used in any previous validation step, and (3) be a vector with unique values.} -\item{label}{\emph{An optional label for the validation step} +\item{label}{\emph{Optional label for the validation step} -\verb{scalar} // \emph{default:} \code{NULL} (\code{optional}) +\verb{vector} // \emph{default:} \code{NULL} (\code{optional}) -An optional label for the validation step. This label appears in the -\emph{agent} report and, for the best appearance, it should be kept quite short.} +Optional label for the validation step. This label appears in the \emph{agent} +report and, for the best appearance, it should be kept quite short. See +the \emph{Labels} section for more information.} \item{brief}{\emph{Brief description for the validation step} @@ -93,7 +94,7 @@ be used with \code{.} (serving as the input data table) to evaluate to a single logical value. With this approach, the \strong{pointblank} function \code{\link[=has_columns]{has_columns()}} can be used to determine whether to make a validation step active on the basis of one or more columns existing in the table -(e.g., \code{~ . \%>\% has_columns(vars(d, e))}).} +(e.g., \code{~ . \%>\% has_columns(c(d, e))}).} \item{object}{\emph{A data table for expectations or tests} @@ -161,12 +162,17 @@ formally tested (so be mindful of this when using unsupported backends with \section{Column Names}{ -If providing multiple column names, the result will be an expansion of -validation steps to that number of column names (e.g., \code{vars(col_a, col_b)} -will result in the entry of two validation steps). Aside from column names in -quotes and in \code{vars()}, \strong{tidyselect} helper functions are available for -specifying columns. They are: \code{starts_with()}, \code{ends_with()}, \code{contains()}, -\code{matches()}, and \code{everything()}. +\code{columns} may be a single column (as symbol \code{a} or string \code{"a"}) or a vector +of columns (\code{c(a, b, c)} or \code{c("a", "b", "c")}). \code{{tidyselect}} helpers +are also supported, such as \code{contains("date")} and \code{where(is.double)}. If +passing an \emph{external vector} of columns, it should be wrapped in \code{all_of()}. + +When multiple columns are selected by \code{columns}, the result will be an +expansion of validation steps to that number of columns (e.g., +\code{c(col_a, col_b)} will result in the entry of two validation steps). + +Previously, columns could be specified in \code{vars()}. This continues to work, +but \code{c()} offers the same capability and supersedes \code{vars()} in \code{columns}. } \section{Actions}{ @@ -184,6 +190,21 @@ depending on the situation (the first produces a warning, the other \code{stop()}s). } +\section{Labels}{ + + +\code{label} may be a single string or a character vector that matches the number +of expanded steps. \code{label} also supports \code{{glue}} syntax and exposes the +following dynamic variables contextualized to the current step: +\itemize{ +\item \code{"{.step}"}: The validation step name +\item \code{"{.col}"}: The current column name +} + +The glue context also supports ordinary expressions for further flexibility +(e.g., \code{"{toupper(.step)}"}) as long as they return a length-1 string. +} + \section{Briefs}{ @@ -210,7 +231,7 @@ R statement: \if{html}{\out{
}}\preformatted{agent \%>\% col_exists( - columns = vars(a), + columns = a, actions = action_levels(warn_at = 0.1, stop_at = 0.2), label = "The `col_exists()` step.", active = FALSE @@ -221,7 +242,7 @@ YAML representation: \if{html}{\out{
}}\preformatted{steps: - col_exists: - columns: vars(a) + columns: c(a) actions: warn_fraction: 0.1 stop_fraction: 0.2 @@ -268,7 +289,7 @@ Validate that column \code{a} exists in the \code{tbl} table with \code{col_exis \if{html}{\out{
}}\preformatted{agent <- create_agent(tbl = tbl) \%>\% - col_exists(columns = vars(a)) \%>\% + col_exists(columns = a) \%>\% interrogate() }\if{html}{\out{
}} @@ -289,7 +310,7 @@ This way of using validation functions acts as a data filter. Data is passed through but should \code{stop()} if there is a single test unit failing. The behavior of side effects can be customized with the \code{actions} option. -\if{html}{\out{
}}\preformatted{tbl \%>\% col_exists(columns = vars(a)) +\if{html}{\out{
}}\preformatted{tbl \%>\% col_exists(columns = a) #> # A tibble: 6 x 2 #> a b #> @@ -307,7 +328,7 @@ The behavior of side effects can be customized with the \code{actions} option. With the \verb{expect_*()} form, we would typically perform one validation at a time. This is primarily used in \strong{testthat} tests. -\if{html}{\out{
}}\preformatted{expect_col_exists(tbl, columns = vars(a)) +\if{html}{\out{
}}\preformatted{expect_col_exists(tbl, columns = a) }\if{html}{\out{
}} } @@ -316,7 +337,7 @@ time. This is primarily used in \strong{testthat} tests. With the \verb{test_*()} form, we should get a single logical value returned to us. -\if{html}{\out{
}}\preformatted{tbl \%>\% test_col_exists(columns = vars(a)) +\if{html}{\out{
}}\preformatted{tbl \%>\% test_col_exists(columns = a) #> [1] TRUE }\if{html}{\out{
}} } @@ -342,12 +363,12 @@ Other validation functions: \code{\link{col_vals_decreasing}()}, \code{\link{col_vals_equal}()}, \code{\link{col_vals_expr}()}, -\code{\link{col_vals_gte}()}, \code{\link{col_vals_gt}()}, +\code{\link{col_vals_gte}()}, \code{\link{col_vals_in_set}()}, \code{\link{col_vals_increasing}()}, -\code{\link{col_vals_lte}()}, \code{\link{col_vals_lt}()}, +\code{\link{col_vals_lte}()}, \code{\link{col_vals_make_set}()}, \code{\link{col_vals_make_subset}()}, \code{\link{col_vals_not_between}()}, diff --git a/man/col_is_character.Rd b/man/col_is_character.Rd index a933bf632..f16cec65e 100644 --- a/man/col_is_character.Rd +++ b/man/col_is_character.Rd @@ -31,10 +31,11 @@ commonly created with \code{\link[=create_agent]{create_agent()}}.} \item{columns}{\emph{The target columns} -\verb{} // \strong{required} +\verb{} // \strong{required} -The column (or a set of columns, provided as a character vector) to which -this validation should be applied.} +A column-selecting expression, as one would use inside \code{dplyr::select()}. +Specifies the column (or a set of columns) to which this validation should +be applied. See the \emph{Column Names} section for more information.} \item{actions}{\emph{Thresholds and actions for different states} @@ -60,12 +61,13 @@ produce (influenced by the number of \code{columns} provided), (2) be an ID string not used in any previous validation step, and (3) be a vector with unique values.} -\item{label}{\emph{An optional label for the validation step} +\item{label}{\emph{Optional label for the validation step} -\verb{scalar} // \emph{default:} \code{NULL} (\code{optional}) +\verb{vector} // \emph{default:} \code{NULL} (\code{optional}) -An optional label for the validation step. This label appears in the -\emph{agent} report and, for the best appearance, it should be kept quite short.} +Optional label for the validation step. This label appears in the \emph{agent} +report and, for the best appearance, it should be kept quite short. See +the \emph{Labels} section for more information.} \item{brief}{\emph{Brief description for the validation step} @@ -92,7 +94,7 @@ be used with \code{.} (serving as the input data table) to evaluate to a single logical value. With this approach, the \strong{pointblank} function \code{\link[=has_columns]{has_columns()}} can be used to determine whether to make a validation step active on the basis of one or more columns existing in the table -(e.g., \code{~ . \%>\% has_columns(vars(d, e))}).} +(e.g., \code{~ . \%>\% has_columns(c(d, e))}).} \item{object}{\emph{A data table for expectations or tests} @@ -162,12 +164,17 @@ formally tested (so be mindful of this when using unsupported backends with \section{Column Names}{ -If providing multiple column names, the result will be an expansion of -validation steps to that number of column names (e.g., \code{vars(col_a, col_b)} -will result in the entry of two validation steps). Aside from column names in -quotes and in \code{vars()}, \strong{tidyselect} helper functions are available for -specifying columns. They are: \code{starts_with()}, \code{ends_with()}, \code{contains()}, -\code{matches()}, and \code{everything()}. +\code{columns} may be a single column (as symbol \code{a} or string \code{"a"}) or a vector +of columns (\code{c(a, b, c)} or \code{c("a", "b", "c")}). \code{{tidyselect}} helpers +are also supported, such as \code{contains("date")} and \code{where(is.double)}. If +passing an \emph{external vector} of columns, it should be wrapped in \code{all_of()}. + +When multiple columns are selected by \code{columns}, the result will be an +expansion of validation steps to that number of columns (e.g., +\code{c(col_a, col_b)} will result in the entry of two validation steps). + +Previously, columns could be specified in \code{vars()}. This continues to work, +but \code{c()} offers the same capability and supersedes \code{vars()} in \code{columns}. } \section{Actions}{ @@ -185,6 +192,21 @@ happens. For the \verb{col_is_*()}-type functions, using \code{action_levels(war situation (the first produces a warning, the other will \code{stop()}). } +\section{Labels}{ + + +\code{label} may be a single string or a character vector that matches the number +of expanded steps. \code{label} also supports \code{{glue}} syntax and exposes the +following dynamic variables contextualized to the current step: +\itemize{ +\item \code{"{.step}"}: The validation step name +\item \code{"{.col}"}: The current column name +} + +The glue context also supports ordinary expressions for further flexibility +(e.g., \code{"{toupper(.step)}"}) as long as they return a length-1 string. +} + \section{Briefs}{ @@ -211,7 +233,7 @@ R statement: \if{html}{\out{
}}\preformatted{agent \%>\% col_is_character( - columns = vars(a), + columns = a, actions = action_levels(warn_at = 0.1, stop_at = 0.2), label = "The `col_is_character()` step.", active = FALSE @@ -222,7 +244,7 @@ YAML representation: \if{html}{\out{
}}\preformatted{steps: - col_is_character: - columns: vars(a) + columns: c(a) actions: warn_fraction: 0.1 stop_fraction: 0.2 @@ -269,7 +291,7 @@ Validate that column \code{b} has the \code{character} class. \if{html}{\out{
}}\preformatted{agent <- create_agent(tbl = tbl) \%>\% - col_is_character(columns = vars(b)) \%>\% + col_is_character(columns = b) \%>\% interrogate() }\if{html}{\out{
}} @@ -291,7 +313,7 @@ through but should \code{stop()} if there is a single test unit failing. The behavior of side effects can be customized with the \code{actions} option. \if{html}{\out{
}}\preformatted{tbl \%>\% - col_is_character(columns = vars(b)) \%>\% + col_is_character(columns = b) \%>\% dplyr::slice(1:5) #> # A tibble: 5 x 2 #> a b @@ -309,7 +331,7 @@ behavior of side effects can be customized with the \code{actions} option. With the \verb{expect_*()} form, we would typically perform one validation at a time. This is primarily used in \strong{testthat} tests. -\if{html}{\out{
}}\preformatted{expect_col_is_character(tbl, columns = vars(b)) +\if{html}{\out{
}}\preformatted{expect_col_is_character(tbl, columns = b) }\if{html}{\out{
}} } @@ -318,7 +340,7 @@ time. This is primarily used in \strong{testthat} tests. With the \verb{test_*()} form, we should get a single logical value returned to us. -\if{html}{\out{
}}\preformatted{tbl \%>\% test_col_is_character(columns = vars(b)) +\if{html}{\out{
}}\preformatted{tbl \%>\% test_col_is_character(columns = b) #> [1] TRUE }\if{html}{\out{
}} } @@ -344,12 +366,12 @@ Other validation functions: \code{\link{col_vals_decreasing}()}, \code{\link{col_vals_equal}()}, \code{\link{col_vals_expr}()}, -\code{\link{col_vals_gte}()}, \code{\link{col_vals_gt}()}, +\code{\link{col_vals_gte}()}, \code{\link{col_vals_in_set}()}, \code{\link{col_vals_increasing}()}, -\code{\link{col_vals_lte}()}, \code{\link{col_vals_lt}()}, +\code{\link{col_vals_lte}()}, \code{\link{col_vals_make_set}()}, \code{\link{col_vals_make_subset}()}, \code{\link{col_vals_not_between}()}, diff --git a/man/col_is_date.Rd b/man/col_is_date.Rd index a9dd83989..568b0516c 100644 --- a/man/col_is_date.Rd +++ b/man/col_is_date.Rd @@ -31,10 +31,11 @@ commonly created with \code{\link[=create_agent]{create_agent()}}.} \item{columns}{\emph{The target columns} -\verb{} // \strong{required} +\verb{} // \strong{required} -The column (or a set of columns, provided as a character vector) to which -this validation should be applied.} +A column-selecting expression, as one would use inside \code{dplyr::select()}. +Specifies the column (or a set of columns) to which this validation should +be applied. See the \emph{Column Names} section for more information.} \item{actions}{\emph{Thresholds and actions for different states} @@ -60,12 +61,13 @@ produce (influenced by the number of \code{columns} provided), (2) be an ID string not used in any previous validation step, and (3) be a vector with unique values.} -\item{label}{\emph{An optional label for the validation step} +\item{label}{\emph{Optional label for the validation step} -\verb{scalar} // \emph{default:} \code{NULL} (\code{optional}) +\verb{vector} // \emph{default:} \code{NULL} (\code{optional}) -An optional label for the validation step. This label appears in the -\emph{agent} report and, for the best appearance, it should be kept quite short.} +Optional label for the validation step. This label appears in the \emph{agent} +report and, for the best appearance, it should be kept quite short. See +the \emph{Labels} section for more information.} \item{brief}{\emph{Brief description for the validation step} @@ -92,7 +94,7 @@ be used with \code{.} (serving as the input data table) to evaluate to a single logical value. With this approach, the \strong{pointblank} function \code{\link[=has_columns]{has_columns()}} can be used to determine whether to make a validation step active on the basis of one or more columns existing in the table -(e.g., \code{~ . \%>\% has_columns(vars(d, e))}).} +(e.g., \code{~ . \%>\% has_columns(c(d, e))}).} \item{object}{\emph{A data table for expectations or tests} @@ -162,12 +164,17 @@ formally tested (so be mindful of this when using unsupported backends with \section{Column Names}{ -If providing multiple column names, the result will be an expansion of -validation steps to that number of column names (e.g., \code{vars(col_a, col_b)} -will result in the entry of two validation steps). Aside from column names in -quotes and in \code{vars()}, \strong{tidyselect} helper functions are available for -specifying columns. They are: \code{starts_with()}, \code{ends_with()}, \code{contains()}, -\code{matches()}, and \code{everything()}. +\code{columns} may be a single column (as symbol \code{a} or string \code{"a"}) or a vector +of columns (\code{c(a, b, c)} or \code{c("a", "b", "c")}). \code{{tidyselect}} helpers +are also supported, such as \code{contains("date")} and \code{where(is.double)}. If +passing an \emph{external vector} of columns, it should be wrapped in \code{all_of()}. + +When multiple columns are selected by \code{columns}, the result will be an +expansion of validation steps to that number of columns (e.g., +\code{c(col_a, col_b)} will result in the entry of two validation steps). + +Previously, columns could be specified in \code{vars()}. This continues to work, +but \code{c()} offers the same capability and supersedes \code{vars()} in \code{columns}. } \section{Actions}{ @@ -185,6 +192,21 @@ happens. For the \verb{col_is_*()}-type functions, using \code{action_levels(war situation (the first produces a warning, the other will \code{stop()}). } +\section{Labels}{ + + +\code{label} may be a single string or a character vector that matches the number +of expanded steps. \code{label} also supports \code{{glue}} syntax and exposes the +following dynamic variables contextualized to the current step: +\itemize{ +\item \code{"{.step}"}: The validation step name +\item \code{"{.col}"}: The current column name +} + +The glue context also supports ordinary expressions for further flexibility +(e.g., \code{"{toupper(.step)}"}) as long as they return a length-1 string. +} + \section{Briefs}{ @@ -211,7 +233,7 @@ R statement: \if{html}{\out{
}}\preformatted{agent \%>\% col_is_date( - columns = vars(a), + columns = a, actions = action_levels(warn_at = 0.1, stop_at = 0.2), label = "The `col_is_date()` step.", active = FALSE @@ -222,7 +244,7 @@ YAML representation: \if{html}{\out{
}}\preformatted{steps: - col_is_date: - columns: vars(a) + columns: c(a) actions: warn_fraction: 0.1 stop_fraction: 0.2 @@ -268,7 +290,7 @@ Validate that the column \code{date} has the \code{Date} class. \if{html}{\out{
}}\preformatted{agent <- create_agent(tbl = small_table) \%>\% - col_is_date(columns = vars(date)) \%>\% + col_is_date(columns = date) \%>\% interrogate() }\if{html}{\out{
}} @@ -290,7 +312,7 @@ through but should \code{stop()} if there is a single test unit failing. The behavior of side effects can be customized with the \code{actions} option. \if{html}{\out{
}}\preformatted{small_table \%>\% - col_is_date(columns = vars(date)) \%>\% + col_is_date(columns = date) \%>\% dplyr::slice(1:5) #> # A tibble: 5 x 8 #> date_time date a b c d e f @@ -308,7 +330,7 @@ behavior of side effects can be customized with the \code{actions} option. With the \verb{expect_*()} form, we would typically perform one validation at a time. This is primarily used in \strong{testthat} tests. -\if{html}{\out{
}}\preformatted{expect_col_is_date(small_table, columns = vars(date)) +\if{html}{\out{
}}\preformatted{expect_col_is_date(small_table, columns = date) }\if{html}{\out{
}} } @@ -317,7 +339,7 @@ time. This is primarily used in \strong{testthat} tests. With the \verb{test_*()} form, we should get a single logical value returned to us. -\if{html}{\out{
}}\preformatted{small_table \%>\% test_col_is_date(columns = vars(date)) +\if{html}{\out{
}}\preformatted{small_table \%>\% test_col_is_date(columns = date) #> [1] TRUE }\if{html}{\out{
}} } @@ -343,12 +365,12 @@ Other validation functions: \code{\link{col_vals_decreasing}()}, \code{\link{col_vals_equal}()}, \code{\link{col_vals_expr}()}, -\code{\link{col_vals_gte}()}, \code{\link{col_vals_gt}()}, +\code{\link{col_vals_gte}()}, \code{\link{col_vals_in_set}()}, \code{\link{col_vals_increasing}()}, -\code{\link{col_vals_lte}()}, \code{\link{col_vals_lt}()}, +\code{\link{col_vals_lte}()}, \code{\link{col_vals_make_set}()}, \code{\link{col_vals_make_subset}()}, \code{\link{col_vals_not_between}()}, diff --git a/man/col_is_factor.Rd b/man/col_is_factor.Rd index 8393c8e66..3bc0219e3 100644 --- a/man/col_is_factor.Rd +++ b/man/col_is_factor.Rd @@ -31,10 +31,11 @@ commonly created with \code{\link[=create_agent]{create_agent()}}.} \item{columns}{\emph{The target columns} -\verb{} // \strong{required} +\verb{} // \strong{required} -The column (or a set of columns, provided as a character vector) to which -this validation should be applied.} +A column-selecting expression, as one would use inside \code{dplyr::select()}. +Specifies the column (or a set of columns) to which this validation should +be applied. See the \emph{Column Names} section for more information.} \item{actions}{\emph{Thresholds and actions for different states} @@ -60,12 +61,13 @@ produce (influenced by the number of \code{columns} provided), (2) be an ID string not used in any previous validation step, and (3) be a vector with unique values.} -\item{label}{\emph{An optional label for the validation step} +\item{label}{\emph{Optional label for the validation step} -\verb{scalar} // \emph{default:} \code{NULL} (\code{optional}) +\verb{vector} // \emph{default:} \code{NULL} (\code{optional}) -An optional label for the validation step. This label appears in the -\emph{agent} report and, for the best appearance, it should be kept quite short.} +Optional label for the validation step. This label appears in the \emph{agent} +report and, for the best appearance, it should be kept quite short. See +the \emph{Labels} section for more information.} \item{brief}{\emph{Brief description for the validation step} @@ -92,7 +94,7 @@ be used with \code{.} (serving as the input data table) to evaluate to a single logical value. With this approach, the \strong{pointblank} function \code{\link[=has_columns]{has_columns()}} can be used to determine whether to make a validation step active on the basis of one or more columns existing in the table -(e.g., \code{~ . \%>\% has_columns(vars(d, e))}).} +(e.g., \code{~ . \%>\% has_columns(c(d, e))}).} \item{object}{\emph{A data table for expectations or tests} @@ -162,12 +164,17 @@ formally tested (so be mindful of this when using unsupported backends with \section{Column Names}{ -If providing multiple column names, the result will be an expansion of -validation steps to that number of column names (e.g., \code{vars(col_a, col_b)} -will result in the entry of two validation steps). Aside from column names in -quotes and in \code{vars()}, \strong{tidyselect} helper functions are available for -specifying columns. They are: \code{starts_with()}, \code{ends_with()}, \code{contains()}, -\code{matches()}, and \code{everything()}. +\code{columns} may be a single column (as symbol \code{a} or string \code{"a"}) or a vector +of columns (\code{c(a, b, c)} or \code{c("a", "b", "c")}). \code{{tidyselect}} helpers +are also supported, such as \code{contains("date")} and \code{where(is.double)}. If +passing an \emph{external vector} of columns, it should be wrapped in \code{all_of()}. + +When multiple columns are selected by \code{columns}, the result will be an +expansion of validation steps to that number of columns (e.g., +\code{c(col_a, col_b)} will result in the entry of two validation steps). + +Previously, columns could be specified in \code{vars()}. This continues to work, +but \code{c()} offers the same capability and supersedes \code{vars()} in \code{columns}. } \section{Actions}{ @@ -185,6 +192,21 @@ happens. For the \verb{col_is_*()}-type functions, using \code{action_levels(war situation (the first produces a warning, the other will \code{stop()}). } +\section{Labels}{ + + +\code{label} may be a single string or a character vector that matches the number +of expanded steps. \code{label} also supports \code{{glue}} syntax and exposes the +following dynamic variables contextualized to the current step: +\itemize{ +\item \code{"{.step}"}: The validation step name +\item \code{"{.col}"}: The current column name +} + +The glue context also supports ordinary expressions for further flexibility +(e.g., \code{"{toupper(.step)}"}) as long as they return a length-1 string. +} + \section{Briefs}{ @@ -211,7 +233,7 @@ R statement: \if{html}{\out{
}}\preformatted{agent \%>\% col_is_factor( - columns = vars(a), + columns = a, actions = action_levels(warn_at = 0.1, stop_at = 0.2), label = "The `col_is_factor()` step.", active = FALSE @@ -222,7 +244,7 @@ YAML representation: \if{html}{\out{
}}\preformatted{steps: - col_is_factor: - columns: vars(a) + columns: c(a) actions: warn_fraction: 0.1 stop_fraction: 0.2 @@ -274,7 +296,7 @@ Validate that the column \code{f} in the \code{tbl} object is of the \code{facto \if{html}{\out{
}}\preformatted{agent <- create_agent(tbl = tbl) \%>\% - col_is_factor(columns = vars(f)) \%>\% + col_is_factor(columns = f) \%>\% interrogate() }\if{html}{\out{
}} @@ -296,7 +318,7 @@ through but should \code{stop()} if there is a single test unit failing. The behavior of side effects can be customized with the \code{actions} option. \if{html}{\out{
}}\preformatted{tbl \%>\% - col_is_factor(columns = vars(f)) \%>\% + col_is_factor(columns = f) \%>\% dplyr::slice(1:5) #> # A tibble: 5 x 8 #> date_time date a b c d e f @@ -314,7 +336,7 @@ behavior of side effects can be customized with the \code{actions} option. With the \verb{expect_*()} form, we would typically perform one validation at a time. This is primarily used in \strong{testthat} tests. -\if{html}{\out{
}}\preformatted{expect_col_is_factor(tbl, vars(f)) +\if{html}{\out{
}}\preformatted{expect_col_is_factor(tbl, f) }\if{html}{\out{
}} } @@ -323,7 +345,7 @@ time. This is primarily used in \strong{testthat} tests. With the \verb{test_*()} form, we should get a single logical value returned to us. -\if{html}{\out{
}}\preformatted{tbl \%>\% test_col_is_factor(columns = vars(f)) +\if{html}{\out{
}}\preformatted{tbl \%>\% test_col_is_factor(columns = f) #> [1] TRUE }\if{html}{\out{
}} } @@ -349,12 +371,12 @@ Other validation functions: \code{\link{col_vals_decreasing}()}, \code{\link{col_vals_equal}()}, \code{\link{col_vals_expr}()}, -\code{\link{col_vals_gte}()}, \code{\link{col_vals_gt}()}, +\code{\link{col_vals_gte}()}, \code{\link{col_vals_in_set}()}, \code{\link{col_vals_increasing}()}, -\code{\link{col_vals_lte}()}, \code{\link{col_vals_lt}()}, +\code{\link{col_vals_lte}()}, \code{\link{col_vals_make_set}()}, \code{\link{col_vals_make_subset}()}, \code{\link{col_vals_not_between}()}, diff --git a/man/col_is_integer.Rd b/man/col_is_integer.Rd index 884e125aa..09eb320aa 100644 --- a/man/col_is_integer.Rd +++ b/man/col_is_integer.Rd @@ -31,10 +31,11 @@ commonly created with \code{\link[=create_agent]{create_agent()}}.} \item{columns}{\emph{The target columns} -\verb{} // \strong{required} +\verb{} // \strong{required} -The column (or a set of columns, provided as a character vector) to which -this validation should be applied.} +A column-selecting expression, as one would use inside \code{dplyr::select()}. +Specifies the column (or a set of columns) to which this validation should +be applied. See the \emph{Column Names} section for more information.} \item{actions}{\emph{Thresholds and actions for different states} @@ -60,12 +61,13 @@ produce (influenced by the number of \code{columns} provided), (2) be an ID string not used in any previous validation step, and (3) be a vector with unique values.} -\item{label}{\emph{An optional label for the validation step} +\item{label}{\emph{Optional label for the validation step} -\verb{scalar} // \emph{default:} \code{NULL} (\code{optional}) +\verb{vector} // \emph{default:} \code{NULL} (\code{optional}) -An optional label for the validation step. This label appears in the -\emph{agent} report and, for the best appearance, it should be kept quite short.} +Optional label for the validation step. This label appears in the \emph{agent} +report and, for the best appearance, it should be kept quite short. See +the \emph{Labels} section for more information.} \item{brief}{\emph{Brief description for the validation step} @@ -92,7 +94,7 @@ be used with \code{.} (serving as the input data table) to evaluate to a single logical value. With this approach, the \strong{pointblank} function \code{\link[=has_columns]{has_columns()}} can be used to determine whether to make a validation step active on the basis of one or more columns existing in the table -(e.g., \code{~ . \%>\% has_columns(vars(d, e))}).} +(e.g., \code{~ . \%>\% has_columns(c(d, e))}).} \item{object}{\emph{A data table for expectations or tests} @@ -162,12 +164,17 @@ formally tested (so be mindful of this when using unsupported backends with \section{Column Names}{ -If providing multiple column names, the result will be an expansion of -validation steps to that number of column names (e.g., \code{vars(col_a, col_b)} -will result in the entry of two validation steps). Aside from column names in -quotes and in \code{vars()}, \strong{tidyselect} helper functions are available for -specifying columns. They are: \code{starts_with()}, \code{ends_with()}, \code{contains()}, -\code{matches()}, and \code{everything()}. +\code{columns} may be a single column (as symbol \code{a} or string \code{"a"}) or a vector +of columns (\code{c(a, b, c)} or \code{c("a", "b", "c")}). \code{{tidyselect}} helpers +are also supported, such as \code{contains("date")} and \code{where(is.double)}. If +passing an \emph{external vector} of columns, it should be wrapped in \code{all_of()}. + +When multiple columns are selected by \code{columns}, the result will be an +expansion of validation steps to that number of columns (e.g., +\code{c(col_a, col_b)} will result in the entry of two validation steps). + +Previously, columns could be specified in \code{vars()}. This continues to work, +but \code{c()} offers the same capability and supersedes \code{vars()} in \code{columns}. } \section{Actions}{ @@ -185,6 +192,21 @@ happens. For the \verb{col_is_*()}-type functions, using \code{action_levels(war situation (the first produces a warning, the other will \code{stop()}). } +\section{Labels}{ + + +\code{label} may be a single string or a character vector that matches the number +of expanded steps. \code{label} also supports \code{{glue}} syntax and exposes the +following dynamic variables contextualized to the current step: +\itemize{ +\item \code{"{.step}"}: The validation step name +\item \code{"{.col}"}: The current column name +} + +The glue context also supports ordinary expressions for further flexibility +(e.g., \code{"{toupper(.step)}"}) as long as they return a length-1 string. +} + \section{Briefs}{ @@ -211,7 +233,7 @@ R statement: \if{html}{\out{
}}\preformatted{agent \%>\% col_is_integer( - columns = vars(a), + columns = a, actions = action_levels(warn_at = 0.1, stop_at = 0.2), label = "The `col_is_integer()` step.", active = FALSE @@ -222,7 +244,7 @@ YAML representation: \if{html}{\out{
}}\preformatted{steps: - col_is_integer: - columns: vars(a) + columns: c(a) actions: warn_fraction: 0.1 stop_fraction: 0.2 @@ -267,7 +289,7 @@ Validate that column \code{b} has the \code{integer} class. \if{html}{\out{
}}\preformatted{agent <- create_agent(tbl = tbl) \%>\% - col_is_integer(columns = vars(b)) \%>\% + col_is_integer(columns = b) \%>\% interrogate() }\if{html}{\out{
}} @@ -288,7 +310,7 @@ This way of using validation functions acts as a data filter. Data is passed through but should \code{stop()} if there is a single test unit failing. The behavior of side effects can be customized with the \code{actions} option. -\if{html}{\out{
}}\preformatted{tbl \%>\% col_is_integer(columns = vars(b)) +\if{html}{\out{
}}\preformatted{tbl \%>\% col_is_integer(columns = b) #> # A tibble: 6 x 2 #> a b #> @@ -306,7 +328,7 @@ behavior of side effects can be customized with the \code{actions} option. With the \verb{expect_*()} form, we would typically perform one validation at a time. This is primarily used in \strong{testthat} tests. -\if{html}{\out{
}}\preformatted{expect_col_is_integer(tbl, columns = vars(b)) +\if{html}{\out{
}}\preformatted{expect_col_is_integer(tbl, columns = b) }\if{html}{\out{
}} } @@ -315,7 +337,7 @@ time. This is primarily used in \strong{testthat} tests. With the \verb{test_*()} form, we should get a single logical value returned to us. -\if{html}{\out{
}}\preformatted{tbl \%>\% test_col_is_integer(columns = vars(b)) +\if{html}{\out{
}}\preformatted{tbl \%>\% test_col_is_integer(columns = b) #> [1] TRUE }\if{html}{\out{
}} } @@ -341,12 +363,12 @@ Other validation functions: \code{\link{col_vals_decreasing}()}, \code{\link{col_vals_equal}()}, \code{\link{col_vals_expr}()}, -\code{\link{col_vals_gte}()}, \code{\link{col_vals_gt}()}, +\code{\link{col_vals_gte}()}, \code{\link{col_vals_in_set}()}, \code{\link{col_vals_increasing}()}, -\code{\link{col_vals_lte}()}, \code{\link{col_vals_lt}()}, +\code{\link{col_vals_lte}()}, \code{\link{col_vals_make_set}()}, \code{\link{col_vals_make_subset}()}, \code{\link{col_vals_not_between}()}, diff --git a/man/col_is_logical.Rd b/man/col_is_logical.Rd index d3bef5639..2003c7192 100644 --- a/man/col_is_logical.Rd +++ b/man/col_is_logical.Rd @@ -31,10 +31,11 @@ commonly created with \code{\link[=create_agent]{create_agent()}}.} \item{columns}{\emph{The target columns} -\verb{} // \strong{required} +\verb{} // \strong{required} -The column (or a set of columns, provided as a character vector) to which -this validation should be applied.} +A column-selecting expression, as one would use inside \code{dplyr::select()}. +Specifies the column (or a set of columns) to which this validation should +be applied. See the \emph{Column Names} section for more information.} \item{actions}{\emph{Thresholds and actions for different states} @@ -60,12 +61,13 @@ produce (influenced by the number of \code{columns} provided), (2) be an ID string not used in any previous validation step, and (3) be a vector with unique values.} -\item{label}{\emph{An optional label for the validation step} +\item{label}{\emph{Optional label for the validation step} -\verb{scalar} // \emph{default:} \code{NULL} (\code{optional}) +\verb{vector} // \emph{default:} \code{NULL} (\code{optional}) -An optional label for the validation step. This label appears in the -\emph{agent} report and, for the best appearance, it should be kept quite short.} +Optional label for the validation step. This label appears in the \emph{agent} +report and, for the best appearance, it should be kept quite short. See +the \emph{Labels} section for more information.} \item{brief}{\emph{Brief description for the validation step} @@ -92,7 +94,7 @@ be used with \code{.} (serving as the input data table) to evaluate to a single logical value. With this approach, the \strong{pointblank} function \code{\link[=has_columns]{has_columns()}} can be used to determine whether to make a validation step active on the basis of one or more columns existing in the table -(e.g., \code{~ . \%>\% has_columns(vars(d, e))}).} +(e.g., \code{~ . \%>\% has_columns(c(d, e))}).} \item{object}{\emph{A data table for expectations or tests} @@ -162,12 +164,17 @@ formally tested (so be mindful of this when using unsupported backends with \section{Column Names}{ -If providing multiple column names, the result will be an expansion of -validation steps to that number of column names (e.g., \code{vars(col_a, col_b)} -will result in the entry of two validation steps). Aside from column names in -quotes and in \code{vars()}, \strong{tidyselect} helper functions are available for -specifying columns. They are: \code{starts_with()}, \code{ends_with()}, \code{contains()}, -\code{matches()}, and \code{everything()}. +\code{columns} may be a single column (as symbol \code{a} or string \code{"a"}) or a vector +of columns (\code{c(a, b, c)} or \code{c("a", "b", "c")}). \code{{tidyselect}} helpers +are also supported, such as \code{contains("date")} and \code{where(is.double)}. If +passing an \emph{external vector} of columns, it should be wrapped in \code{all_of()}. + +When multiple columns are selected by \code{columns}, the result will be an +expansion of validation steps to that number of columns (e.g., +\code{c(col_a, col_b)} will result in the entry of two validation steps). + +Previously, columns could be specified in \code{vars()}. This continues to work, +but \code{c()} offers the same capability and supersedes \code{vars()} in \code{columns}. } \section{Actions}{ @@ -185,6 +192,21 @@ happens. For the \verb{col_is_*()}-type functions, using \code{action_levels(war situation (the first produces a warning, the other will \code{stop()}). } +\section{Labels}{ + + +\code{label} may be a single string or a character vector that matches the number +of expanded steps. \code{label} also supports \code{{glue}} syntax and exposes the +following dynamic variables contextualized to the current step: +\itemize{ +\item \code{"{.step}"}: The validation step name +\item \code{"{.col}"}: The current column name +} + +The glue context also supports ordinary expressions for further flexibility +(e.g., \code{"{toupper(.step)}"}) as long as they return a length-1 string. +} + \section{Briefs}{ @@ -211,7 +233,7 @@ R statement: \if{html}{\out{
}}\preformatted{agent \%>\% col_is_logical( - columns = vars(a), + columns = a, actions = action_levels(warn_at = 0.1, stop_at = 0.2), label = "The `col_is_logical()` step.", active = FALSE @@ -222,7 +244,7 @@ YAML representation: \if{html}{\out{
}}\preformatted{steps: - col_is_logical: - columns: vars(a) + columns: c(a) actions: warn_fraction: 0.1 stop_fraction: 0.2 @@ -269,7 +291,7 @@ Validate that the column \code{e} has the \code{logical} class. \if{html}{\out{
}}\preformatted{agent <- create_agent(tbl = small_table) \%>\% - col_is_logical(columns = vars(e)) \%>\% + col_is_logical(columns = e) \%>\% interrogate() }\if{html}{\out{
}} @@ -291,7 +313,7 @@ through but should \code{stop()} if there is a single test unit failing. The behavior of side effects can be customized with the \code{actions} option. \if{html}{\out{
}}\preformatted{small_table \%>\% - col_is_logical(columns = vars(e)) \%>\% + col_is_logical(columns = e) \%>\% dplyr::slice(1:5) #> # A tibble: 5 x 8 #> date_time date a b c d e f @@ -309,7 +331,7 @@ behavior of side effects can be customized with the \code{actions} option. With the \verb{expect_*()} form, we would typically perform one validation at a time. This is primarily used in \strong{testthat} tests. -\if{html}{\out{
}}\preformatted{expect_col_is_logical(small_table, columns = vars(e)) +\if{html}{\out{
}}\preformatted{expect_col_is_logical(small_table, columns = e) }\if{html}{\out{
}} } @@ -318,7 +340,7 @@ time. This is primarily used in \strong{testthat} tests. With the \verb{test_*()} form, we should get a single logical value returned to us. -\if{html}{\out{
}}\preformatted{small_table \%>\% test_col_is_logical(columns = vars(e)) +\if{html}{\out{
}}\preformatted{small_table \%>\% test_col_is_logical(columns = e) #> [1] TRUE }\if{html}{\out{
}} } @@ -344,12 +366,12 @@ Other validation functions: \code{\link{col_vals_decreasing}()}, \code{\link{col_vals_equal}()}, \code{\link{col_vals_expr}()}, -\code{\link{col_vals_gte}()}, \code{\link{col_vals_gt}()}, +\code{\link{col_vals_gte}()}, \code{\link{col_vals_in_set}()}, \code{\link{col_vals_increasing}()}, -\code{\link{col_vals_lte}()}, \code{\link{col_vals_lt}()}, +\code{\link{col_vals_lte}()}, \code{\link{col_vals_make_set}()}, \code{\link{col_vals_make_subset}()}, \code{\link{col_vals_not_between}()}, diff --git a/man/col_is_numeric.Rd b/man/col_is_numeric.Rd index 3b9096cad..61332bc9c 100644 --- a/man/col_is_numeric.Rd +++ b/man/col_is_numeric.Rd @@ -31,10 +31,11 @@ commonly created with \code{\link[=create_agent]{create_agent()}}.} \item{columns}{\emph{The target columns} -\verb{} // \strong{required} +\verb{} // \strong{required} -The column (or a set of columns, provided as a character vector) to which -this validation should be applied.} +A column-selecting expression, as one would use inside \code{dplyr::select()}. +Specifies the column (or a set of columns) to which this validation should +be applied. See the \emph{Column Names} section for more information.} \item{actions}{\emph{Thresholds and actions for different states} @@ -60,12 +61,13 @@ produce (influenced by the number of \code{columns} provided), (2) be an ID string not used in any previous validation step, and (3) be a vector with unique values.} -\item{label}{\emph{An optional label for the validation step} +\item{label}{\emph{Optional label for the validation step} -\verb{scalar} // \emph{default:} \code{NULL} (\code{optional}) +\verb{vector} // \emph{default:} \code{NULL} (\code{optional}) -An optional label for the validation step. This label appears in the -\emph{agent} report and, for the best appearance, it should be kept quite short.} +Optional label for the validation step. This label appears in the \emph{agent} +report and, for the best appearance, it should be kept quite short. See +the \emph{Labels} section for more information.} \item{brief}{\emph{Brief description for the validation step} @@ -92,7 +94,7 @@ be used with \code{.} (serving as the input data table) to evaluate to a single logical value. With this approach, the \strong{pointblank} function \code{\link[=has_columns]{has_columns()}} can be used to determine whether to make a validation step active on the basis of one or more columns existing in the table -(e.g., \code{~ . \%>\% has_columns(vars(d, e))}).} +(e.g., \code{~ . \%>\% has_columns(c(d, e))}).} \item{object}{\emph{A data table for expectations or tests} @@ -162,12 +164,17 @@ formally tested (so be mindful of this when using unsupported backends with \section{Column Names}{ -If providing multiple column names, the result will be an expansion of -validation steps to that number of column names (e.g., \code{vars(col_a, col_b)} -will result in the entry of two validation steps). Aside from column names in -quotes and in \code{vars()}, \strong{tidyselect} helper functions are available for -specifying columns. They are: \code{starts_with()}, \code{ends_with()}, \code{contains()}, -\code{matches()}, and \code{everything()}. +\code{columns} may be a single column (as symbol \code{a} or string \code{"a"}) or a vector +of columns (\code{c(a, b, c)} or \code{c("a", "b", "c")}). \code{{tidyselect}} helpers +are also supported, such as \code{contains("date")} and \code{where(is.double)}. If +passing an \emph{external vector} of columns, it should be wrapped in \code{all_of()}. + +When multiple columns are selected by \code{columns}, the result will be an +expansion of validation steps to that number of columns (e.g., +\code{c(col_a, col_b)} will result in the entry of two validation steps). + +Previously, columns could be specified in \code{vars()}. This continues to work, +but \code{c()} offers the same capability and supersedes \code{vars()} in \code{columns}. } \section{Actions}{ @@ -185,6 +192,21 @@ happens. For the \verb{col_is_*()}-type functions, using \code{action_levels(war situation (the first produces a warning, the other will \code{stop()}). } +\section{Labels}{ + + +\code{label} may be a single string or a character vector that matches the number +of expanded steps. \code{label} also supports \code{{glue}} syntax and exposes the +following dynamic variables contextualized to the current step: +\itemize{ +\item \code{"{.step}"}: The validation step name +\item \code{"{.col}"}: The current column name +} + +The glue context also supports ordinary expressions for further flexibility +(e.g., \code{"{toupper(.step)}"}) as long as they return a length-1 string. +} + \section{Briefs}{ @@ -211,7 +233,7 @@ R statement: \if{html}{\out{
}}\preformatted{agent \%>\% col_is_numeric( - columns = vars(a), + columns = a, actions = action_levels(warn_at = 0.1, stop_at = 0.2), label = "The `col_is_numeric()` step.", active = FALSE @@ -222,7 +244,7 @@ YAML representation: \if{html}{\out{
}}\preformatted{steps: - col_is_numeric: - columns: vars(a) + columns: c(a) actions: warn_fraction: 0.1 stop_fraction: 0.2 @@ -269,7 +291,7 @@ Validate that the column \code{d} has the \code{numeric} class. \if{html}{\out{
}}\preformatted{agent <- create_agent(tbl = small_table) \%>\% - col_is_numeric(columns = vars(d)) \%>\% + col_is_numeric(columns = d) \%>\% interrogate() }\if{html}{\out{
}} @@ -291,7 +313,7 @@ through but should \code{stop()} if there is a single test unit failing. The behavior of side effects can be customized with the \code{actions} option. \if{html}{\out{
}}\preformatted{small_table \%>\% - col_is_numeric(columns = vars(d)) \%>\% + col_is_numeric(columns = d) \%>\% dplyr::slice(1:5) #> # A tibble: 5 x 8 #> date_time date a b c d e f @@ -309,7 +331,7 @@ behavior of side effects can be customized with the \code{actions} option. With the \verb{expect_*()} form, we would typically perform one validation at a time. This is primarily used in \strong{testthat} tests. -\if{html}{\out{
}}\preformatted{expect_col_is_numeric(small_table, columns = vars(d)) +\if{html}{\out{
}}\preformatted{expect_col_is_numeric(small_table, columns = d) }\if{html}{\out{
}} } @@ -318,7 +340,7 @@ time. This is primarily used in \strong{testthat} tests. With the \verb{test_*()} form, we should get a single logical value returned to us. -\if{html}{\out{
}}\preformatted{small_table \%>\% test_col_is_numeric(columns = vars(d)) +\if{html}{\out{
}}\preformatted{small_table \%>\% test_col_is_numeric(columns = d) #> [1] TRUE }\if{html}{\out{
}} } @@ -344,12 +366,12 @@ Other validation functions: \code{\link{col_vals_decreasing}()}, \code{\link{col_vals_equal}()}, \code{\link{col_vals_expr}()}, -\code{\link{col_vals_gte}()}, \code{\link{col_vals_gt}()}, +\code{\link{col_vals_gte}()}, \code{\link{col_vals_in_set}()}, \code{\link{col_vals_increasing}()}, -\code{\link{col_vals_lte}()}, \code{\link{col_vals_lt}()}, +\code{\link{col_vals_lte}()}, \code{\link{col_vals_make_set}()}, \code{\link{col_vals_make_subset}()}, \code{\link{col_vals_not_between}()}, diff --git a/man/col_is_posix.Rd b/man/col_is_posix.Rd index da2efde82..64c6566c2 100644 --- a/man/col_is_posix.Rd +++ b/man/col_is_posix.Rd @@ -31,10 +31,11 @@ commonly created with \code{\link[=create_agent]{create_agent()}}.} \item{columns}{\emph{The target columns} -\verb{} // \strong{required} +\verb{} // \strong{required} -The column (or a set of columns, provided as a character vector) to which -this validation should be applied.} +A column-selecting expression, as one would use inside \code{dplyr::select()}. +Specifies the column (or a set of columns) to which this validation should +be applied. See the \emph{Column Names} section for more information.} \item{actions}{\emph{Thresholds and actions for different states} @@ -60,12 +61,13 @@ produce (influenced by the number of \code{columns} provided), (2) be an ID string not used in any previous validation step, and (3) be a vector with unique values.} -\item{label}{\emph{An optional label for the validation step} +\item{label}{\emph{Optional label for the validation step} -\verb{scalar} // \emph{default:} \code{NULL} (\code{optional}) +\verb{vector} // \emph{default:} \code{NULL} (\code{optional}) -An optional label for the validation step. This label appears in the -\emph{agent} report and, for the best appearance, it should be kept quite short.} +Optional label for the validation step. This label appears in the \emph{agent} +report and, for the best appearance, it should be kept quite short. See +the \emph{Labels} section for more information.} \item{brief}{\emph{Brief description for the validation step} @@ -92,7 +94,7 @@ be used with \code{.} (serving as the input data table) to evaluate to a single logical value. With this approach, the \strong{pointblank} function \code{\link[=has_columns]{has_columns()}} can be used to determine whether to make a validation step active on the basis of one or more columns existing in the table -(e.g., \code{~ . \%>\% has_columns(vars(d, e))}).} +(e.g., \code{~ . \%>\% has_columns(c(d, e))}).} \item{object}{\emph{A data table for expectations or tests} @@ -162,12 +164,17 @@ formally tested (so be mindful of this when using unsupported backends with \section{Column Names}{ -If providing multiple column names, the result will be an expansion of -validation steps to that number of column names (e.g., \code{vars(col_a, col_b)} -will result in the entry of two validation steps). Aside from column names in -quotes and in \code{vars()}, \strong{tidyselect} helper functions are available for -specifying columns. They are: \code{starts_with()}, \code{ends_with()}, \code{contains()}, -\code{matches()}, and \code{everything()}. +\code{columns} may be a single column (as symbol \code{a} or string \code{"a"}) or a vector +of columns (\code{c(a, b, c)} or \code{c("a", "b", "c")}). \code{{tidyselect}} helpers +are also supported, such as \code{contains("date")} and \code{where(is.double)}. If +passing an \emph{external vector} of columns, it should be wrapped in \code{all_of()}. + +When multiple columns are selected by \code{columns}, the result will be an +expansion of validation steps to that number of columns (e.g., +\code{c(col_a, col_b)} will result in the entry of two validation steps). + +Previously, columns could be specified in \code{vars()}. This continues to work, +but \code{c()} offers the same capability and supersedes \code{vars()} in \code{columns}. } \section{Actions}{ @@ -185,6 +192,21 @@ happens. For the \verb{col_is_*()}-type functions, using \code{action_levels(war situation (the first produces a warning, the other will \code{stop()}). } +\section{Labels}{ + + +\code{label} may be a single string or a character vector that matches the number +of expanded steps. \code{label} also supports \code{{glue}} syntax and exposes the +following dynamic variables contextualized to the current step: +\itemize{ +\item \code{"{.step}"}: The validation step name +\item \code{"{.col}"}: The current column name +} + +The glue context also supports ordinary expressions for further flexibility +(e.g., \code{"{toupper(.step)}"}) as long as they return a length-1 string. +} + \section{Briefs}{ @@ -211,7 +233,7 @@ R statement: \if{html}{\out{
}}\preformatted{agent \%>\% col_is_posix( - columns = vars(a), + columns = a, actions = action_levels(warn_at = 0.1, stop_at = 0.2), label = "The `col_is_posix()` step.", active = FALSE @@ -222,7 +244,7 @@ YAML representation: \if{html}{\out{
}}\preformatted{steps: - col_is_posix: - columns: vars(a) + columns: c(a) actions: warn_fraction: 0.1 stop_fraction: 0.2 @@ -269,7 +291,7 @@ Validate that the column \code{date_time} is indeed a date-time column. \if{html}{\out{
}}\preformatted{agent <- create_agent(tbl = small_table) \%>\% - col_is_posix(columns = vars(date_time)) \%>\% + col_is_posix(columns = date_time) \%>\% interrogate() }\if{html}{\out{
}} @@ -291,7 +313,7 @@ through but should \code{stop()} if there is a single test unit failing. The behavior of side effects can be customized with the \code{actions} option. \if{html}{\out{
}}\preformatted{small_table \%>\% - col_is_posix(columns = vars(date_time)) \%>\% + col_is_posix(columns = date_time) \%>\% dplyr::slice(1:5) #> # A tibble: 5 x 8 #> date_time date a b c d e f @@ -309,7 +331,7 @@ behavior of side effects can be customized with the \code{actions} option. With the \verb{expect_*()} form, we would typically perform one validation at a time. This is primarily used in \strong{testthat} tests. -\if{html}{\out{
}}\preformatted{expect_col_is_posix(small_table, columns = vars(date_time)) +\if{html}{\out{
}}\preformatted{expect_col_is_posix(small_table, columns = date_time) }\if{html}{\out{
}} } @@ -318,7 +340,7 @@ time. This is primarily used in \strong{testthat} tests. With the \verb{test_*()} form, we should get a single logical value returned to us. -\if{html}{\out{
}}\preformatted{small_table \%>\% test_col_is_posix(columns = vars(date_time)) +\if{html}{\out{
}}\preformatted{small_table \%>\% test_col_is_posix(columns = date_time) #> [1] TRUE }\if{html}{\out{
}} } @@ -344,12 +366,12 @@ Other validation functions: \code{\link{col_vals_decreasing}()}, \code{\link{col_vals_equal}()}, \code{\link{col_vals_expr}()}, -\code{\link{col_vals_gte}()}, \code{\link{col_vals_gt}()}, +\code{\link{col_vals_gte}()}, \code{\link{col_vals_in_set}()}, \code{\link{col_vals_increasing}()}, -\code{\link{col_vals_lte}()}, \code{\link{col_vals_lt}()}, +\code{\link{col_vals_lte}()}, \code{\link{col_vals_make_set}()}, \code{\link{col_vals_make_subset}()}, \code{\link{col_vals_not_between}()}, diff --git a/man/col_schema.Rd b/man/col_schema.Rd index 905673486..00daf5e7b 100644 --- a/man/col_schema.Rd +++ b/man/col_schema.Rd @@ -22,8 +22,8 @@ An option to use a table object to define the schema. If this is provided then any values provided to \code{...} will be ignored. This can either be a table object, a table-prep formula.This can be a table object such as a data frame, a tibble, a \code{tbl_dbi} object, or a \code{tbl_spark} object. -Alternatively, a table-prep formula (\verb{~
}) or a -function (\verb{function()
}) can be used to lazily read in +Alternatively, a table-prep formula (\verb{~ }) or a +function (\verb{function() }) can be used to lazily read in the table at interrogation time.} \item{.db_col_types}{\emph{Use R column types or database column types?} @@ -139,8 +139,8 @@ example. \seealso{ Other Utility and Helper Functions: -\code{\link{affix_datetime}()}, \code{\link{affix_date}()}, +\code{\link{affix_datetime}()}, \code{\link{from_github}()}, \code{\link{has_columns}()}, \code{\link{stop_if_not}()} diff --git a/man/col_schema_match.Rd b/man/col_schema_match.Rd index aea64c3d8..05683362f 100644 --- a/man/col_schema_match.Rd +++ b/man/col_schema_match.Rd @@ -110,12 +110,13 @@ produce (influenced by the number of \code{columns} provided), (2) be an ID string not used in any previous validation step, and (3) be a vector with unique values.} -\item{label}{\emph{An optional label for the validation step} +\item{label}{\emph{Optional label for the validation step} -\verb{scalar} // \emph{default:} \code{NULL} (\code{optional}) +\verb{vector} // \emph{default:} \code{NULL} (\code{optional}) -An optional label for the validation step. This label appears in the -\emph{agent} report and, for the best appearance, it should be kept quite short.} +Optional label for the validation step. This label appears in the \emph{agent} +report and, for the best appearance, it should be kept quite short. See +the \emph{Labels} section for more information.} \item{brief}{\emph{Brief description for the validation step} @@ -142,7 +143,7 @@ be used with \code{.} (serving as the input data table) to evaluate to a single logical value. With this approach, the \strong{pointblank} function \code{\link[=has_columns]{has_columns()}} can be used to determine whether to make a validation step active on the basis of one or more columns existing in the table -(e.g., \code{~ . \%>\% has_columns(vars(d, e))}).} +(e.g., \code{~ . \%>\% has_columns(c(d, e))}).} \item{object}{\emph{A data table for expectations or tests} @@ -241,6 +242,20 @@ depending on the situation (the first produces a warning, the other \code{stop()}s). } +\section{Labels}{ + + +\code{label} may be a single string or a character vector that matches the number +of expanded steps. \code{label} also supports \code{{glue}} syntax and exposes the +following dynamic variables contextualized to the current step: +\itemize{ +\item \code{"{.step}"}: The validation step name +} + +The glue context also supports ordinary expressions for further flexibility +(e.g., \code{"{toupper(.step)}"}) as long as they return a length-1 string. +} + \section{Briefs}{ @@ -429,12 +444,12 @@ Other validation functions: \code{\link{col_vals_decreasing}()}, \code{\link{col_vals_equal}()}, \code{\link{col_vals_expr}()}, -\code{\link{col_vals_gte}()}, \code{\link{col_vals_gt}()}, +\code{\link{col_vals_gte}()}, \code{\link{col_vals_in_set}()}, \code{\link{col_vals_increasing}()}, -\code{\link{col_vals_lte}()}, \code{\link{col_vals_lt}()}, +\code{\link{col_vals_lte}()}, \code{\link{col_vals_make_set}()}, \code{\link{col_vals_make_subset}()}, \code{\link{col_vals_not_between}()}, diff --git a/man/col_vals_between.Rd b/man/col_vals_between.Rd index 0b8544b5b..603926f7f 100644 --- a/man/col_vals_between.Rd +++ b/man/col_vals_between.Rd @@ -55,10 +55,11 @@ commonly created with \code{\link[=create_agent]{create_agent()}}.} \item{columns}{\emph{The target columns} -\verb{} // \strong{required} +\verb{} // \strong{required} -The column (or a set of columns, provided as a character vector) to which -this validation should be applied.} +A column-selecting expression, as one would use inside \code{dplyr::select()}. +Specifies the column (or a set of columns) to which this validation should +be applied. See the \emph{Column Names} section for more information.} \item{left}{\emph{Definition of left bound} @@ -136,12 +137,13 @@ produce (influenced by the number of \code{columns} provided), (2) be an ID string not used in any previous validation step, and (3) be a vector with unique values.} -\item{label}{\emph{An optional label for the validation step} +\item{label}{\emph{Optional label for the validation step} -\verb{scalar} // \emph{default:} \code{NULL} (\code{optional}) +\verb{vector} // \emph{default:} \code{NULL} (\code{optional}) -An optional label for the validation step. This label appears in the -\emph{agent} report and, for the best appearance, it should be kept quite short.} +Optional label for the validation step. This label appears in the \emph{agent} +report and, for the best appearance, it should be kept quite short. See +the \emph{Labels} section for more information.} \item{brief}{\emph{Brief description for the validation step} @@ -168,7 +170,7 @@ be used with \code{.} (serving as the input data table) to evaluate to a single logical value. With this approach, the \strong{pointblank} function \code{\link[=has_columns]{has_columns()}} can be used to determine whether to make a validation step active on the basis of one or more columns existing in the table -(e.g., \code{~ . \%>\% has_columns(vars(d, e))}).} +(e.g., \code{~ . \%>\% has_columns(c(d, e))}).} \item{object}{\emph{A data table for expectations or tests} @@ -245,12 +247,17 @@ formally tested (so be mindful of this when using unsupported backends with \section{Column Names}{ -If providing multiple column names to \code{columns}, the result will be an -expansion of validation steps to that number of column names (e.g., -\code{vars(col_a, col_b)} will result in the entry of two validation steps). Aside -from column names in quotes and in \code{vars()}, \strong{tidyselect} helper functions -are available for specifying columns. They are: \code{starts_with()}, -\code{ends_with()}, \code{contains()}, \code{matches()}, and \code{everything()}. +\code{columns} may be a single column (as symbol \code{a} or string \code{"a"}) or a vector +of columns (\code{c(a, b, c)} or \code{c("a", "b", "c")}). \code{{tidyselect}} helpers +are also supported, such as \code{contains("date")} and \code{where(is.double)}. If +passing an \emph{external vector} of columns, it should be wrapped in \code{all_of()}. + +When multiple columns are selected by \code{columns}, the result will be an +expansion of validation steps to that number of columns (e.g., +\code{c(col_a, col_b)} will result in the entry of two validation steps). + +Previously, columns could be specified in \code{vars()}. This continues to work, +but \code{c()} offers the same capability and supersedes \code{vars()} in \code{columns}. } \section{Missing Values}{ @@ -332,6 +339,23 @@ quarter of the total test units fails, the other \code{stop()}s at the same threshold level). } +\section{Labels}{ + + +\code{label} may be a single string or a character vector that matches the number +of expanded steps. \code{label} also supports \code{{glue}} syntax and exposes the +following dynamic variables contextualized to the current step: +\itemize{ +\item \code{"{.step}"}: The validation step name +\item \code{"{.col}"}: The current column name +\item \code{"{.seg_col}"}: The current segment's column name +\item \code{"{.seg_val}"}: The current segment's value/group +} + +The glue context also supports ordinary expressions for further flexibility +(e.g., \code{"{toupper(.step)}"}) as long as they return a length-1 string. +} + \section{Briefs}{ @@ -358,7 +382,7 @@ R statement: \if{html}{\out{
}}\preformatted{agent \%>\% col_vals_between( - columns = vars(a), + columns = a, left = 1, right = 2, inclusive = c(TRUE, FALSE), @@ -375,7 +399,7 @@ YAML representation: \if{html}{\out{
}}\preformatted{steps: - col_vals_between: - columns: vars(a) + columns: c(a) left: 1.0 right: 2.0 inclusive: @@ -433,7 +457,7 @@ are \code{NA} values, we'll choose to let those pass validation by setting \if{html}{\out{
}}\preformatted{agent <- create_agent(tbl = small_table) \%>\% col_vals_between( - columns = vars(c), + columns = c, left = 1, right = 9, na_pass = TRUE ) \%>\% @@ -459,7 +483,7 @@ behavior of side effects can be customized with the \code{actions} option. \if{html}{\out{
}}\preformatted{small_table \%>\% col_vals_between( - columns = vars(c), + columns = c, left = 1, right = 9, na_pass = TRUE ) \%>\% @@ -474,7 +498,7 @@ With the \verb{expect_*()} form, we would typically perform one validation at a time. This is primarily used in \strong{testthat} tests. \if{html}{\out{
}}\preformatted{expect_col_vals_between( - small_table, columns = vars(c), + small_table, columns = c, left = 1, right = 9, na_pass = TRUE ) @@ -488,7 +512,7 @@ us. \if{html}{\out{
}}\preformatted{small_table \%>\% test_col_vals_between( - columns = vars(c), + columns = c, left = 1, right = 9, na_pass = TRUE ) @@ -505,7 +529,7 @@ values are \code{9} and they now fall outside of the upper (or right) bound. \if{html}{\out{
}}\preformatted{small_table \%>\% test_col_vals_between( - columns = vars(c), left = 1, right = 9, + columns = c, left = 1, right = 9, inclusive = c(TRUE, FALSE), na_pass = TRUE ) @@ -536,12 +560,12 @@ Other validation functions: \code{\link{col_vals_decreasing}()}, \code{\link{col_vals_equal}()}, \code{\link{col_vals_expr}()}, -\code{\link{col_vals_gte}()}, \code{\link{col_vals_gt}()}, +\code{\link{col_vals_gte}()}, \code{\link{col_vals_in_set}()}, \code{\link{col_vals_increasing}()}, -\code{\link{col_vals_lte}()}, \code{\link{col_vals_lt}()}, +\code{\link{col_vals_lte}()}, \code{\link{col_vals_make_set}()}, \code{\link{col_vals_make_subset}()}, \code{\link{col_vals_not_between}()}, diff --git a/man/col_vals_decreasing.Rd b/man/col_vals_decreasing.Rd index fc02d3a42..1bcededc5 100644 --- a/man/col_vals_decreasing.Rd +++ b/man/col_vals_decreasing.Rd @@ -52,10 +52,11 @@ commonly created with \code{\link[=create_agent]{create_agent()}}.} \item{columns}{\emph{The target columns} -\verb{} // \strong{required} +\verb{} // \strong{required} -The column (or a set of columns, provided as a character vector) to which -this validation should be applied.} +A column-selecting expression, as one would use inside \code{dplyr::select()}. +Specifies the column (or a set of columns) to which this validation should +be applied. See the \emph{Column Names} section for more information.} \item{allow_stationary}{\emph{Allowance for stationary pauses in values} @@ -128,12 +129,13 @@ produce (influenced by the number of \code{columns} provided), (2) be an ID string not used in any previous validation step, and (3) be a vector with unique values.} -\item{label}{\emph{An optional label for the validation step} +\item{label}{\emph{Optional label for the validation step} -\verb{scalar} // \emph{default:} \code{NULL} (\code{optional}) +\verb{vector} // \emph{default:} \code{NULL} (\code{optional}) -An optional label for the validation step. This label appears in the -\emph{agent} report and, for the best appearance, it should be kept quite short.} +Optional label for the validation step. This label appears in the \emph{agent} +report and, for the best appearance, it should be kept quite short. See +the \emph{Labels} section for more information.} \item{brief}{\emph{Brief description for the validation step} @@ -160,7 +162,7 @@ be used with \code{.} (serving as the input data table) to evaluate to a single logical value. With this approach, the \strong{pointblank} function \code{\link[=has_columns]{has_columns()}} can be used to determine whether to make a validation step active on the basis of one or more columns existing in the table -(e.g., \code{~ . \%>\% has_columns(vars(d, e))}).} +(e.g., \code{~ . \%>\% has_columns(c(d, e))}).} \item{object}{\emph{A data table for expectations or tests} @@ -232,12 +234,17 @@ formally tested (so be mindful of this when using unsupported backends with \section{Column Names}{ -If providing multiple column names to \code{columns}, the result will be an -expansion of validation steps to that number of column names (e.g., -\code{vars(col_a, col_b)} will result in the entry of two validation steps). Aside -from column names in quotes and in \code{vars()}, \strong{tidyselect} helper functions -are available for specifying columns. They are: \code{starts_with()}, -\code{ends_with()}, \code{contains()}, \code{matches()}, and \code{everything()}. +\code{columns} may be a single column (as symbol \code{a} or string \code{"a"}) or a vector +of columns (\code{c(a, b, c)} or \code{c("a", "b", "c")}). \code{{tidyselect}} helpers +are also supported, such as \code{contains("date")} and \code{where(is.double)}. If +passing an \emph{external vector} of columns, it should be wrapped in \code{all_of()}. + +When multiple columns are selected by \code{columns}, the result will be an +expansion of validation steps to that number of columns (e.g., +\code{c(col_a, col_b)} will result in the entry of two validation steps). + +Previously, columns could be specified in \code{vars()}. This continues to work, +but \code{c()} offers the same capability and supersedes \code{vars()} in \code{columns}. } \section{Missing Values}{ @@ -319,6 +326,23 @@ quarter of the total test units fails, the other \code{stop()}s at the same threshold level). } +\section{Labels}{ + + +\code{label} may be a single string or a character vector that matches the number +of expanded steps. \code{label} also supports \code{{glue}} syntax and exposes the +following dynamic variables contextualized to the current step: +\itemize{ +\item \code{"{.step}"}: The validation step name +\item \code{"{.col}"}: The current column name +\item \code{"{.seg_col}"}: The current segment's column name +\item \code{"{.seg_val}"}: The current segment's value/group +} + +The glue context also supports ordinary expressions for further flexibility +(e.g., \code{"{toupper(.step)}"}) as long as they return a length-1 string. +} + \section{Briefs}{ @@ -345,7 +369,7 @@ R statement: \if{html}{\out{
}}\preformatted{agent \%>\% col_vals_decreasing( - columns = vars(a), + columns = a, allow_stationary = TRUE, increasing_tol = 0.5, na_pass = TRUE, @@ -361,7 +385,7 @@ YAML representation: \if{html}{\out{
}}\preformatted{steps: - col_vals_decreasing: - columns: vars(a) + columns: c(a) allow_stationary: true increasing_tol: 0.5 na_pass: true @@ -430,7 +454,7 @@ to \code{TRUE}). \if{html}{\out{
}}\preformatted{agent <- create_agent(tbl = game_revenue_2) \%>\% col_vals_decreasing( - columns = vars(time_left), + columns = time_left, allow_stationary = TRUE ) \%>\% interrogate() @@ -455,7 +479,7 @@ behavior of side effects can be customized with the \code{actions} option. \if{html}{\out{
}}\preformatted{game_revenue_2 \%>\% col_vals_decreasing( - columns = vars(time_left), + columns = time_left, allow_stationary = TRUE ) \%>\% dplyr::select(time_left) \%>\% @@ -475,7 +499,7 @@ time. This is primarily used in \strong{testthat} tests. \if{html}{\out{
}}\preformatted{expect_col_vals_decreasing( game_revenue_2, - columns = vars(time_left), + columns = time_left, allow_stationary = TRUE ) }\if{html}{\out{
}} @@ -488,7 +512,7 @@ us. \if{html}{\out{
}}\preformatted{game_revenue_2 \%>\% test_col_vals_decreasing( - columns = vars(time_left), + columns = time_left, allow_stationary = TRUE ) #> [1] TRUE @@ -519,12 +543,12 @@ Other validation functions: \code{\link{col_vals_between}()}, \code{\link{col_vals_equal}()}, \code{\link{col_vals_expr}()}, -\code{\link{col_vals_gte}()}, \code{\link{col_vals_gt}()}, +\code{\link{col_vals_gte}()}, \code{\link{col_vals_in_set}()}, \code{\link{col_vals_increasing}()}, -\code{\link{col_vals_lte}()}, \code{\link{col_vals_lt}()}, +\code{\link{col_vals_lte}()}, \code{\link{col_vals_make_set}()}, \code{\link{col_vals_make_subset}()}, \code{\link{col_vals_not_between}()}, diff --git a/man/col_vals_equal.Rd b/man/col_vals_equal.Rd index 237e3e164..d812e6ef8 100644 --- a/man/col_vals_equal.Rd +++ b/man/col_vals_equal.Rd @@ -49,10 +49,11 @@ commonly created with \code{\link[=create_agent]{create_agent()}}.} \item{columns}{\emph{The target columns} -\verb{} // \strong{required} +\verb{} // \strong{required} -The column (or a set of columns, provided as a character vector) to which -this validation should be applied.} +A column-selecting expression, as one would use inside \code{dplyr::select()}. +Specifies the column (or a set of columns) to which this validation should +be applied. See the \emph{Column Names} section for more information.} \item{value}{\emph{Value for comparison} @@ -113,12 +114,13 @@ produce (influenced by the number of \code{columns} provided), (2) be an ID string not used in any previous validation step, and (3) be a vector with unique values.} -\item{label}{\emph{An optional label for the validation step} +\item{label}{\emph{Optional label for the validation step} -\verb{scalar} // \emph{default:} \code{NULL} (\code{optional}) +\verb{vector} // \emph{default:} \code{NULL} (\code{optional}) -An optional label for the validation step. This label appears in the -\emph{agent} report and, for the best appearance, it should be kept quite short.} +Optional label for the validation step. This label appears in the \emph{agent} +report and, for the best appearance, it should be kept quite short. See +the \emph{Labels} section for more information.} \item{brief}{\emph{Brief description for the validation step} @@ -145,7 +147,7 @@ be used with \code{.} (serving as the input data table) to evaluate to a single logical value. With this approach, the \strong{pointblank} function \code{\link[=has_columns]{has_columns()}} can be used to determine whether to make a validation step active on the basis of one or more columns existing in the table -(e.g., \code{~ . \%>\% has_columns(vars(d, e))}).} +(e.g., \code{~ . \%>\% has_columns(c(d, e))}).} \item{object}{\emph{A data table for expectations or tests} @@ -215,12 +217,17 @@ formally tested (so be mindful of this when using unsupported backends with \section{Column Names}{ -If providing multiple column names to \code{columns}, the result will be an -expansion of validation steps to that number of column names (e.g., -\code{vars(col_a, col_b)} will result in the entry of two validation steps). Aside -from column names in quotes and in \code{vars()}, \strong{tidyselect} helper functions -are available for specifying columns. They are: \code{starts_with()}, -\code{ends_with()}, \code{contains()}, \code{matches()}, and \code{everything()}. +\code{columns} may be a single column (as symbol \code{a} or string \code{"a"}) or a vector +of columns (\code{c(a, b, c)} or \code{c("a", "b", "c")}). \code{{tidyselect}} helpers +are also supported, such as \code{contains("date")} and \code{where(is.double)}. If +passing an \emph{external vector} of columns, it should be wrapped in \code{all_of()}. + +When multiple columns are selected by \code{columns}, the result will be an +expansion of validation steps to that number of columns (e.g., +\code{c(col_a, col_b)} will result in the entry of two validation steps). + +Previously, columns could be specified in \code{vars()}. This continues to work, +but \code{c()} offers the same capability and supersedes \code{vars()} in \code{columns}. } \section{Missing Values}{ @@ -302,6 +309,23 @@ quarter of the total test units fails, the other \code{stop()}s at the same threshold level). } +\section{Labels}{ + + +\code{label} may be a single string or a character vector that matches the number +of expanded steps. \code{label} also supports \code{{glue}} syntax and exposes the +following dynamic variables contextualized to the current step: +\itemize{ +\item \code{"{.step}"}: The validation step name +\item \code{"{.col}"}: The current column name +\item \code{"{.seg_col}"}: The current segment's column name +\item \code{"{.seg_val}"}: The current segment's value/group +} + +The glue context also supports ordinary expressions for further flexibility +(e.g., \code{"{toupper(.step)}"}) as long as they return a length-1 string. +} + \section{Briefs}{ @@ -328,7 +352,7 @@ R statement: \if{html}{\out{
}}\preformatted{agent \%>\% col_vals_equal( - columns = vars(a), + columns = a, value = 1, na_pass = TRUE, preconditions = ~ . \%>\% dplyr::filter(a < 10), @@ -343,7 +367,7 @@ YAML representation: \if{html}{\out{
}}\preformatted{steps: - col_vals_equal: - columns: vars(a) + columns: c(a) value: 1.0 na_pass: true preconditions: ~. \%>\% dplyr::filter(a < 10) @@ -398,7 +422,7 @@ units, one for each row). \if{html}{\out{
}}\preformatted{agent <- create_agent(tbl = tbl) \%>\% - col_vals_equal(columns = vars(a), value = 5) \%>\% + col_vals_equal(columns = a, value = 5) \%>\% interrogate() }\if{html}{\out{
}} @@ -420,7 +444,7 @@ through but should \code{stop()} if there is a single test unit failing. The behavior of side effects can be customized with the \code{actions} option. \if{html}{\out{
}}\preformatted{tbl \%>\% - col_vals_equal(columns = vars(a), value = 5) \%>\% + col_vals_equal(columns = a, value = 5) \%>\% dplyr::pull(a) #> [1] 5 5 5 5 5 5 }\if{html}{\out{
}} @@ -431,7 +455,7 @@ behavior of side effects can be customized with the \code{actions} option. With the \verb{expect_*()} form, we would typically perform one validation at a time. This is primarily used in \strong{testthat} tests. -\if{html}{\out{
}}\preformatted{expect_col_vals_equal(tbl, columns = vars(a), value = 5) +\if{html}{\out{
}}\preformatted{expect_col_vals_equal(tbl, columns = a, value = 5) }\if{html}{\out{
}} } @@ -440,7 +464,7 @@ time. This is primarily used in \strong{testthat} tests. With the \verb{test_*()} form, we should get a single logical value returned to us. -\if{html}{\out{
}}\preformatted{test_col_vals_equal(tbl, columns = vars(a), value = 5) +\if{html}{\out{
}}\preformatted{test_col_vals_equal(tbl, columns = a, value = 5) #> [1] TRUE }\if{html}{\out{
}} } @@ -468,12 +492,12 @@ Other validation functions: \code{\link{col_vals_between}()}, \code{\link{col_vals_decreasing}()}, \code{\link{col_vals_expr}()}, -\code{\link{col_vals_gte}()}, \code{\link{col_vals_gt}()}, +\code{\link{col_vals_gte}()}, \code{\link{col_vals_in_set}()}, \code{\link{col_vals_increasing}()}, -\code{\link{col_vals_lte}()}, \code{\link{col_vals_lt}()}, +\code{\link{col_vals_lte}()}, \code{\link{col_vals_make_set}()}, \code{\link{col_vals_make_subset}()}, \code{\link{col_vals_not_between}()}, diff --git a/man/col_vals_expr.Rd b/man/col_vals_expr.Rd index f065d303c..ad2afea65 100644 --- a/man/col_vals_expr.Rd +++ b/man/col_vals_expr.Rd @@ -83,12 +83,13 @@ produce (influenced by the number of \code{columns} provided), (2) be an ID string not used in any previous validation step, and (3) be a vector with unique values.} -\item{label}{\emph{An optional label for the validation step} +\item{label}{\emph{Optional label for the validation step} -\verb{scalar} // \emph{default:} \code{NULL} (\code{optional}) +\verb{vector} // \emph{default:} \code{NULL} (\code{optional}) -An optional label for the validation step. This label appears in the -\emph{agent} report and, for the best appearance, it should be kept quite short.} +Optional label for the validation step. This label appears in the \emph{agent} +report and, for the best appearance, it should be kept quite short. See +the \emph{Labels} section for more information.} \item{brief}{\emph{Brief description for the validation step} @@ -115,7 +116,7 @@ be used with \code{.} (serving as the input data table) to evaluate to a single logical value. With this approach, the \strong{pointblank} function \code{\link[=has_columns]{has_columns()}} can be used to determine whether to make a validation step active on the basis of one or more columns existing in the table -(e.g., \code{~ . \%>\% has_columns(vars(d, e))}).} +(e.g., \code{~ . \%>\% has_columns(c(d, e))}).} \item{object}{\emph{A data table for expectations or tests} @@ -252,6 +253,23 @@ quarter of the total test units fails, the other \code{stop()}s at the same threshold level). } +\section{Labels}{ + + +\code{label} may be a single string or a character vector that matches the number +of expanded steps. \code{label} also supports \code{{glue}} syntax and exposes the +following dynamic variables contextualized to the current step: +\itemize{ +\item \code{"{.step}"}: The validation step name +\item \code{"{.col}"}: The current column name +\item \code{"{.seg_col}"}: The current segment's column name +\item \code{"{.seg_val}"}: The current segment's value/group +} + +The glue context also supports ordinary expressions for further flexibility +(e.g., \code{"{toupper(.step)}"}) as long as they return a length-1 string. +} + \section{Briefs}{ @@ -438,12 +456,12 @@ Other validation functions: \code{\link{col_vals_between}()}, \code{\link{col_vals_decreasing}()}, \code{\link{col_vals_equal}()}, -\code{\link{col_vals_gte}()}, \code{\link{col_vals_gt}()}, +\code{\link{col_vals_gte}()}, \code{\link{col_vals_in_set}()}, \code{\link{col_vals_increasing}()}, -\code{\link{col_vals_lte}()}, \code{\link{col_vals_lt}()}, +\code{\link{col_vals_lte}()}, \code{\link{col_vals_make_set}()}, \code{\link{col_vals_make_subset}()}, \code{\link{col_vals_not_between}()}, diff --git a/man/col_vals_gt.Rd b/man/col_vals_gt.Rd index ed4d4bb34..37fc5c40e 100644 --- a/man/col_vals_gt.Rd +++ b/man/col_vals_gt.Rd @@ -49,10 +49,11 @@ commonly created with \code{\link[=create_agent]{create_agent()}}.} \item{columns}{\emph{The target columns} -\verb{} // \strong{required} +\verb{} // \strong{required} -The column (or a set of columns, provided as a character vector) to which -this validation should be applied.} +A column-selecting expression, as one would use inside \code{dplyr::select()}. +Specifies the column (or a set of columns) to which this validation should +be applied. See the \emph{Column Names} section for more information.} \item{value}{\emph{Value for comparison} @@ -113,12 +114,13 @@ produce (influenced by the number of \code{columns} provided), (2) be an ID string not used in any previous validation step, and (3) be a vector with unique values.} -\item{label}{\emph{An optional label for the validation step} +\item{label}{\emph{Optional label for the validation step} -\verb{scalar} // \emph{default:} \code{NULL} (\code{optional}) +\verb{vector} // \emph{default:} \code{NULL} (\code{optional}) -An optional label for the validation step. This label appears in the -\emph{agent} report and, for the best appearance, it should be kept quite short.} +Optional label for the validation step. This label appears in the \emph{agent} +report and, for the best appearance, it should be kept quite short. See +the \emph{Labels} section for more information.} \item{brief}{\emph{Brief description for the validation step} @@ -145,7 +147,7 @@ be used with \code{.} (serving as the input data table) to evaluate to a single logical value. With this approach, the \strong{pointblank} function \code{\link[=has_columns]{has_columns()}} can be used to determine whether to make a validation step active on the basis of one or more columns existing in the table -(e.g., \code{~ . \%>\% has_columns(vars(d, e))}).} +(e.g., \code{~ . \%>\% has_columns(c(d, e))}).} \item{object}{\emph{A data table for expectations or tests} @@ -216,12 +218,17 @@ formally tested (so be mindful of this when using unsupported backends with \section{Column Names}{ -If providing multiple column names to \code{columns}, the result will be an -expansion of validation steps to that number of column names (e.g., -\code{vars(col_a, col_b)} will result in the entry of two validation steps). Aside -from column names in quotes and in \code{vars()}, \strong{tidyselect} helper functions -are available for specifying columns. They are: \code{starts_with()}, -\code{ends_with()}, \code{contains()}, \code{matches()}, and \code{everything()}. +\code{columns} may be a single column (as symbol \code{a} or string \code{"a"}) or a vector +of columns (\code{c(a, b, c)} or \code{c("a", "b", "c")}). \code{{tidyselect}} helpers +are also supported, such as \code{contains("date")} and \code{where(is.double)}. If +passing an \emph{external vector} of columns, it should be wrapped in \code{all_of()}. + +When multiple columns are selected by \code{columns}, the result will be an +expansion of validation steps to that number of columns (e.g., +\code{c(col_a, col_b)} will result in the entry of two validation steps). + +Previously, columns could be specified in \code{vars()}. This continues to work, +but \code{c()} offers the same capability and supersedes \code{vars()} in \code{columns}. } \section{Missing Values}{ @@ -303,6 +310,23 @@ quarter of the total test units fails, the other \code{stop()}s at the same threshold level). } +\section{Labels}{ + + +\code{label} may be a single string or a character vector that matches the number +of expanded steps. \code{label} also supports \code{{glue}} syntax and exposes the +following dynamic variables contextualized to the current step: +\itemize{ +\item \code{"{.step}"}: The validation step name +\item \code{"{.col}"}: The current column name +\item \code{"{.seg_col}"}: The current segment's column name +\item \code{"{.seg_val}"}: The current segment's value/group +} + +The glue context also supports ordinary expressions for further flexibility +(e.g., \code{"{toupper(.step)}"}) as long as they return a length-1 string. +} + \section{Briefs}{ @@ -329,7 +353,7 @@ R statement: \if{html}{\out{
}}\preformatted{agent \%>\% col_vals_gt( - columns = vars(a), + columns = a, value = 1, na_pass = TRUE, preconditions = ~ . \%>\% dplyr::filter(a < 10), @@ -344,7 +368,7 @@ YAML representation: \if{html}{\out{
}}\preformatted{steps: - col_vals_gt: - columns: vars(a) + columns: c(a) value: 1.0 na_pass: true preconditions: ~. \%>\% dplyr::filter(a < 10) @@ -399,7 +423,7 @@ test units, one for each row). \if{html}{\out{
}}\preformatted{agent <- create_agent(tbl = tbl) \%>\% - col_vals_gt(columns = vars(a), value = 4) \%>\% + col_vals_gt(columns = a, value = 4) \%>\% interrogate() }\if{html}{\out{
}} @@ -420,7 +444,7 @@ This way of using validation functions acts as a data filter. Data is passed through but should \code{stop()} if there is a single test unit failing. The behavior of side effects can be customized with the \code{actions} option. -\if{html}{\out{
}}\preformatted{tbl \%>\% col_vals_gt(columns = vars(a), value = 4) +\if{html}{\out{
}}\preformatted{tbl \%>\% col_vals_gt(columns = a, value = 4) #> # A tibble: 6 x 6 #> a b c d e f #> @@ -438,7 +462,7 @@ behavior of side effects can be customized with the \code{actions} option. With the \verb{expect_*()} form, we would typically perform one validation at a time. This is primarily used in \strong{testthat} tests. -\if{html}{\out{
}}\preformatted{expect_col_vals_gt(tbl, columns = vars(a), value = 4) +\if{html}{\out{
}}\preformatted{expect_col_vals_gt(tbl, columns = a, value = 4) }\if{html}{\out{
}} } @@ -447,7 +471,7 @@ time. This is primarily used in \strong{testthat} tests. With the \verb{test_*()} form, we should get a single logical value returned to us. -\if{html}{\out{
}}\preformatted{test_col_vals_gt(tbl, columns = vars(a), value = 4) +\if{html}{\out{
}}\preformatted{test_col_vals_gt(tbl, columns = a, value = 4) #> [1] TRUE }\if{html}{\out{
}} } @@ -479,8 +503,8 @@ Other validation functions: \code{\link{col_vals_gte}()}, \code{\link{col_vals_in_set}()}, \code{\link{col_vals_increasing}()}, -\code{\link{col_vals_lte}()}, \code{\link{col_vals_lt}()}, +\code{\link{col_vals_lte}()}, \code{\link{col_vals_make_set}()}, \code{\link{col_vals_make_subset}()}, \code{\link{col_vals_not_between}()}, diff --git a/man/col_vals_gte.Rd b/man/col_vals_gte.Rd index fa80a2bfe..e8029980e 100644 --- a/man/col_vals_gte.Rd +++ b/man/col_vals_gte.Rd @@ -50,10 +50,11 @@ commonly created with \code{\link[=create_agent]{create_agent()}}.} \item{columns}{\emph{The target columns} -\verb{} // \strong{required} +\verb{} // \strong{required} -The column (or a set of columns, provided as a character vector) to which -this validation should be applied.} +A column-selecting expression, as one would use inside \code{dplyr::select()}. +Specifies the column (or a set of columns) to which this validation should +be applied. See the \emph{Column Names} section for more information.} \item{value}{\emph{Value for comparison} @@ -114,12 +115,13 @@ produce (influenced by the number of \code{columns} provided), (2) be an ID string not used in any previous validation step, and (3) be a vector with unique values.} -\item{label}{\emph{An optional label for the validation step} +\item{label}{\emph{Optional label for the validation step} -\verb{scalar} // \emph{default:} \code{NULL} (\code{optional}) +\verb{vector} // \emph{default:} \code{NULL} (\code{optional}) -An optional label for the validation step. This label appears in the -\emph{agent} report and, for the best appearance, it should be kept quite short.} +Optional label for the validation step. This label appears in the \emph{agent} +report and, for the best appearance, it should be kept quite short. See +the \emph{Labels} section for more information.} \item{brief}{\emph{Brief description for the validation step} @@ -146,7 +148,7 @@ be used with \code{.} (serving as the input data table) to evaluate to a single logical value. With this approach, the \strong{pointblank} function \code{\link[=has_columns]{has_columns()}} can be used to determine whether to make a validation step active on the basis of one or more columns existing in the table -(e.g., \code{~ . \%>\% has_columns(vars(d, e))}).} +(e.g., \code{~ . \%>\% has_columns(c(d, e))}).} \item{object}{\emph{A data table for expectations or tests} @@ -217,12 +219,17 @@ formally tested (so be mindful of this when using unsupported backends with \section{Column Names}{ -If providing multiple column names to \code{columns}, the result will be an -expansion of validation steps to that number of column names (e.g., -\code{vars(col_a, col_b)} will result in the entry of two validation steps). Aside -from column names in quotes and in \code{vars()}, \strong{tidyselect} helper functions -are available for specifying columns. They are: \code{starts_with()}, -\code{ends_with()}, \code{contains()}, \code{matches()}, and \code{everything()}. +\code{columns} may be a single column (as symbol \code{a} or string \code{"a"}) or a vector +of columns (\code{c(a, b, c)} or \code{c("a", "b", "c")}). \code{{tidyselect}} helpers +are also supported, such as \code{contains("date")} and \code{where(is.double)}. If +passing an \emph{external vector} of columns, it should be wrapped in \code{all_of()}. + +When multiple columns are selected by \code{columns}, the result will be an +expansion of validation steps to that number of columns (e.g., +\code{c(col_a, col_b)} will result in the entry of two validation steps). + +Previously, columns could be specified in \code{vars()}. This continues to work, +but \code{c()} offers the same capability and supersedes \code{vars()} in \code{columns}. } \section{Missing Values}{ @@ -302,6 +309,23 @@ situation (the first produces a warning when a quarter of the total test units fails, the other \code{stop()}s at the same threshold level). } +\section{Labels}{ + + +\code{label} may be a single string or a character vector that matches the number +of expanded steps. \code{label} also supports \code{{glue}} syntax and exposes the +following dynamic variables contextualized to the current step: +\itemize{ +\item \code{"{.step}"}: The validation step name +\item \code{"{.col}"}: The current column name +\item \code{"{.seg_col}"}: The current segment's column name +\item \code{"{.seg_val}"}: The current segment's value/group +} + +The glue context also supports ordinary expressions for further flexibility +(e.g., \code{"{toupper(.step)}"}) as long as they return a length-1 string. +} + \section{Briefs}{ @@ -328,7 +352,7 @@ R statement: \if{html}{\out{
}}\preformatted{agent \%>\% col_vals_gte( - columns = vars(a), + columns = a, value = 1, na_pass = TRUE, preconditions = ~ . \%>\% dplyr::filter(a < 10), @@ -343,7 +367,7 @@ YAML representation: \if{html}{\out{
}}\preformatted{steps: - col_vals_gte: - columns: vars(a) + columns: c(a) value: 1.0 na_pass: true preconditions: ~. \%>\% dplyr::filter(a < 10) @@ -398,7 +422,7 @@ are 6 test units, one for each row). \if{html}{\out{
}}\preformatted{agent <- create_agent(tbl = tbl) \%>\% - col_vals_gte(columns = vars(a), value = 5) \%>\% + col_vals_gte(columns = a, value = 5) \%>\% interrogate() }\if{html}{\out{
}} @@ -419,7 +443,7 @@ This way of using validation functions acts as a data filter. Data is passed through but should \code{stop()} if there is a single test unit failing. The behavior of side effects can be customized with the \code{actions} option. -\if{html}{\out{
}}\preformatted{tbl \%>\% col_vals_gte(columns = vars(a), value = 5) +\if{html}{\out{
}}\preformatted{tbl \%>\% col_vals_gte(columns = a, value = 5) #> # A tibble: 6 x 6 #> a b c d e f #> @@ -437,7 +461,7 @@ behavior of side effects can be customized with the \code{actions} option. With the \verb{expect_*()} form, we would typically perform one validation at a time. This is primarily used in \strong{testthat} tests. -\if{html}{\out{
}}\preformatted{expect_col_vals_gte(tbl, columns = vars(a), value = 5) +\if{html}{\out{
}}\preformatted{expect_col_vals_gte(tbl, columns = a, value = 5) }\if{html}{\out{
}} } @@ -446,7 +470,7 @@ time. This is primarily used in \strong{testthat} tests. With the \verb{test_*()} form, we should get a single logical value returned to us. -\if{html}{\out{
}}\preformatted{test_col_vals_gte(tbl, columns = vars(a), value = 5) +\if{html}{\out{
}}\preformatted{test_col_vals_gte(tbl, columns = a, value = 5) #> [1] TRUE }\if{html}{\out{
}} } @@ -478,8 +502,8 @@ Other validation functions: \code{\link{col_vals_gt}()}, \code{\link{col_vals_in_set}()}, \code{\link{col_vals_increasing}()}, -\code{\link{col_vals_lte}()}, \code{\link{col_vals_lt}()}, +\code{\link{col_vals_lte}()}, \code{\link{col_vals_make_set}()}, \code{\link{col_vals_make_subset}()}, \code{\link{col_vals_not_between}()}, diff --git a/man/col_vals_in_set.Rd b/man/col_vals_in_set.Rd index 8386f6dcb..276799106 100644 --- a/man/col_vals_in_set.Rd +++ b/man/col_vals_in_set.Rd @@ -40,10 +40,11 @@ commonly created with \code{\link[=create_agent]{create_agent()}}.} \item{columns}{\emph{The target columns} -\verb{} // \strong{required} +\verb{} // \strong{required} -The column (or a set of columns, provided as a character vector) to which -this validation should be applied.} +A column-selecting expression, as one would use inside \code{dplyr::select()}. +Specifies the column (or a set of columns) to which this validation should +be applied. See the \emph{Column Names} section for more information.} \item{set}{\emph{Set of values} @@ -96,12 +97,13 @@ produce (influenced by the number of \code{columns} provided), (2) be an ID string not used in any previous validation step, and (3) be a vector with unique values.} -\item{label}{\emph{An optional label for the validation step} +\item{label}{\emph{Optional label for the validation step} -\verb{scalar} // \emph{default:} \code{NULL} (\code{optional}) +\verb{vector} // \emph{default:} \code{NULL} (\code{optional}) -An optional label for the validation step. This label appears in the -\emph{agent} report and, for the best appearance, it should be kept quite short.} +Optional label for the validation step. This label appears in the \emph{agent} +report and, for the best appearance, it should be kept quite short. See +the \emph{Labels} section for more information.} \item{brief}{\emph{Brief description for the validation step} @@ -128,7 +130,7 @@ be used with \code{.} (serving as the input data table) to evaluate to a single logical value. With this approach, the \strong{pointblank} function \code{\link[=has_columns]{has_columns()}} can be used to determine whether to make a validation step active on the basis of one or more columns existing in the table -(e.g., \code{~ . \%>\% has_columns(vars(d, e))}).} +(e.g., \code{~ . \%>\% has_columns(c(d, e))}).} \item{object}{\emph{A data table for expectations or tests} @@ -197,12 +199,17 @@ formally tested (so be mindful of this when using unsupported backends with \section{Column Names}{ -If providing multiple column names, the result will be an expansion of -validation steps to that number of column names (e.g., \code{vars(col_a, col_b)} -will result in the entry of two validation steps). Aside from column names in -quotes and in \code{vars()}, \strong{tidyselect} helper functions are available for -specifying columns. They are: \code{starts_with()}, \code{ends_with()}, \code{contains()}, -\code{matches()}, and \code{everything()}. +\code{columns} may be a single column (as symbol \code{a} or string \code{"a"}) or a vector +of columns (\code{c(a, b, c)} or \code{c("a", "b", "c")}). \code{{tidyselect}} helpers +are also supported, such as \code{contains("date")} and \code{where(is.double)}. If +passing an \emph{external vector} of columns, it should be wrapped in \code{all_of()}. + +When multiple columns are selected by \code{columns}, the result will be an +expansion of validation steps to that number of columns (e.g., +\code{c(col_a, col_b)} will result in the entry of two validation steps). + +Previously, columns could be specified in \code{vars()}. This continues to work, +but \code{c()} offers the same capability and supersedes \code{vars()} in \code{columns}. } \section{Preconditions}{ @@ -276,6 +283,23 @@ quarter of the total test units fails, the other \code{stop()}s at the same threshold level). } +\section{Labels}{ + + +\code{label} may be a single string or a character vector that matches the number +of expanded steps. \code{label} also supports \code{{glue}} syntax and exposes the +following dynamic variables contextualized to the current step: +\itemize{ +\item \code{"{.step}"}: The validation step name +\item \code{"{.col}"}: The current column name +\item \code{"{.seg_col}"}: The current segment's column name +\item \code{"{.seg_val}"}: The current segment's value/group +} + +The glue context also supports ordinary expressions for further flexibility +(e.g., \code{"{toupper(.step)}"}) as long as they return a length-1 string. +} + \section{Briefs}{ @@ -302,7 +326,7 @@ R statement: \if{html}{\out{
}}\preformatted{agent \%>\% col_vals_in_set( - columns = vars(a), + columns = a, set = c(1, 2, 3, 4), preconditions = ~ . \%>\% dplyr::filter(a < 10), segments = b ~ c("group_1", "group_2"), @@ -316,7 +340,7 @@ YAML representation: \if{html}{\out{
}}\preformatted{steps: - col_vals_in_set: - columns: vars(a) + columns: c(a) set: - 1.0 - 2.0 @@ -372,7 +396,7 @@ any failing test units (there are 13 test units, one for each row). \if{html}{\out{
}}\preformatted{agent <- create_agent(tbl = small_table) \%>\% col_vals_in_set( - columns = vars(f), set = c("low", "mid", "high") + columns = f, set = c("low", "mid", "high") ) \%>\% interrogate() }\if{html}{\out{
}} @@ -396,7 +420,7 @@ behavior of side effects can be customized with the \code{actions} option. \if{html}{\out{
}}\preformatted{small_table \%>\% col_vals_in_set( - columns = vars(f), set = c("low", "mid", "high") + columns = f, set = c("low", "mid", "high") ) \%>\% dplyr::pull(f) \%>\% unique() @@ -411,7 +435,7 @@ time. This is primarily used in \strong{testthat} tests. \if{html}{\out{
}}\preformatted{expect_col_vals_in_set( small_table, - columns = vars(f), set = c("low", "mid", "high") + columns = f, set = c("low", "mid", "high") ) }\if{html}{\out{
}} } @@ -423,7 +447,7 @@ us. \if{html}{\out{
}}\preformatted{small_table \%>\% test_col_vals_in_set( - columns = vars(f), set = c("low", "mid", "high") + columns = f, set = c("low", "mid", "high") ) #> [1] TRUE }\if{html}{\out{
}} @@ -453,11 +477,11 @@ Other validation functions: \code{\link{col_vals_decreasing}()}, \code{\link{col_vals_equal}()}, \code{\link{col_vals_expr}()}, -\code{\link{col_vals_gte}()}, \code{\link{col_vals_gt}()}, +\code{\link{col_vals_gte}()}, \code{\link{col_vals_increasing}()}, -\code{\link{col_vals_lte}()}, \code{\link{col_vals_lt}()}, +\code{\link{col_vals_lte}()}, \code{\link{col_vals_make_set}()}, \code{\link{col_vals_make_subset}()}, \code{\link{col_vals_not_between}()}, diff --git a/man/col_vals_increasing.Rd b/man/col_vals_increasing.Rd index f3043355b..3bc98a748 100644 --- a/man/col_vals_increasing.Rd +++ b/man/col_vals_increasing.Rd @@ -52,10 +52,11 @@ commonly created with \code{\link[=create_agent]{create_agent()}}.} \item{columns}{\emph{The target columns} -\verb{} // \strong{required} +\verb{} // \strong{required} -The column (or a set of columns, provided as a character vector) to which -this validation should be applied.} +A column-selecting expression, as one would use inside \code{dplyr::select()}. +Specifies the column (or a set of columns) to which this validation should +be applied. See the \emph{Column Names} section for more information.} \item{allow_stationary}{\emph{Allowance for stationary pauses in values} @@ -128,12 +129,13 @@ produce (influenced by the number of \code{columns} provided), (2) be an ID string not used in any previous validation step, and (3) be a vector with unique values.} -\item{label}{\emph{An optional label for the validation step} +\item{label}{\emph{Optional label for the validation step} -\verb{scalar} // \emph{default:} \code{NULL} (\code{optional}) +\verb{vector} // \emph{default:} \code{NULL} (\code{optional}) -An optional label for the validation step. This label appears in the -\emph{agent} report and, for the best appearance, it should be kept quite short.} +Optional label for the validation step. This label appears in the \emph{agent} +report and, for the best appearance, it should be kept quite short. See +the \emph{Labels} section for more information.} \item{brief}{\emph{Brief description for the validation step} @@ -160,7 +162,7 @@ be used with \code{.} (serving as the input data table) to evaluate to a single logical value. With this approach, the \strong{pointblank} function \code{\link[=has_columns]{has_columns()}} can be used to determine whether to make a validation step active on the basis of one or more columns existing in the table -(e.g., \code{~ . \%>\% has_columns(vars(d, e))}).} +(e.g., \code{~ . \%>\% has_columns(c(d, e))}).} \item{object}{\emph{A data table for expectations or tests} @@ -232,12 +234,17 @@ formally tested (so be mindful of this when using unsupported backends with \section{Column Names}{ -If providing multiple column names to \code{columns}, the result will be an -expansion of validation steps to that number of column names (e.g., -\code{vars(col_a, col_b)} will result in the entry of two validation steps). Aside -from column names in quotes and in \code{vars()}, \strong{tidyselect} helper functions -are available for specifying columns. They are: \code{starts_with()}, -\code{ends_with()}, \code{contains()}, \code{matches()}, and \code{everything()}. +\code{columns} may be a single column (as symbol \code{a} or string \code{"a"}) or a vector +of columns (\code{c(a, b, c)} or \code{c("a", "b", "c")}). \code{{tidyselect}} helpers +are also supported, such as \code{contains("date")} and \code{where(is.double)}. If +passing an \emph{external vector} of columns, it should be wrapped in \code{all_of()}. + +When multiple columns are selected by \code{columns}, the result will be an +expansion of validation steps to that number of columns (e.g., +\code{c(col_a, col_b)} will result in the entry of two validation steps). + +Previously, columns could be specified in \code{vars()}. This continues to work, +but \code{c()} offers the same capability and supersedes \code{vars()} in \code{columns}. } \section{Missing Values}{ @@ -319,6 +326,23 @@ quarter of the total test units fails, the other \code{stop()}s at the same threshold level). } +\section{Labels}{ + + +\code{label} may be a single string or a character vector that matches the number +of expanded steps. \code{label} also supports \code{{glue}} syntax and exposes the +following dynamic variables contextualized to the current step: +\itemize{ +\item \code{"{.step}"}: The validation step name +\item \code{"{.col}"}: The current column name +\item \code{"{.seg_col}"}: The current segment's column name +\item \code{"{.seg_val}"}: The current segment's value/group +} + +The glue context also supports ordinary expressions for further flexibility +(e.g., \code{"{toupper(.step)}"}) as long as they return a length-1 string. +} + \section{Briefs}{ @@ -345,7 +369,7 @@ R statement: \if{html}{\out{
}}\preformatted{agent \%>\% col_vals_increasing( - columns = vars(a), + columns = a, allow_stationary = TRUE, decreasing_tol = 0.5, na_pass = TRUE, @@ -361,7 +385,7 @@ YAML representation: \if{html}{\out{
}}\preformatted{steps: - col_vals_increasing: - columns: vars(a) + columns: c(a) allow_stationary: true decreasing_tol: 0.5 na_pass: true @@ -417,7 +441,7 @@ to \code{TRUE}). We'll determine if this validation has any failing test units \if{html}{\out{
}}\preformatted{agent <- create_agent(tbl = game_revenue) \%>\% col_vals_increasing( - columns = vars(session_start), + columns = session_start, allow_stationary = TRUE ) \%>\% interrogate() @@ -442,7 +466,7 @@ behavior of side effects can be customized with the \code{actions} option. \if{html}{\out{
}}\preformatted{game_revenue \%>\% col_vals_increasing( - columns = vars(session_start), + columns = session_start, allow_stationary = TRUE ) \%>\% dplyr::select(session_start) \%>\% @@ -462,7 +486,7 @@ time. This is primarily used in \strong{testthat} tests. \if{html}{\out{
}}\preformatted{expect_col_vals_increasing( game_revenue, - columns = vars(session_start), + columns = session_start, allow_stationary = TRUE ) }\if{html}{\out{
}} @@ -475,7 +499,7 @@ us. \if{html}{\out{
}}\preformatted{game_revenue \%>\% test_col_vals_increasing( - columns = vars(session_start), + columns = session_start, allow_stationary = TRUE ) #> [1] TRUE @@ -507,11 +531,11 @@ Other validation functions: \code{\link{col_vals_decreasing}()}, \code{\link{col_vals_equal}()}, \code{\link{col_vals_expr}()}, -\code{\link{col_vals_gte}()}, \code{\link{col_vals_gt}()}, +\code{\link{col_vals_gte}()}, \code{\link{col_vals_in_set}()}, -\code{\link{col_vals_lte}()}, \code{\link{col_vals_lt}()}, +\code{\link{col_vals_lte}()}, \code{\link{col_vals_make_set}()}, \code{\link{col_vals_make_subset}()}, \code{\link{col_vals_not_between}()}, diff --git a/man/col_vals_lt.Rd b/man/col_vals_lt.Rd index 0af9dd513..6685582e4 100644 --- a/man/col_vals_lt.Rd +++ b/man/col_vals_lt.Rd @@ -49,10 +49,11 @@ commonly created with \code{\link[=create_agent]{create_agent()}}.} \item{columns}{\emph{The target columns} -\verb{} // \strong{required} +\verb{} // \strong{required} -The column (or a set of columns, provided as a character vector) to which -this validation should be applied.} +A column-selecting expression, as one would use inside \code{dplyr::select()}. +Specifies the column (or a set of columns) to which this validation should +be applied. See the \emph{Column Names} section for more information.} \item{value}{\emph{Value for comparison} @@ -113,12 +114,13 @@ produce (influenced by the number of \code{columns} provided), (2) be an ID string not used in any previous validation step, and (3) be a vector with unique values.} -\item{label}{\emph{An optional label for the validation step} +\item{label}{\emph{Optional label for the validation step} -\verb{scalar} // \emph{default:} \code{NULL} (\code{optional}) +\verb{vector} // \emph{default:} \code{NULL} (\code{optional}) -An optional label for the validation step. This label appears in the -\emph{agent} report and, for the best appearance, it should be kept quite short.} +Optional label for the validation step. This label appears in the \emph{agent} +report and, for the best appearance, it should be kept quite short. See +the \emph{Labels} section for more information.} \item{brief}{\emph{Brief description for the validation step} @@ -145,7 +147,7 @@ be used with \code{.} (serving as the input data table) to evaluate to a single logical value. With this approach, the \strong{pointblank} function \code{\link[=has_columns]{has_columns()}} can be used to determine whether to make a validation step active on the basis of one or more columns existing in the table -(e.g., \code{~ . \%>\% has_columns(vars(d, e))}).} +(e.g., \code{~ . \%>\% has_columns(c(d, e))}).} \item{object}{\emph{A data table for expectations or tests} @@ -216,12 +218,17 @@ formally tested (so be mindful of this when using unsupported backends with \section{Column Names}{ -If providing multiple column names to \code{columns}, the result will be an -expansion of validation steps to that number of column names (e.g., -\code{vars(col_a, col_b)} will result in the entry of two validation steps). Aside -from column names in quotes and in \code{vars()}, \strong{tidyselect} helper functions -are available for specifying columns. They are: \code{starts_with()}, -\code{ends_with()}, \code{contains()}, \code{matches()}, and \code{everything()}. +\code{columns} may be a single column (as symbol \code{a} or string \code{"a"}) or a vector +of columns (\code{c(a, b, c)} or \code{c("a", "b", "c")}). \code{{tidyselect}} helpers +are also supported, such as \code{contains("date")} and \code{where(is.double)}. If +passing an \emph{external vector} of columns, it should be wrapped in \code{all_of()}. + +When multiple columns are selected by \code{columns}, the result will be an +expansion of validation steps to that number of columns (e.g., +\code{c(col_a, col_b)} will result in the entry of two validation steps). + +Previously, columns could be specified in \code{vars()}. This continues to work, +but \code{c()} offers the same capability and supersedes \code{vars()} in \code{columns}. } \section{Missing Values}{ @@ -303,6 +310,23 @@ quarter of the total test units fails, the other \code{stop()}s at the same threshold level). } +\section{Labels}{ + + +\code{label} may be a single string or a character vector that matches the number +of expanded steps. \code{label} also supports \code{{glue}} syntax and exposes the +following dynamic variables contextualized to the current step: +\itemize{ +\item \code{"{.step}"}: The validation step name +\item \code{"{.col}"}: The current column name +\item \code{"{.seg_col}"}: The current segment's column name +\item \code{"{.seg_val}"}: The current segment's value/group +} + +The glue context also supports ordinary expressions for further flexibility +(e.g., \code{"{toupper(.step)}"}) as long as they return a length-1 string. +} + \section{Briefs}{ @@ -329,7 +353,7 @@ R statement: \if{html}{\out{
}}\preformatted{agent \%>\% col_vals_lt( - columns = vars(a), + columns = a, value = 1, na_pass = TRUE, preconditions = ~ . \%>\% dplyr::filter(a < 10), @@ -344,7 +368,7 @@ YAML representation: \if{html}{\out{
}}\preformatted{steps: - col_vals_lt: - columns: vars(a) + columns: c(a) value: 1.0 na_pass: true preconditions: ~. \%>\% dplyr::filter(a < 10) @@ -399,7 +423,7 @@ units, one for each row). \if{html}{\out{
}}\preformatted{agent <- create_agent(tbl = tbl) \%>\% - col_vals_lt(columns = vars(c), value = 5) \%>\% + col_vals_lt(columns = c, value = 5) \%>\% interrogate() }\if{html}{\out{
}} @@ -421,7 +445,7 @@ through but should \code{stop()} if there is a single test unit failing. The behavior of side effects can be customized with the \code{actions} option. \if{html}{\out{
}}\preformatted{tbl \%>\% - col_vals_lt(columns = vars(c), value = 5) \%>\% + col_vals_lt(columns = c, value = 5) \%>\% dplyr::pull(c) #> [1] 1 1 1 2 3 4 }\if{html}{\out{
}} @@ -432,7 +456,7 @@ behavior of side effects can be customized with the \code{actions} option. With the \verb{expect_*()} form, we would typically perform one validation at a time. This is primarily used in \strong{testthat} tests. -\if{html}{\out{
}}\preformatted{expect_col_vals_lt(tbl, columns = vars(c), value = 5) +\if{html}{\out{
}}\preformatted{expect_col_vals_lt(tbl, columns = c, value = 5) }\if{html}{\out{
}} } @@ -441,7 +465,7 @@ time. This is primarily used in \strong{testthat} tests. With the \verb{test_*()} form, we should get a single logical value returned to us. -\if{html}{\out{
}}\preformatted{test_col_vals_lt(tbl, columns = vars(c), value = 5) +\if{html}{\out{
}}\preformatted{test_col_vals_lt(tbl, columns = c, value = 5) #> [1] TRUE }\if{html}{\out{
}} } @@ -470,8 +494,8 @@ Other validation functions: \code{\link{col_vals_decreasing}()}, \code{\link{col_vals_equal}()}, \code{\link{col_vals_expr}()}, -\code{\link{col_vals_gte}()}, \code{\link{col_vals_gt}()}, +\code{\link{col_vals_gte}()}, \code{\link{col_vals_in_set}()}, \code{\link{col_vals_increasing}()}, \code{\link{col_vals_lte}()}, diff --git a/man/col_vals_lte.Rd b/man/col_vals_lte.Rd index 54049914c..93ce82291 100644 --- a/man/col_vals_lte.Rd +++ b/man/col_vals_lte.Rd @@ -50,10 +50,11 @@ commonly created with \code{\link[=create_agent]{create_agent()}}.} \item{columns}{\emph{The target columns} -\verb{} // \strong{required} +\verb{} // \strong{required} -The column (or a set of columns, provided as a character vector) to which -this validation should be applied.} +A column-selecting expression, as one would use inside \code{dplyr::select()}. +Specifies the column (or a set of columns) to which this validation should +be applied. See the \emph{Column Names} section for more information.} \item{value}{\emph{Value for comparison} @@ -114,12 +115,13 @@ produce (influenced by the number of \code{columns} provided), (2) be an ID string not used in any previous validation step, and (3) be a vector with unique values.} -\item{label}{\emph{An optional label for the validation step} +\item{label}{\emph{Optional label for the validation step} -\verb{scalar} // \emph{default:} \code{NULL} (\code{optional}) +\verb{vector} // \emph{default:} \code{NULL} (\code{optional}) -An optional label for the validation step. This label appears in the -\emph{agent} report and, for the best appearance, it should be kept quite short.} +Optional label for the validation step. This label appears in the \emph{agent} +report and, for the best appearance, it should be kept quite short. See +the \emph{Labels} section for more information.} \item{brief}{\emph{Brief description for the validation step} @@ -146,7 +148,7 @@ be used with \code{.} (serving as the input data table) to evaluate to a single logical value. With this approach, the \strong{pointblank} function \code{\link[=has_columns]{has_columns()}} can be used to determine whether to make a validation step active on the basis of one or more columns existing in the table -(e.g., \code{~ . \%>\% has_columns(vars(d, e))}).} +(e.g., \code{~ . \%>\% has_columns(c(d, e))}).} \item{object}{\emph{A data table for expectations or tests} @@ -217,12 +219,17 @@ formally tested (so be mindful of this when using unsupported backends with \section{Column Names}{ -If providing multiple column names to \code{columns}, the result will be an -expansion of validation steps to that number of column names (e.g., -\code{vars(col_a, col_b)} will result in the entry of two validation steps). Aside -from column names in quotes and in \code{vars()}, \strong{tidyselect} helper functions -are available for specifying columns. They are: \code{starts_with()}, -\code{ends_with()}, \code{contains()}, \code{matches()}, and \code{everything()}. +\code{columns} may be a single column (as symbol \code{a} or string \code{"a"}) or a vector +of columns (\code{c(a, b, c)} or \code{c("a", "b", "c")}). \code{{tidyselect}} helpers +are also supported, such as \code{contains("date")} and \code{where(is.double)}. If +passing an \emph{external vector} of columns, it should be wrapped in \code{all_of()}. + +When multiple columns are selected by \code{columns}, the result will be an +expansion of validation steps to that number of columns (e.g., +\code{c(col_a, col_b)} will result in the entry of two validation steps). + +Previously, columns could be specified in \code{vars()}. This continues to work, +but \code{c()} offers the same capability and supersedes \code{vars()} in \code{columns}. } \section{Missing Values}{ @@ -304,6 +311,23 @@ quarter of the total test units fails, the other \code{stop()}s at the same threshold level). } +\section{Labels}{ + + +\code{label} may be a single string or a character vector that matches the number +of expanded steps. \code{label} also supports \code{{glue}} syntax and exposes the +following dynamic variables contextualized to the current step: +\itemize{ +\item \code{"{.step}"}: The validation step name +\item \code{"{.col}"}: The current column name +\item \code{"{.seg_col}"}: The current segment's column name +\item \code{"{.seg_val}"}: The current segment's value/group +} + +The glue context also supports ordinary expressions for further flexibility +(e.g., \code{"{toupper(.step)}"}) as long as they return a length-1 string. +} + \section{Briefs}{ @@ -330,7 +354,7 @@ R statement: \if{html}{\out{
}}\preformatted{agent \%>\% col_vals_lte( - columns = vars(a), + columns = a, value = 1, na_pass = TRUE, preconditions = ~ . \%>\% dplyr::filter(a < 10), @@ -345,7 +369,7 @@ YAML representation: \if{html}{\out{
}}\preformatted{steps: - col_vals_lte: - columns: vars(a) + columns: c(a) value: 1.0 na_pass: true preconditions: ~. \%>\% dplyr::filter(a < 10) @@ -400,7 +424,7 @@ Validate that values in column \code{c} are all less than or equal to the value \if{html}{\out{
}}\preformatted{agent <- create_agent(tbl = tbl) \%>\% - col_vals_lte(columns = vars(c), value = 4) \%>\% + col_vals_lte(columns = c, value = 4) \%>\% interrogate() }\if{html}{\out{
}} @@ -422,7 +446,7 @@ through but should \code{stop()} if there is a single test unit failing. The behavior of side effects can be customized with the \code{actions} option. \if{html}{\out{
}}\preformatted{tbl \%>\% - col_vals_lte(columns = vars(c), value = 4) \%>\% + col_vals_lte(columns = c, value = 4) \%>\% dplyr::pull(c) #> [1] 1 1 1 2 3 4 }\if{html}{\out{
}} @@ -433,7 +457,7 @@ behavior of side effects can be customized with the \code{actions} option. With the \verb{expect_*()} form, we would typically perform one validation at a time. This is primarily used in \strong{testthat} tests. -\if{html}{\out{
}}\preformatted{expect_col_vals_lte(tbl, columns = vars(c), value = 4) +\if{html}{\out{
}}\preformatted{expect_col_vals_lte(tbl, columns = c, value = 4) }\if{html}{\out{
}} } @@ -442,7 +466,7 @@ time. This is primarily used in \strong{testthat} tests. With the \verb{test_*()} form, we should get a single logical value returned to us. -\if{html}{\out{
}}\preformatted{test_col_vals_lte(tbl, columns = vars(c), value = 4) +\if{html}{\out{
}}\preformatted{test_col_vals_lte(tbl, columns = c, value = 4) #> [1] TRUE }\if{html}{\out{
}} } @@ -471,8 +495,8 @@ Other validation functions: \code{\link{col_vals_decreasing}()}, \code{\link{col_vals_equal}()}, \code{\link{col_vals_expr}()}, -\code{\link{col_vals_gte}()}, \code{\link{col_vals_gt}()}, +\code{\link{col_vals_gte}()}, \code{\link{col_vals_in_set}()}, \code{\link{col_vals_increasing}()}, \code{\link{col_vals_lt}()}, diff --git a/man/col_vals_make_set.Rd b/man/col_vals_make_set.Rd index de82d9c57..62c119e3c 100644 --- a/man/col_vals_make_set.Rd +++ b/man/col_vals_make_set.Rd @@ -46,10 +46,11 @@ commonly created with \code{\link[=create_agent]{create_agent()}}.} \item{columns}{\emph{The target columns} -\verb{} // \strong{required} +\verb{} // \strong{required} -The column (or a set of columns, provided as a character vector) to which -this validation should be applied.} +A column-selecting expression, as one would use inside \code{dplyr::select()}. +Specifies the column (or a set of columns) to which this validation should +be applied. See the \emph{Column Names} section for more information.} \item{set}{\emph{Set of values} @@ -102,12 +103,13 @@ produce (influenced by the number of \code{columns} provided), (2) be an ID string not used in any previous validation step, and (3) be a vector with unique values.} -\item{label}{\emph{An optional label for the validation step} +\item{label}{\emph{Optional label for the validation step} -\verb{scalar} // \emph{default:} \code{NULL} (\code{optional}) +\verb{vector} // \emph{default:} \code{NULL} (\code{optional}) -An optional label for the validation step. This label appears in the -\emph{agent} report and, for the best appearance, it should be kept quite short.} +Optional label for the validation step. This label appears in the \emph{agent} +report and, for the best appearance, it should be kept quite short. See +the \emph{Labels} section for more information.} \item{brief}{\emph{Brief description for the validation step} @@ -134,7 +136,7 @@ be used with \code{.} (serving as the input data table) to evaluate to a single logical value. With this approach, the \strong{pointblank} function \code{\link[=has_columns]{has_columns()}} can be used to determine whether to make a validation step active on the basis of one or more columns existing in the table -(e.g., \code{~ . \%>\% has_columns(vars(d, e))}).} +(e.g., \code{~ . \%>\% has_columns(c(d, e))}).} \item{object}{\emph{A data table for expectations or tests} @@ -207,12 +209,17 @@ formally tested (so be mindful of this when using unsupported backends with \section{Column Names}{ -If providing multiple column names, the result will be an expansion of -validation steps to that number of column names (e.g., \code{vars(col_a, col_b)} -will result in the entry of two validation steps). Aside from column names in -quotes and in \code{vars()}, \strong{tidyselect} helper functions are available for -specifying columns. They are: \code{starts_with()}, \code{ends_with()}, \code{contains()}, -\code{matches()}, and \code{everything()}. +\code{columns} may be a single column (as symbol \code{a} or string \code{"a"}) or a vector +of columns (\code{c(a, b, c)} or \code{c("a", "b", "c")}). \code{{tidyselect}} helpers +are also supported, such as \code{contains("date")} and \code{where(is.double)}. If +passing an \emph{external vector} of columns, it should be wrapped in \code{all_of()}. + +When multiple columns are selected by \code{columns}, the result will be an +expansion of validation steps to that number of columns (e.g., +\code{c(col_a, col_b)} will result in the entry of two validation steps). + +Previously, columns could be specified in \code{vars()}. This continues to work, +but \code{c()} offers the same capability and supersedes \code{vars()} in \code{columns}. } \section{Preconditions}{ @@ -286,6 +293,23 @@ quarter of the total test units fails, the other \code{stop()}s at the same threshold level). } +\section{Labels}{ + + +\code{label} may be a single string or a character vector that matches the number +of expanded steps. \code{label} also supports \code{{glue}} syntax and exposes the +following dynamic variables contextualized to the current step: +\itemize{ +\item \code{"{.step}"}: The validation step name +\item \code{"{.col}"}: The current column name +\item \code{"{.seg_col}"}: The current segment's column name +\item \code{"{.seg_val}"}: The current segment's value/group +} + +The glue context also supports ordinary expressions for further flexibility +(e.g., \code{"{toupper(.step)}"}) as long as they return a length-1 string. +} + \section{Briefs}{ @@ -312,7 +336,7 @@ R statement: \if{html}{\out{
}}\preformatted{agent \%>\% col_vals_make_set( - columns = vars(a), + columns = a, set = c(1, 2, 3, 4), preconditions = ~ . \%>\% dplyr::filter(a < 10), segments = b ~ c("group_1", "group_2"), @@ -326,7 +350,7 @@ YAML representation: \if{html}{\out{
}}\preformatted{steps: - col_vals_make_set: - columns: vars(a) + columns: c(a) set: - 1.0 - 2.0 @@ -382,7 +406,7 @@ failing test units (there are 4 test units). \if{html}{\out{
}}\preformatted{agent <- create_agent(tbl = small_table) \%>\% col_vals_make_set( - columns = vars(f), set = c("low", "mid", "high") + columns = f, set = c("low", "mid", "high") ) \%>\% interrogate() }\if{html}{\out{
}} @@ -406,7 +430,7 @@ behavior of side effects can be customized with the \code{actions} option. \if{html}{\out{
}}\preformatted{small_table \%>\% col_vals_make_set( - columns = vars(f), set = c("low", "mid", "high") + columns = f, set = c("low", "mid", "high") ) \%>\% dplyr::pull(f) \%>\% unique() @@ -421,7 +445,7 @@ time. This is primarily used in \strong{testthat} tests. \if{html}{\out{
}}\preformatted{expect_col_vals_make_set( small_table, - columns = vars(f), set = c("low", "mid", "high") + columns = f, set = c("low", "mid", "high") ) }\if{html}{\out{
}} } @@ -433,7 +457,7 @@ us. \if{html}{\out{
}}\preformatted{small_table \%>\% test_col_vals_make_set( - columns = vars(f), set = c("low", "mid", "high") + columns = f, set = c("low", "mid", "high") ) #> [1] TRUE }\if{html}{\out{
}} @@ -461,12 +485,12 @@ Other validation functions: \code{\link{col_vals_decreasing}()}, \code{\link{col_vals_equal}()}, \code{\link{col_vals_expr}()}, -\code{\link{col_vals_gte}()}, \code{\link{col_vals_gt}()}, +\code{\link{col_vals_gte}()}, \code{\link{col_vals_in_set}()}, \code{\link{col_vals_increasing}()}, -\code{\link{col_vals_lte}()}, \code{\link{col_vals_lt}()}, +\code{\link{col_vals_lte}()}, \code{\link{col_vals_make_subset}()}, \code{\link{col_vals_not_between}()}, \code{\link{col_vals_not_equal}()}, diff --git a/man/col_vals_make_subset.Rd b/man/col_vals_make_subset.Rd index d3031784a..f4289f19a 100644 --- a/man/col_vals_make_subset.Rd +++ b/man/col_vals_make_subset.Rd @@ -46,10 +46,11 @@ commonly created with \code{\link[=create_agent]{create_agent()}}.} \item{columns}{\emph{The target columns} -\verb{} // \strong{required} +\verb{} // \strong{required} -The column (or a set of columns, provided as a character vector) to which -this validation should be applied.} +A column-selecting expression, as one would use inside \code{dplyr::select()}. +Specifies the column (or a set of columns) to which this validation should +be applied. See the \emph{Column Names} section for more information.} \item{set}{\emph{Set of values} @@ -102,12 +103,13 @@ produce (influenced by the number of \code{columns} provided), (2) be an ID string not used in any previous validation step, and (3) be a vector with unique values.} -\item{label}{\emph{An optional label for the validation step} +\item{label}{\emph{Optional label for the validation step} -\verb{scalar} // \emph{default:} \code{NULL} (\code{optional}) +\verb{vector} // \emph{default:} \code{NULL} (\code{optional}) -An optional label for the validation step. This label appears in the -\emph{agent} report and, for the best appearance, it should be kept quite short.} +Optional label for the validation step. This label appears in the \emph{agent} +report and, for the best appearance, it should be kept quite short. See +the \emph{Labels} section for more information.} \item{brief}{\emph{Brief description for the validation step} @@ -134,7 +136,7 @@ be used with \code{.} (serving as the input data table) to evaluate to a single logical value. With this approach, the \strong{pointblank} function \code{\link[=has_columns]{has_columns()}} can be used to determine whether to make a validation step active on the basis of one or more columns existing in the table -(e.g., \code{~ . \%>\% has_columns(vars(d, e))}).} +(e.g., \code{~ . \%>\% has_columns(c(d, e))}).} \item{object}{\emph{A data table for expectations or tests} @@ -203,12 +205,17 @@ formally tested (so be mindful of this when using unsupported backends with \section{Column Names}{ -If providing multiple column names, the result will be an expansion of -validation steps to that number of column names (e.g., \code{vars(col_a, col_b)} -will result in the entry of two validation steps). Aside from column names in -quotes and in \code{vars()}, \strong{tidyselect} helper functions are available for -specifying columns. They are: \code{starts_with()}, \code{ends_with()}, \code{contains()}, -\code{matches()}, and \code{everything()}. +\code{columns} may be a single column (as symbol \code{a} or string \code{"a"}) or a vector +of columns (\code{c(a, b, c)} or \code{c("a", "b", "c")}). \code{{tidyselect}} helpers +are also supported, such as \code{contains("date")} and \code{where(is.double)}. If +passing an \emph{external vector} of columns, it should be wrapped in \code{all_of()}. + +When multiple columns are selected by \code{columns}, the result will be an +expansion of validation steps to that number of columns (e.g., +\code{c(col_a, col_b)} will result in the entry of two validation steps). + +Previously, columns could be specified in \code{vars()}. This continues to work, +but \code{c()} offers the same capability and supersedes \code{vars()} in \code{columns}. } \section{Preconditions}{ @@ -282,6 +289,23 @@ quarter of the total test units fails, the other \code{stop()}s at the same threshold level). } +\section{Labels}{ + + +\code{label} may be a single string or a character vector that matches the number +of expanded steps. \code{label} also supports \code{{glue}} syntax and exposes the +following dynamic variables contextualized to the current step: +\itemize{ +\item \code{"{.step}"}: The validation step name +\item \code{"{.col}"}: The current column name +\item \code{"{.seg_col}"}: The current segment's column name +\item \code{"{.seg_val}"}: The current segment's value/group +} + +The glue context also supports ordinary expressions for further flexibility +(e.g., \code{"{toupper(.step)}"}) as long as they return a length-1 string. +} + \section{Briefs}{ @@ -308,7 +332,7 @@ R statement: \if{html}{\out{
}}\preformatted{agent \%>\% col_vals_make_subset( - columns = vars(a), + columns = a, set = c(1, 2, 3, 4), preconditions = ~ . \%>\% dplyr::filter(a < 10), segments = b ~ c("group_1", "group_2"), @@ -322,7 +346,7 @@ YAML representation: \if{html}{\out{
}}\preformatted{steps: - col_vals_make_subset: - columns: vars(a) + columns: c(a) set: - 1.0 - 2.0 @@ -379,7 +403,7 @@ units (there are 2 test units, one per element in the \code{set}). \if{html}{\out{
}}\preformatted{agent <- create_agent(tbl = small_table) \%>\% col_vals_make_subset( - columns = vars(f), set = c("low", "high") + columns = f, set = c("low", "high") ) \%>\% interrogate() }\if{html}{\out{
}} @@ -403,7 +427,7 @@ behavior of side effects can be customized with the \code{actions} option. \if{html}{\out{
}}\preformatted{small_table \%>\% col_vals_make_subset( - columns = vars(f), set = c("low", "high") + columns = f, set = c("low", "high") ) \%>\% dplyr::pull(f) \%>\% unique() @@ -418,7 +442,7 @@ time. This is primarily used in \strong{testthat} tests. \if{html}{\out{
}}\preformatted{expect_col_vals_make_subset( small_table, - columns = vars(f), set = c("low", "high") + columns = f, set = c("low", "high") ) }\if{html}{\out{
}} } @@ -430,7 +454,7 @@ us. \if{html}{\out{
}}\preformatted{small_table \%>\% test_col_vals_make_subset( - columns = vars(f), set = c("low", "high") + columns = f, set = c("low", "high") ) #> [1] TRUE }\if{html}{\out{
}} @@ -458,12 +482,12 @@ Other validation functions: \code{\link{col_vals_decreasing}()}, \code{\link{col_vals_equal}()}, \code{\link{col_vals_expr}()}, -\code{\link{col_vals_gte}()}, \code{\link{col_vals_gt}()}, +\code{\link{col_vals_gte}()}, \code{\link{col_vals_in_set}()}, \code{\link{col_vals_increasing}()}, -\code{\link{col_vals_lte}()}, \code{\link{col_vals_lt}()}, +\code{\link{col_vals_lte}()}, \code{\link{col_vals_make_set}()}, \code{\link{col_vals_not_between}()}, \code{\link{col_vals_not_equal}()}, diff --git a/man/col_vals_not_between.Rd b/man/col_vals_not_between.Rd index f2ce20cef..7f90eac28 100644 --- a/man/col_vals_not_between.Rd +++ b/man/col_vals_not_between.Rd @@ -55,10 +55,11 @@ commonly created with \code{\link[=create_agent]{create_agent()}}.} \item{columns}{\emph{The target columns} -\verb{} // \strong{required} +\verb{} // \strong{required} -The column (or a set of columns, provided as a character vector) to which -this validation should be applied.} +A column-selecting expression, as one would use inside \code{dplyr::select()}. +Specifies the column (or a set of columns) to which this validation should +be applied. See the \emph{Column Names} section for more information.} \item{left}{\emph{Definition of left bound} @@ -136,12 +137,13 @@ produce (influenced by the number of \code{columns} provided), (2) be an ID string not used in any previous validation step, and (3) be a vector with unique values.} -\item{label}{\emph{An optional label for the validation step} +\item{label}{\emph{Optional label for the validation step} -\verb{scalar} // \emph{default:} \code{NULL} (\code{optional}) +\verb{vector} // \emph{default:} \code{NULL} (\code{optional}) -An optional label for the validation step. This label appears in the -\emph{agent} report and, for the best appearance, it should be kept quite short.} +Optional label for the validation step. This label appears in the \emph{agent} +report and, for the best appearance, it should be kept quite short. See +the \emph{Labels} section for more information.} \item{brief}{\emph{Brief description for the validation step} @@ -168,7 +170,7 @@ be used with \code{.} (serving as the input data table) to evaluate to a single logical value. With this approach, the \strong{pointblank} function \code{\link[=has_columns]{has_columns()}} can be used to determine whether to make a validation step active on the basis of one or more columns existing in the table -(e.g., \code{~ . \%>\% has_columns(vars(d, e))}).} +(e.g., \code{~ . \%>\% has_columns(c(d, e))}).} \item{object}{\emph{A data table for expectations or tests} @@ -245,12 +247,17 @@ formally tested (so be mindful of this when using unsupported backends with \section{Column Names}{ -If providing multiple column names to \code{columns}, the result will be an -expansion of validation steps to that number of column names (e.g., -\code{vars(col_a, col_b)} will result in the entry of two validation steps). Aside -from column names in quotes and in \code{vars()}, \strong{tidyselect} helper functions -are available for specifying columns. They are: \code{starts_with()}, -\code{ends_with()}, \code{contains()}, \code{matches()}, and \code{everything()}. +\code{columns} may be a single column (as symbol \code{a} or string \code{"a"}) or a vector +of columns (\code{c(a, b, c)} or \code{c("a", "b", "c")}). \code{{tidyselect}} helpers +are also supported, such as \code{contains("date")} and \code{where(is.double)}. If +passing an \emph{external vector} of columns, it should be wrapped in \code{all_of()}. + +When multiple columns are selected by \code{columns}, the result will be an +expansion of validation steps to that number of columns (e.g., +\code{c(col_a, col_b)} will result in the entry of two validation steps). + +Previously, columns could be specified in \code{vars()}. This continues to work, +but \code{c()} offers the same capability and supersedes \code{vars()} in \code{columns}. } \section{Missing Values}{ @@ -332,6 +339,23 @@ quarter of the total test units fails, the other \code{stop()}s at the same threshold level). } +\section{Labels}{ + + +\code{label} may be a single string or a character vector that matches the number +of expanded steps. \code{label} also supports \code{{glue}} syntax and exposes the +following dynamic variables contextualized to the current step: +\itemize{ +\item \code{"{.step}"}: The validation step name +\item \code{"{.col}"}: The current column name +\item \code{"{.seg_col}"}: The current segment's column name +\item \code{"{.seg_val}"}: The current segment's value/group +} + +The glue context also supports ordinary expressions for further flexibility +(e.g., \code{"{toupper(.step)}"}) as long as they return a length-1 string. +} + \section{Briefs}{ @@ -358,7 +382,7 @@ R statement: \if{html}{\out{
}}\preformatted{agent \%>\% col_vals_not_between( - columns = vars(a), + columns = a, left = 1, right = 2, inclusive = c(TRUE, FALSE), @@ -375,7 +399,7 @@ YAML representation: \if{html}{\out{
}}\preformatted{steps: - col_vals_not_between: - columns: vars(a) + columns: c(a) left: 1.0 right: 2.0 inclusive: @@ -434,7 +458,7 @@ units (there are 13 test units, one for each row). \if{html}{\out{
}}\preformatted{agent <- create_agent(tbl = small_table) \%>\% col_vals_not_between( - columns = vars(c), + columns = c, left = 10, right = 20, na_pass = TRUE ) \%>\% @@ -460,7 +484,7 @@ behavior of side effects can be customized with the \code{actions} option. \if{html}{\out{
}}\preformatted{small_table \%>\% col_vals_not_between( - columns = vars(c), + columns = c, left = 10, right = 20, na_pass = TRUE ) \%>\% @@ -475,7 +499,7 @@ With the \verb{expect_*()} form, we would typically perform one validation at a time. This is primarily used in \strong{testthat} tests. \if{html}{\out{
}}\preformatted{expect_col_vals_not_between( - small_table, columns = vars(c), + small_table, columns = c, left = 10, right = 20, na_pass = TRUE ) @@ -489,7 +513,7 @@ us. \if{html}{\out{
}}\preformatted{small_table \%>\% test_col_vals_not_between( - columns = vars(c), + columns = c, left = 10, right = 20, na_pass = TRUE ) @@ -506,7 +530,7 @@ In changing the lower bound to be \code{9} and making it non-inclusive, we get \if{html}{\out{
}}\preformatted{small_table \%>\% test_col_vals_not_between( - columns = vars(c), + columns = c, left = 9, right = 20, inclusive = c(FALSE, TRUE), na_pass = TRUE @@ -539,12 +563,12 @@ Other validation functions: \code{\link{col_vals_decreasing}()}, \code{\link{col_vals_equal}()}, \code{\link{col_vals_expr}()}, -\code{\link{col_vals_gte}()}, \code{\link{col_vals_gt}()}, +\code{\link{col_vals_gte}()}, \code{\link{col_vals_in_set}()}, \code{\link{col_vals_increasing}()}, -\code{\link{col_vals_lte}()}, \code{\link{col_vals_lt}()}, +\code{\link{col_vals_lte}()}, \code{\link{col_vals_make_set}()}, \code{\link{col_vals_make_subset}()}, \code{\link{col_vals_not_equal}()}, diff --git a/man/col_vals_not_equal.Rd b/man/col_vals_not_equal.Rd index f3ddb70d3..3b6d81500 100644 --- a/man/col_vals_not_equal.Rd +++ b/man/col_vals_not_equal.Rd @@ -49,10 +49,11 @@ commonly created with \code{\link[=create_agent]{create_agent()}}.} \item{columns}{\emph{The target columns} -\verb{} // \strong{required} +\verb{} // \strong{required} -The column (or a set of columns, provided as a character vector) to which -this validation should be applied.} +A column-selecting expression, as one would use inside \code{dplyr::select()}. +Specifies the column (or a set of columns) to which this validation should +be applied. See the \emph{Column Names} section for more information.} \item{value}{\emph{Value for comparison} @@ -113,12 +114,13 @@ produce (influenced by the number of \code{columns} provided), (2) be an ID string not used in any previous validation step, and (3) be a vector with unique values.} -\item{label}{\emph{An optional label for the validation step} +\item{label}{\emph{Optional label for the validation step} -\verb{scalar} // \emph{default:} \code{NULL} (\code{optional}) +\verb{vector} // \emph{default:} \code{NULL} (\code{optional}) -An optional label for the validation step. This label appears in the -\emph{agent} report and, for the best appearance, it should be kept quite short.} +Optional label for the validation step. This label appears in the \emph{agent} +report and, for the best appearance, it should be kept quite short. See +the \emph{Labels} section for more information.} \item{brief}{\emph{Brief description for the validation step} @@ -145,7 +147,7 @@ be used with \code{.} (serving as the input data table) to evaluate to a single logical value. With this approach, the \strong{pointblank} function \code{\link[=has_columns]{has_columns()}} can be used to determine whether to make a validation step active on the basis of one or more columns existing in the table -(e.g., \code{~ . \%>\% has_columns(vars(d, e))}).} +(e.g., \code{~ . \%>\% has_columns(c(d, e))}).} \item{object}{\emph{A data table for expectations or tests} @@ -214,12 +216,17 @@ formally tested (so be mindful of this when using unsupported backends with \section{Column Names}{ -If providing multiple column names, the result will be an expansion of -validation steps to that number of column names (e.g., \code{vars(col_a, col_b)} -will result in the entry of two validation steps). Aside from column names in -quotes and in \code{vars()}, \strong{tidyselect} helper functions are available for -specifying columns. They are: \code{starts_with()}, \code{ends_with()}, \code{contains()}, -\code{matches()}, and \code{everything()}. +\code{columns} may be a single column (as symbol \code{a} or string \code{"a"}) or a vector +of columns (\code{c(a, b, c)} or \code{c("a", "b", "c")}). \code{{tidyselect}} helpers +are also supported, such as \code{contains("date")} and \code{where(is.double)}. If +passing an \emph{external vector} of columns, it should be wrapped in \code{all_of()}. + +When multiple columns are selected by \code{columns}, the result will be an +expansion of validation steps to that number of columns (e.g., +\code{c(col_a, col_b)} will result in the entry of two validation steps). + +Previously, columns could be specified in \code{vars()}. This continues to work, +but \code{c()} offers the same capability and supersedes \code{vars()} in \code{columns}. } \section{Missing Values}{ @@ -301,6 +308,23 @@ quarter of the total test units fails, the other \code{stop()}s at the same threshold level). } +\section{Labels}{ + + +\code{label} may be a single string or a character vector that matches the number +of expanded steps. \code{label} also supports \code{{glue}} syntax and exposes the +following dynamic variables contextualized to the current step: +\itemize{ +\item \code{"{.step}"}: The validation step name +\item \code{"{.col}"}: The current column name +\item \code{"{.seg_col}"}: The current segment's column name +\item \code{"{.seg_val}"}: The current segment's value/group +} + +The glue context also supports ordinary expressions for further flexibility +(e.g., \code{"{toupper(.step)}"}) as long as they return a length-1 string. +} + \section{Briefs}{ @@ -327,7 +351,7 @@ R statement: \if{html}{\out{
}}\preformatted{agent \%>\% col_vals_not_equal( - columns = vars(a), + columns = a, value = 1, na_pass = TRUE, preconditions = ~ . \%>\% dplyr::filter(a < 10), @@ -342,7 +366,7 @@ YAML representation: \if{html}{\out{
}}\preformatted{steps: - col_vals_not_equal: - columns: vars(a) + columns: c(a) value: 1.0 na_pass: true preconditions: ~. \%>\% dplyr::filter(a < 10) @@ -397,7 +421,7 @@ test units, one for each row). \if{html}{\out{
}}\preformatted{agent <- create_agent(tbl = tbl) \%>\% - col_vals_not_equal(columns = vars(a), value = 6) \%>\% + col_vals_not_equal(columns = a, value = 6) \%>\% interrogate() }\if{html}{\out{
}} @@ -419,7 +443,7 @@ through but should \code{stop()} if there is a single test unit failing. The behavior of side effects can be customized with the \code{actions} option. \if{html}{\out{
}}\preformatted{tbl \%>\% - col_vals_not_equal(columns = vars(a), value = 6) \%>\% + col_vals_not_equal(columns = a, value = 6) \%>\% dplyr::pull(a) #> [1] 5 5 5 5 5 5 }\if{html}{\out{
}} @@ -430,7 +454,7 @@ behavior of side effects can be customized with the \code{actions} option. With the \verb{expect_*()} form, we would typically perform one validation at a time. This is primarily used in \strong{testthat} tests. -\if{html}{\out{
}}\preformatted{expect_col_vals_not_equal(tbl, columns = vars(a), value = 6) +\if{html}{\out{
}}\preformatted{expect_col_vals_not_equal(tbl, columns = a, value = 6) }\if{html}{\out{
}} } @@ -439,7 +463,7 @@ time. This is primarily used in \strong{testthat} tests. With the \verb{test_*()} form, we should get a single logical value returned to us. -\if{html}{\out{
}}\preformatted{test_col_vals_not_equal(tbl, columns = vars(a), value = 6) +\if{html}{\out{
}}\preformatted{test_col_vals_not_equal(tbl, columns = a, value = 6) #> [1] TRUE }\if{html}{\out{
}} } @@ -468,12 +492,12 @@ Other validation functions: \code{\link{col_vals_decreasing}()}, \code{\link{col_vals_equal}()}, \code{\link{col_vals_expr}()}, -\code{\link{col_vals_gte}()}, \code{\link{col_vals_gt}()}, +\code{\link{col_vals_gte}()}, \code{\link{col_vals_in_set}()}, \code{\link{col_vals_increasing}()}, -\code{\link{col_vals_lte}()}, \code{\link{col_vals_lt}()}, +\code{\link{col_vals_lte}()}, \code{\link{col_vals_make_set}()}, \code{\link{col_vals_make_subset}()}, \code{\link{col_vals_not_between}()}, diff --git a/man/col_vals_not_in_set.Rd b/man/col_vals_not_in_set.Rd index a3b041737..26bdc1f34 100644 --- a/man/col_vals_not_in_set.Rd +++ b/man/col_vals_not_in_set.Rd @@ -46,10 +46,11 @@ commonly created with \code{\link[=create_agent]{create_agent()}}.} \item{columns}{\emph{The target columns} -\verb{} // \strong{required} +\verb{} // \strong{required} -The column (or a set of columns, provided as a character vector) to which -this validation should be applied.} +A column-selecting expression, as one would use inside \code{dplyr::select()}. +Specifies the column (or a set of columns) to which this validation should +be applied. See the \emph{Column Names} section for more information.} \item{set}{\emph{Set of values} @@ -102,12 +103,13 @@ produce (influenced by the number of \code{columns} provided), (2) be an ID string not used in any previous validation step, and (3) be a vector with unique values.} -\item{label}{\emph{An optional label for the validation step} +\item{label}{\emph{Optional label for the validation step} -\verb{scalar} // \emph{default:} \code{NULL} (\code{optional}) +\verb{vector} // \emph{default:} \code{NULL} (\code{optional}) -An optional label for the validation step. This label appears in the -\emph{agent} report and, for the best appearance, it should be kept quite short.} +Optional label for the validation step. This label appears in the \emph{agent} +report and, for the best appearance, it should be kept quite short. See +the \emph{Labels} section for more information.} \item{brief}{\emph{Brief description for the validation step} @@ -134,7 +136,7 @@ be used with \code{.} (serving as the input data table) to evaluate to a single logical value. With this approach, the \strong{pointblank} function \code{\link[=has_columns]{has_columns()}} can be used to determine whether to make a validation step active on the basis of one or more columns existing in the table -(e.g., \code{~ . \%>\% has_columns(vars(d, e))}).} +(e.g., \code{~ . \%>\% has_columns(c(d, e))}).} \item{object}{\emph{A data table for expectations or tests} @@ -203,12 +205,17 @@ formally tested (so be mindful of this when using unsupported backends with \section{Column Names}{ -If providing multiple column names, the result will be an expansion of -validation steps to that number of column names (e.g., \code{vars(col_a, col_b)} -will result in the entry of two validation steps). Aside from column names in -quotes and in \code{vars()}, \strong{tidyselect} helper functions are available for -specifying columns. They are: \code{starts_with()}, \code{ends_with()}, \code{contains()}, -\code{matches()}, and \code{everything()}. +\code{columns} may be a single column (as symbol \code{a} or string \code{"a"}) or a vector +of columns (\code{c(a, b, c)} or \code{c("a", "b", "c")}). \code{{tidyselect}} helpers +are also supported, such as \code{contains("date")} and \code{where(is.double)}. If +passing an \emph{external vector} of columns, it should be wrapped in \code{all_of()}. + +When multiple columns are selected by \code{columns}, the result will be an +expansion of validation steps to that number of columns (e.g., +\code{c(col_a, col_b)} will result in the entry of two validation steps). + +Previously, columns could be specified in \code{vars()}. This continues to work, +but \code{c()} offers the same capability and supersedes \code{vars()} in \code{columns}. } \section{Preconditions}{ @@ -282,6 +289,23 @@ quarter of the total test units fails, the other \code{stop()}s at the same threshold level). } +\section{Labels}{ + + +\code{label} may be a single string or a character vector that matches the number +of expanded steps. \code{label} also supports \code{{glue}} syntax and exposes the +following dynamic variables contextualized to the current step: +\itemize{ +\item \code{"{.step}"}: The validation step name +\item \code{"{.col}"}: The current column name +\item \code{"{.seg_col}"}: The current segment's column name +\item \code{"{.seg_val}"}: The current segment's value/group +} + +The glue context also supports ordinary expressions for further flexibility +(e.g., \code{"{toupper(.step)}"}) as long as they return a length-1 string. +} + \section{Briefs}{ @@ -308,7 +332,7 @@ R statement: \if{html}{\out{
}}\preformatted{agent \%>\% col_vals_not_in_set( - columns = vars(a), + columns = a, set = c(1, 2, 3, 4), preconditions = ~ . \%>\% dplyr::filter(a < 10), segments = b ~ c("group_1", "group_2"), @@ -322,7 +346,7 @@ YAML representation: \if{html}{\out{
}}\preformatted{steps: - col_vals_not_in_set: - columns: vars(a) + columns: c(a) set: - 1.0 - 2.0 @@ -359,7 +383,7 @@ and \code{highs}. We'll determine if this validation has any failing test units \if{html}{\out{
}}\preformatted{agent <- create_agent(tbl = small_table) \%>\% col_vals_not_in_set( - columns = vars(f), set = c("lows", "mids", "highs") + columns = f, set = c("lows", "mids", "highs") ) \%>\% interrogate() }\if{html}{\out{
}} @@ -383,7 +407,7 @@ behavior of side effects can be customized with the \code{actions} option. \if{html}{\out{
}}\preformatted{small_table \%>\% col_vals_not_in_set( - columns = vars(f), set = c("lows", "mids", "highs") + columns = f, set = c("lows", "mids", "highs") ) \%>\% dplyr::pull(f) \%>\% unique() @@ -397,7 +421,7 @@ time. This is primarily used in \strong{testthat} tests. \if{html}{\out{
}}\preformatted{expect_col_vals_not_in_set( small_table, - columns = vars(f), set = c("lows", "mids", "highs") + columns = f, set = c("lows", "mids", "highs") ) }\if{html}{\out{
}} } @@ -409,7 +433,7 @@ us. \if{html}{\out{
}}\preformatted{small_table \%>\% test_col_vals_not_in_set( - columns = vars(f), set = c("lows", "mids", "highs") + columns = f, set = c("lows", "mids", "highs") ) #> [1] TRUE }\if{html}{\out{
}} @@ -439,12 +463,12 @@ Other validation functions: \code{\link{col_vals_decreasing}()}, \code{\link{col_vals_equal}()}, \code{\link{col_vals_expr}()}, -\code{\link{col_vals_gte}()}, \code{\link{col_vals_gt}()}, +\code{\link{col_vals_gte}()}, \code{\link{col_vals_in_set}()}, \code{\link{col_vals_increasing}()}, -\code{\link{col_vals_lte}()}, \code{\link{col_vals_lt}()}, +\code{\link{col_vals_lte}()}, \code{\link{col_vals_make_set}()}, \code{\link{col_vals_make_subset}()}, \code{\link{col_vals_not_between}()}, diff --git a/man/col_vals_not_null.Rd b/man/col_vals_not_null.Rd index 425e15f43..9e7e1cbb4 100644 --- a/man/col_vals_not_null.Rd +++ b/man/col_vals_not_null.Rd @@ -33,10 +33,11 @@ commonly created with \code{\link[=create_agent]{create_agent()}}.} \item{columns}{\emph{The target columns} -\verb{} // \strong{required} +\verb{} // \strong{required} -The column (or a set of columns, provided as a character vector) to which -this validation should be applied.} +A column-selecting expression, as one would use inside \code{dplyr::select()}. +Specifies the column (or a set of columns) to which this validation should +be applied. See the \emph{Column Names} section for more information.} \item{preconditions}{\emph{Input table modification prior to validation} @@ -82,12 +83,13 @@ produce (influenced by the number of \code{columns} provided), (2) be an ID string not used in any previous validation step, and (3) be a vector with unique values.} -\item{label}{\emph{An optional label for the validation step} +\item{label}{\emph{Optional label for the validation step} -\verb{scalar} // \emph{default:} \code{NULL} (\code{optional}) +\verb{vector} // \emph{default:} \code{NULL} (\code{optional}) -An optional label for the validation step. This label appears in the -\emph{agent} report and, for the best appearance, it should be kept quite short.} +Optional label for the validation step. This label appears in the \emph{agent} +report and, for the best appearance, it should be kept quite short. See +the \emph{Labels} section for more information.} \item{brief}{\emph{Brief description for the validation step} @@ -114,7 +116,7 @@ be used with \code{.} (serving as the input data table) to evaluate to a single logical value. With this approach, the \strong{pointblank} function \code{\link[=has_columns]{has_columns()}} can be used to determine whether to make a validation step active on the basis of one or more columns existing in the table -(e.g., \code{~ . \%>\% has_columns(vars(d, e))}).} +(e.g., \code{~ . \%>\% has_columns(c(d, e))}).} \item{object}{\emph{A data table for expectations or tests} @@ -184,12 +186,17 @@ formally tested (so be mindful of this when using unsupported backends with \section{Column Names}{ -If providing multiple column names, the result will be an expansion of -validation steps to that number of column names (e.g., \code{vars(col_a, col_b)} -will result in the entry of two validation steps). Aside from column names in -quotes and in \code{vars()}, \strong{tidyselect} helper functions are available for -specifying columns. They are: \code{starts_with()}, \code{ends_with()}, \code{contains()}, -\code{matches()}, and \code{everything()}. +\code{columns} may be a single column (as symbol \code{a} or string \code{"a"}) or a vector +of columns (\code{c(a, b, c)} or \code{c("a", "b", "c")}). \code{{tidyselect}} helpers +are also supported, such as \code{contains("date")} and \code{where(is.double)}. If +passing an \emph{external vector} of columns, it should be wrapped in \code{all_of()}. + +When multiple columns are selected by \code{columns}, the result will be an +expansion of validation steps to that number of columns (e.g., +\code{c(col_a, col_b)} will result in the entry of two validation steps). + +Previously, columns could be specified in \code{vars()}. This continues to work, +but \code{c()} offers the same capability and supersedes \code{vars()} in \code{columns}. } \section{Preconditions}{ @@ -263,6 +270,23 @@ quarter of the total test units fails, the other \code{stop()}s at the same threshold level). } +\section{Labels}{ + + +\code{label} may be a single string or a character vector that matches the number +of expanded steps. \code{label} also supports \code{{glue}} syntax and exposes the +following dynamic variables contextualized to the current step: +\itemize{ +\item \code{"{.step}"}: The validation step name +\item \code{"{.col}"}: The current column name +\item \code{"{.seg_col}"}: The current segment's column name +\item \code{"{.seg_val}"}: The current segment's value/group +} + +The glue context also supports ordinary expressions for further flexibility +(e.g., \code{"{toupper(.step)}"}) as long as they return a length-1 string. +} + \section{Briefs}{ @@ -289,7 +313,7 @@ R statement: \if{html}{\out{
}}\preformatted{agent \%>\% col_vals_not_null( - columns = vars(a), + columns = a, preconditions = ~ . \%>\% dplyr::filter(a < 10), segments = b ~ c("group_1", "group_2"), actions = action_levels(warn_at = 0.1, stop_at = 0.2), @@ -302,7 +326,7 @@ YAML representation: \if{html}{\out{
}}\preformatted{steps: - col_vals_not_null: - columns: vars(a) + columns: c(a) preconditions: ~. \%>\% dplyr::filter(a < 10) segments: b ~ c("group_1", "group_2") actions: @@ -353,7 +377,7 @@ row). \if{html}{\out{
}}\preformatted{agent <- create_agent(tbl = tbl) \%>\% - col_vals_not_null(columns = vars(b)) \%>\% + col_vals_not_null(columns = b) \%>\% interrogate() }\if{html}{\out{
}} @@ -375,7 +399,7 @@ through but should \code{stop()} if there is a single test unit failing. The behavior of side effects can be customized with the \code{actions} option. \if{html}{\out{
}}\preformatted{tbl \%>\% - col_vals_not_null(columns = vars(b)) \%>\% + col_vals_not_null(columns = b) \%>\% dplyr::pull(b) #> [1] 7 1 0 0 0 }\if{html}{\out{
}} @@ -386,7 +410,7 @@ behavior of side effects can be customized with the \code{actions} option. With the \verb{expect_*()} form, we would typically perform one validation at a time. This is primarily used in \strong{testthat} tests. -\if{html}{\out{
}}\preformatted{expect_col_vals_not_null(tbl, columns = vars(b)) +\if{html}{\out{
}}\preformatted{expect_col_vals_not_null(tbl, columns = b) }\if{html}{\out{
}} } @@ -395,7 +419,7 @@ time. This is primarily used in \strong{testthat} tests. With the \verb{test_*()} form, we should get a single logical value returned to us. -\if{html}{\out{
}}\preformatted{tbl \%>\% test_col_vals_not_null(columns = vars(b)) +\if{html}{\out{
}}\preformatted{tbl \%>\% test_col_vals_not_null(columns = b) #> [1] TRUE }\if{html}{\out{
}} } @@ -424,12 +448,12 @@ Other validation functions: \code{\link{col_vals_decreasing}()}, \code{\link{col_vals_equal}()}, \code{\link{col_vals_expr}()}, -\code{\link{col_vals_gte}()}, \code{\link{col_vals_gt}()}, +\code{\link{col_vals_gte}()}, \code{\link{col_vals_in_set}()}, \code{\link{col_vals_increasing}()}, -\code{\link{col_vals_lte}()}, \code{\link{col_vals_lt}()}, +\code{\link{col_vals_lte}()}, \code{\link{col_vals_make_set}()}, \code{\link{col_vals_make_subset}()}, \code{\link{col_vals_not_between}()}, diff --git a/man/col_vals_null.Rd b/man/col_vals_null.Rd index 281344d5c..6069de1b6 100644 --- a/man/col_vals_null.Rd +++ b/man/col_vals_null.Rd @@ -33,10 +33,11 @@ commonly created with \code{\link[=create_agent]{create_agent()}}.} \item{columns}{\emph{The target columns} -\verb{} // \strong{required} +\verb{} // \strong{required} -The column (or a set of columns, provided as a character vector) to which -this validation should be applied.} +A column-selecting expression, as one would use inside \code{dplyr::select()}. +Specifies the column (or a set of columns) to which this validation should +be applied. See the \emph{Column Names} section for more information.} \item{preconditions}{\emph{Input table modification prior to validation} @@ -82,12 +83,13 @@ produce (influenced by the number of \code{columns} provided), (2) be an ID string not used in any previous validation step, and (3) be a vector with unique values.} -\item{label}{\emph{An optional label for the validation step} +\item{label}{\emph{Optional label for the validation step} -\verb{scalar} // \emph{default:} \code{NULL} (\code{optional}) +\verb{vector} // \emph{default:} \code{NULL} (\code{optional}) -An optional label for the validation step. This label appears in the -\emph{agent} report and, for the best appearance, it should be kept quite short.} +Optional label for the validation step. This label appears in the \emph{agent} +report and, for the best appearance, it should be kept quite short. See +the \emph{Labels} section for more information.} \item{brief}{\emph{Brief description for the validation step} @@ -114,7 +116,7 @@ be used with \code{.} (serving as the input data table) to evaluate to a single logical value. With this approach, the \strong{pointblank} function \code{\link[=has_columns]{has_columns()}} can be used to determine whether to make a validation step active on the basis of one or more columns existing in the table -(e.g., \code{~ . \%>\% has_columns(vars(d, e))}).} +(e.g., \code{~ . \%>\% has_columns(c(d, e))}).} \item{object}{\emph{A data table for expectations or tests} @@ -183,12 +185,17 @@ formally tested (so be mindful of this when using unsupported backends with \section{Column Names}{ -If providing multiple column names, the result will be an expansion of -validation steps to that number of column names (e.g., \code{vars(col_a, col_b)} -will result in the entry of two validation steps). Aside from column names in -quotes and in \code{vars()}, \strong{tidyselect} helper functions are available for -specifying columns. They are: \code{starts_with()}, \code{ends_with()}, \code{contains()}, -\code{matches()}, and \code{everything()}. +\code{columns} may be a single column (as symbol \code{a} or string \code{"a"}) or a vector +of columns (\code{c(a, b, c)} or \code{c("a", "b", "c")}). \code{{tidyselect}} helpers +are also supported, such as \code{contains("date")} and \code{where(is.double)}. If +passing an \emph{external vector} of columns, it should be wrapped in \code{all_of()}. + +When multiple columns are selected by \code{columns}, the result will be an +expansion of validation steps to that number of columns (e.g., +\code{c(col_a, col_b)} will result in the entry of two validation steps). + +Previously, columns could be specified in \code{vars()}. This continues to work, +but \code{c()} offers the same capability and supersedes \code{vars()} in \code{columns}. } \section{Preconditions}{ @@ -262,6 +269,23 @@ quarter of the total test units fails, the other \code{stop()}s at the same threshold level). } +\section{Labels}{ + + +\code{label} may be a single string or a character vector that matches the number +of expanded steps. \code{label} also supports \code{{glue}} syntax and exposes the +following dynamic variables contextualized to the current step: +\itemize{ +\item \code{"{.step}"}: The validation step name +\item \code{"{.col}"}: The current column name +\item \code{"{.seg_col}"}: The current segment's column name +\item \code{"{.seg_val}"}: The current segment's value/group +} + +The glue context also supports ordinary expressions for further flexibility +(e.g., \code{"{toupper(.step)}"}) as long as they return a length-1 string. +} + \section{Briefs}{ @@ -288,7 +312,7 @@ R statement: \if{html}{\out{
}}\preformatted{agent \%>\% col_vals_null( - columns = vars(a), + columns = a, preconditions = ~ . \%>\% dplyr::filter(a < 10), segments = b ~ c("group_1", "group_2"), actions = action_levels(warn_at = 0.1, stop_at = 0.2), @@ -301,7 +325,7 @@ YAML representation: \if{html}{\out{
}}\preformatted{steps: - col_vals_null: - columns: vars(a) + columns: c(a) preconditions: ~. \%>\% dplyr::filter(a < 10) segments: b ~ c("group_1", "group_2") actions: @@ -352,7 +376,7 @@ row). \if{html}{\out{
}}\preformatted{agent <- create_agent(tbl = tbl) \%>\% - col_vals_null(columns = vars(c)) \%>\% + col_vals_null(columns = c) \%>\% interrogate() }\if{html}{\out{
}} @@ -374,7 +398,7 @@ through but should \code{stop()} if there is a single test unit failing. The behavior of side effects can be customized with the \code{actions} option. \if{html}{\out{
}}\preformatted{tbl \%>\% - col_vals_null(columns = vars(c)) \%>\% + col_vals_null(columns = c) \%>\% dplyr::pull(c) #> [1] NA NA NA NA NA }\if{html}{\out{
}} @@ -385,7 +409,7 @@ behavior of side effects can be customized with the \code{actions} option. With the \verb{expect_*()} form, we would typically perform one validation at a time. This is primarily used in \strong{testthat} tests. -\if{html}{\out{
}}\preformatted{expect_col_vals_null(tbl, columns = vars(c)) +\if{html}{\out{
}}\preformatted{expect_col_vals_null(tbl, columns = c) }\if{html}{\out{
}} } @@ -394,7 +418,7 @@ time. This is primarily used in \strong{testthat} tests. With the \verb{test_*()} form, we should get a single logical value returned to us. -\if{html}{\out{
}}\preformatted{tbl \%>\% test_col_vals_null(columns = vars(c)) +\if{html}{\out{
}}\preformatted{tbl \%>\% test_col_vals_null(columns = c) #> [1] TRUE }\if{html}{\out{
}} } @@ -423,12 +447,12 @@ Other validation functions: \code{\link{col_vals_decreasing}()}, \code{\link{col_vals_equal}()}, \code{\link{col_vals_expr}()}, -\code{\link{col_vals_gte}()}, \code{\link{col_vals_gt}()}, +\code{\link{col_vals_gte}()}, \code{\link{col_vals_in_set}()}, \code{\link{col_vals_increasing}()}, -\code{\link{col_vals_lte}()}, \code{\link{col_vals_lt}()}, +\code{\link{col_vals_lte}()}, \code{\link{col_vals_make_set}()}, \code{\link{col_vals_make_subset}()}, \code{\link{col_vals_not_between}()}, diff --git a/man/col_vals_regex.Rd b/man/col_vals_regex.Rd index dd65cb4f0..e0b323569 100644 --- a/man/col_vals_regex.Rd +++ b/man/col_vals_regex.Rd @@ -49,10 +49,11 @@ commonly created with \code{\link[=create_agent]{create_agent()}}.} \item{columns}{\emph{The target columns} -\verb{} // \strong{required} +\verb{} // \strong{required} -The column (or a set of columns, provided as a character vector) to which -this validation should be applied.} +A column-selecting expression, as one would use inside \code{dplyr::select()}. +Specifies the column (or a set of columns) to which this validation should +be applied. See the \emph{Column Names} section for more information.} \item{regex}{\emph{Regex pattern} @@ -112,12 +113,13 @@ produce (influenced by the number of \code{columns} provided), (2) be an ID string not used in any previous validation step, and (3) be a vector with unique values.} -\item{label}{\emph{An optional label for the validation step} +\item{label}{\emph{Optional label for the validation step} -\verb{scalar} // \emph{default:} \code{NULL} (\code{optional}) +\verb{vector} // \emph{default:} \code{NULL} (\code{optional}) -An optional label for the validation step. This label appears in the -\emph{agent} report and, for the best appearance, it should be kept quite short.} +Optional label for the validation step. This label appears in the \emph{agent} +report and, for the best appearance, it should be kept quite short. See +the \emph{Labels} section for more information.} \item{brief}{\emph{Brief description for the validation step} @@ -144,7 +146,7 @@ be used with \code{.} (serving as the input data table) to evaluate to a single logical value. With this approach, the \strong{pointblank} function \code{\link[=has_columns]{has_columns()}} can be used to determine whether to make a validation step active on the basis of one or more columns existing in the table -(e.g., \code{~ . \%>\% has_columns(vars(d, e))}).} +(e.g., \code{~ . \%>\% has_columns(c(d, e))}).} \item{object}{\emph{A data table for expectations or tests} @@ -213,12 +215,17 @@ formally tested (so be mindful of this when using unsupported backends with \section{Column Names}{ -If providing multiple column names, the result will be an expansion of -validation steps to that number of column names (e.g., \code{vars(col_a, col_b)} -will result in the entry of two validation steps). Aside from column names in -quotes and in \code{vars()}, \strong{tidyselect} helper functions are available for -specifying columns. They are: \code{starts_with()}, \code{ends_with()}, \code{contains()}, -\code{matches()}, and \code{everything()}. +\code{columns} may be a single column (as symbol \code{a} or string \code{"a"}) or a vector +of columns (\code{c(a, b, c)} or \code{c("a", "b", "c")}). \code{{tidyselect}} helpers +are also supported, such as \code{contains("date")} and \code{where(is.double)}. If +passing an \emph{external vector} of columns, it should be wrapped in \code{all_of()}. + +When multiple columns are selected by \code{columns}, the result will be an +expansion of validation steps to that number of columns (e.g., +\code{c(col_a, col_b)} will result in the entry of two validation steps). + +Previously, columns could be specified in \code{vars()}. This continues to work, +but \code{c()} offers the same capability and supersedes \code{vars()} in \code{columns}. } \section{Missing Values}{ @@ -300,6 +307,23 @@ quarter of the total test units fails, the other \code{stop()}s at the same threshold level). } +\section{Labels}{ + + +\code{label} may be a single string or a character vector that matches the number +of expanded steps. \code{label} also supports \code{{glue}} syntax and exposes the +following dynamic variables contextualized to the current step: +\itemize{ +\item \code{"{.step}"}: The validation step name +\item \code{"{.col}"}: The current column name +\item \code{"{.seg_col}"}: The current segment's column name +\item \code{"{.seg_val}"}: The current segment's value/group +} + +The glue context also supports ordinary expressions for further flexibility +(e.g., \code{"{toupper(.step)}"}) as long as they return a length-1 string. +} + \section{Briefs}{ @@ -326,7 +350,7 @@ R statement: \if{html}{\out{
}}\preformatted{agent \%>\% col_vals_regex( - columns = vars(a), + columns = a, regex = "[0-9]-[a-z]\{3\}-[0-9]\{3\}", na_pass = TRUE, preconditions = ~ . \%>\% dplyr::filter(a < 10), @@ -341,7 +365,7 @@ YAML representation: \if{html}{\out{
}}\preformatted{steps: - col_vals_regex: - columns: vars(a) + columns: c(a) regex: '[0-9]-[a-z]\{3\}-[0-9]\{3\}' na_pass: true preconditions: ~. \%>\% dplyr::filter(a < 10) @@ -399,7 +423,7 @@ units, one for each row). \if{html}{\out{
}}\preformatted{agent <- create_agent(tbl = small_table) \%>\% - col_vals_regex(columns = vars(b), regex = pattern) \%>\% + col_vals_regex(columns = b, regex = pattern) \%>\% interrogate() }\if{html}{\out{
}} @@ -421,7 +445,7 @@ through but should \code{stop()} if there is a single test unit failing. The behavior of side effects can be customized with the \code{actions} option. \if{html}{\out{
}}\preformatted{small_table \%>\% - col_vals_regex(columns = vars(b), regex = pattern) \%>\% + col_vals_regex(columns = b, regex = pattern) \%>\% dplyr::slice(1:5) #> # A tibble: 5 x 8 #> date_time date a b c d e f @@ -439,7 +463,7 @@ behavior of side effects can be customized with the \code{actions} option. With the \verb{expect_*()} form, we would typically perform one validation at a time. This is primarily used in \strong{testthat} tests. -\if{html}{\out{
}}\preformatted{expect_col_vals_regex(small_table, columns = vars(b), regex = pattern) +\if{html}{\out{
}}\preformatted{expect_col_vals_regex(small_table, columns = b, regex = pattern) }\if{html}{\out{
}} } @@ -448,7 +472,7 @@ time. This is primarily used in \strong{testthat} tests. With the \verb{test_*()} form, we should get a single logical value returned to us. -\if{html}{\out{
}}\preformatted{small_table \%>\% test_col_vals_regex(columns = vars(b), regex = pattern) +\if{html}{\out{
}}\preformatted{small_table \%>\% test_col_vals_regex(columns = b, regex = pattern) #> [1] TRUE }\if{html}{\out{
}} } @@ -475,12 +499,12 @@ Other validation functions: \code{\link{col_vals_decreasing}()}, \code{\link{col_vals_equal}()}, \code{\link{col_vals_expr}()}, -\code{\link{col_vals_gte}()}, \code{\link{col_vals_gt}()}, +\code{\link{col_vals_gte}()}, \code{\link{col_vals_in_set}()}, \code{\link{col_vals_increasing}()}, -\code{\link{col_vals_lte}()}, \code{\link{col_vals_lt}()}, +\code{\link{col_vals_lte}()}, \code{\link{col_vals_make_set}()}, \code{\link{col_vals_make_subset}()}, \code{\link{col_vals_not_between}()}, diff --git a/man/col_vals_within_spec.Rd b/man/col_vals_within_spec.Rd index 5ad799179..bb75adef1 100644 --- a/man/col_vals_within_spec.Rd +++ b/man/col_vals_within_spec.Rd @@ -49,10 +49,11 @@ commonly created with \code{\link[=create_agent]{create_agent()}}.} \item{columns}{\emph{The target columns} -\verb{} // \strong{required} +\verb{} // \strong{required} -The column (or a set of columns, provided as a character vector) to which -this validation should be applied.} +A column-selecting expression, as one would use inside \code{dplyr::select()}. +Specifies the column (or a set of columns) to which this validation should +be applied. See the \emph{Column Names} section for more information.} \item{spec}{\emph{Specification type} @@ -113,12 +114,13 @@ produce (influenced by the number of \code{columns} provided), (2) be an ID string not used in any previous validation step, and (3) be a vector with unique values.} -\item{label}{\emph{An optional label for the validation step} +\item{label}{\emph{Optional label for the validation step} -\verb{scalar} // \emph{default:} \code{NULL} (\code{optional}) +\verb{vector} // \emph{default:} \code{NULL} (\code{optional}) -An optional label for the validation step. This label appears in the -\emph{agent} report and, for the best appearance, it should be kept quite short.} +Optional label for the validation step. This label appears in the \emph{agent} +report and, for the best appearance, it should be kept quite short. See +the \emph{Labels} section for more information.} \item{brief}{\emph{Brief description for the validation step} @@ -145,7 +147,7 @@ be used with \code{.} (serving as the input data table) to evaluate to a single logical value. With this approach, the \strong{pointblank} function \code{\link[=has_columns]{has_columns()}} can be used to determine whether to make a validation step active on the basis of one or more columns existing in the table -(e.g., \code{~ . \%>\% has_columns(vars(d, e))}).} +(e.g., \code{~ . \%>\% has_columns(c(d, e))}).} \item{object}{\emph{A data table for expectations or tests} @@ -266,12 +268,17 @@ Only a single \code{spec} value should be provided per function call. \section{Column Names}{ -If providing multiple column names, the result will be an expansion of -validation steps to that number of column names (e.g., \code{vars(col_a, col_b)} -will result in the entry of two validation steps). Aside from column names in -quotes and in \code{vars()}, \strong{tidyselect} helper functions are available for -specifying columns. They are: \code{starts_with()}, \code{ends_with()}, \code{contains()}, -\code{matches()}, and \code{everything()}. +\code{columns} may be a single column (as symbol \code{a} or string \code{"a"}) or a vector +of columns (\code{c(a, b, c)} or \code{c("a", "b", "c")}). \code{{tidyselect}} helpers +are also supported, such as \code{contains("date")} and \code{where(is.double)}. If +passing an \emph{external vector} of columns, it should be wrapped in \code{all_of()}. + +When multiple columns are selected by \code{columns}, the result will be an +expansion of validation steps to that number of columns (e.g., +\code{c(col_a, col_b)} will result in the entry of two validation steps). + +Previously, columns could be specified in \code{vars()}. This continues to work, +but \code{c()} offers the same capability and supersedes \code{vars()} in \code{columns}. } \section{Missing Values}{ @@ -353,6 +360,23 @@ quarter of the total test units fails, the other \code{stop()}s at the same threshold level). } +\section{Labels}{ + + +\code{label} may be a single string or a character vector that matches the number +of expanded steps. \code{label} also supports \code{{glue}} syntax and exposes the +following dynamic variables contextualized to the current step: +\itemize{ +\item \code{"{.step}"}: The validation step name +\item \code{"{.col}"}: The current column name +\item \code{"{.seg_col}"}: The current segment's column name +\item \code{"{.seg_val}"}: The current segment's value/group +} + +The glue context also supports ordinary expressions for further flexibility +(e.g., \code{"{toupper(.step)}"}) as long as they return a length-1 string. +} + \section{Briefs}{ @@ -379,7 +403,7 @@ R statement: \if{html}{\out{
}}\preformatted{agent \%>\% col_vals_within_spec( - columns = vars(a), + columns = a, spec = "email", na_pass = TRUE, preconditions = ~ . \%>\% dplyr::filter(b < 10), @@ -394,7 +418,7 @@ YAML representation: \if{html}{\out{
}}\preformatted{steps: - col_vals_within_spec: - columns: vars(a) + columns: c(a) spec: email na_pass: true preconditions: ~. \%>\% dplyr::filter(b < 10) @@ -447,7 +471,7 @@ units, one for each row). \if{html}{\out{
}}\preformatted{agent <- create_agent(tbl = spec_slice) \%>\% col_vals_within_spec( - columns = vars(email_addresses), + columns = email_addresses, spec = "email" ) \%>\% interrogate() @@ -472,7 +496,7 @@ behavior of side effects can be customized with the \code{actions} option. \if{html}{\out{
}}\preformatted{spec_slice \%>\% col_vals_within_spec( - columns = vars(email_addresses), + columns = email_addresses, spec = "email" ) \%>\% dplyr::select(email_addresses) @@ -494,7 +518,7 @@ time. This is primarily used in \strong{testthat} tests. \if{html}{\out{
}}\preformatted{expect_col_vals_within_spec( spec_slice, - columns = vars(email_addresses), + columns = email_addresses, spec = "email" ) }\if{html}{\out{
}} @@ -507,7 +531,7 @@ us. \if{html}{\out{
}}\preformatted{spec_slice \%>\% test_col_vals_within_spec( - columns = vars(email_addresses), + columns = email_addresses, spec = "email" ) #> [1] TRUE @@ -536,12 +560,12 @@ Other validation functions: \code{\link{col_vals_decreasing}()}, \code{\link{col_vals_equal}()}, \code{\link{col_vals_expr}()}, -\code{\link{col_vals_gte}()}, \code{\link{col_vals_gt}()}, +\code{\link{col_vals_gte}()}, \code{\link{col_vals_in_set}()}, \code{\link{col_vals_increasing}()}, -\code{\link{col_vals_lte}()}, \code{\link{col_vals_lt}()}, +\code{\link{col_vals_lte}()}, \code{\link{col_vals_make_set}()}, \code{\link{col_vals_make_subset}()}, \code{\link{col_vals_not_between}()}, diff --git a/man/conjointly.Rd b/man/conjointly.Rd index 1da906c83..1233284f8 100644 --- a/man/conjointly.Rd +++ b/man/conjointly.Rd @@ -51,7 +51,7 @@ commonly created with \code{\link[=create_agent]{create_agent()}}.} A collection one-sided formulas that consist of validation functions that validate row units (the \verb{col_vals_*()} series), column existence (\code{\link[=col_exists]{col_exists()}}), or column type (the \verb{col_is_*()} series). An example of -this is \verb{~ col_vals_gte(., vars(a), 5.5), ~ col_vals_not_null(., vars(b)}).} +this is \verb{~ col_vals_gte(., a, 5.5), ~ col_vals_not_null(., b}).} \item{.list}{\emph{Alternative to \code{...}} @@ -103,12 +103,13 @@ produce (influenced by the number of \code{columns} provided), (2) be an ID string not used in any previous validation step, and (3) be a vector with unique values.} -\item{label}{\emph{An optional label for the validation step} +\item{label}{\emph{Optional label for the validation step} -\verb{scalar} // \emph{default:} \code{NULL} (\code{optional}) +\verb{vector} // \emph{default:} \code{NULL} (\code{optional}) -An optional label for the validation step. This label appears in the -\emph{agent} report and, for the best appearance, it should be kept quite short.} +Optional label for the validation step. This label appears in the \emph{agent} +report and, for the best appearance, it should be kept quite short. See +the \emph{Labels} section for more information.} \item{brief}{\emph{Brief description for the validation step} @@ -135,7 +136,7 @@ be used with \code{.} (serving as the input data table) to evaluate to a single logical value. With this approach, the \strong{pointblank} function \code{\link[=has_columns]{has_columns()}} can be used to determine whether to make a validation step active on the basis of one or more columns existing in the table -(e.g., \code{~ . \%>\% has_columns(vars(d, e))}).} +(e.g., \code{~ . \%>\% has_columns(c(d, e))}).} \item{object}{\emph{A data table for expectations or tests} @@ -216,12 +217,17 @@ formally tested (so be mindful of this when using unsupported backends with \section{Column Names}{ -If providing multiple column names in any of the supplied validation steps, -the result will be an expansion of sub-validation steps to that number of -column names. Aside from column names in quotes and in \code{vars()}, -\strong{tidyselect} helper functions are available for specifying columns. They -are: \code{starts_with()}, \code{ends_with()}, \code{contains()}, \code{matches()}, and -\code{everything()}. +\code{columns} may be a single column (as symbol \code{a} or string \code{"a"}) or a vector +of columns (\code{c(a, b, c)} or \code{c("a", "b", "c")}). \code{{tidyselect}} helpers +are also supported, such as \code{contains("date")} and \code{where(is.double)}. If +passing an \emph{external vector} of columns, it should be wrapped in \code{all_of()}. + +When multiple columns are selected by \code{columns}, the result will be an +expansion of validation steps to that number of columns (e.g., +\code{c(col_a, col_b)} will result in the entry of two validation steps). + +Previously, columns could be specified in \code{vars()}. This continues to work, +but \code{c()} offers the same capability and supersedes \code{vars()} in \code{columns}. } \section{Preconditions}{ @@ -295,6 +301,22 @@ quarter of the total test units fails, the other \code{stop()}s at the same threshold level). } +\section{Labels}{ + + +\code{label} may be a single string or a character vector that matches the number +of expanded steps. \code{label} also supports \code{{glue}} syntax and exposes the +following dynamic variables contextualized to the current step: +\itemize{ +\item \code{"{.step}"}: The validation step name +\item \code{"{.seg_col}"}: The current segment's column name +\item \code{"{.seg_val}"}: The current segment's value/group +} + +The glue context also supports ordinary expressions for further flexibility +(e.g., \code{"{toupper(.step)}"}) as long as they return a length-1 string. +} + \section{Briefs}{ @@ -321,9 +343,9 @@ R statement: \if{html}{\out{
}}\preformatted{agent \%>\% conjointly( - ~ col_vals_lt(., columns = vars(a), value = 8), - ~ col_vals_gt(., columns = vars(c), value = vars(a)), - ~ col_vals_not_null(., columns = vars(b)), + ~ col_vals_lt(., columns = a, value = 8), + ~ col_vals_gt(., columns = c, value = vars(a)), + ~ col_vals_not_null(., columns = b), preconditions = ~ . \%>\% dplyr::filter(a < 10), segments = b ~ c("group_1", "group_2"), actions = action_levels(warn_at = 0.1, stop_at = 0.2), @@ -337,9 +359,9 @@ YAML representation: \if{html}{\out{
}}\preformatted{steps: - conjointly: fns: - - ~col_vals_lt(., columns = vars(a), value = 8) - - ~col_vals_gt(., columns = vars(c), value = vars(a)) - - ~col_vals_not_null(., columns = vars(b)) + - ~col_vals_lt(., columns = a, value = 8) + - ~col_vals_gt(., columns = c, value = vars(a)) + - ~col_vals_not_null(., columns = b) preconditions: ~. \%>\% dplyr::filter(a < 10) segments: b ~ c("group_1", "group_2") actions: @@ -391,9 +413,9 @@ each row). \if{html}{\out{
}}\preformatted{agent <- create_agent(tbl = tbl) \%>\% conjointly( - ~ col_vals_lt(., columns = vars(a), value = 8), - ~ col_vals_gt(., columns = vars(c), value = vars(a)), - ~ col_vals_not_null(., columns = vars(b)) + ~ col_vals_lt(., columns = a, value = 8), + ~ col_vals_gt(., columns = c, value = vars(a)), + ~ col_vals_not_null(., columns = b) ) \%>\% interrogate() }\if{html}{\out{
}} @@ -422,9 +444,9 @@ behavior of side effects can be customized with the \code{actions} option. \if{html}{\out{
}}\preformatted{tbl \%>\% conjointly( - ~ col_vals_lt(., columns = vars(a), value = 8), - ~ col_vals_gt(., columns = vars(c), value = vars(a)), - ~ col_vals_not_null(., columns = vars(b)) + ~ col_vals_lt(., columns = a, value = 8), + ~ col_vals_gt(., columns = c, value = vars(a)), + ~ col_vals_not_null(., columns = b) ) #> # A tibble: 3 x 3 #> a b c @@ -442,9 +464,9 @@ time. This is primarily used in \strong{testthat} tests. \if{html}{\out{
}}\preformatted{expect_conjointly( tbl, - ~ col_vals_lt(., columns = vars(a), value = 8), - ~ col_vals_gt(., columns = vars(c), value = vars(a)), - ~ col_vals_not_null(., columns = vars(b)) + ~ col_vals_lt(., columns = a, value = 8), + ~ col_vals_gt(., columns = c, value = vars(a)), + ~ col_vals_not_null(., columns = b) ) }\if{html}{\out{
}} } @@ -456,9 +478,9 @@ us. \if{html}{\out{
}}\preformatted{tbl \%>\% test_conjointly( - ~ col_vals_lt(., columns = vars(a), value = 8), - ~ col_vals_gt(., columns = vars(c), value = vars(a)), - ~ col_vals_not_null(., columns = vars(b)) + ~ col_vals_lt(., columns = a, value = 8), + ~ col_vals_gt(., columns = c, value = vars(a)), + ~ col_vals_not_null(., columns = b) ) #> [1] TRUE }\if{html}{\out{
}} @@ -486,12 +508,12 @@ Other validation functions: \code{\link{col_vals_decreasing}()}, \code{\link{col_vals_equal}()}, \code{\link{col_vals_expr}()}, -\code{\link{col_vals_gte}()}, \code{\link{col_vals_gt}()}, +\code{\link{col_vals_gte}()}, \code{\link{col_vals_in_set}()}, \code{\link{col_vals_increasing}()}, -\code{\link{col_vals_lte}()}, \code{\link{col_vals_lt}()}, +\code{\link{col_vals_lte}()}, \code{\link{col_vals_make_set}()}, \code{\link{col_vals_make_subset}()}, \code{\link{col_vals_not_between}()}, diff --git a/man/create_agent.Rd b/man/create_agent.Rd index a8cfeab8d..e9462d034 100644 --- a/man/create_agent.Rd +++ b/man/create_agent.Rd @@ -19,15 +19,15 @@ create_agent( \arguments{ \item{tbl}{\emph{Table or expression for reading in one} -\verb{obj:|
} // \strong{required} +\verb{obj:|} // \strong{required} The input table. This can be a data frame, a tibble, a \code{tbl_dbi} object, or a \code{tbl_spark} object. Alternatively, an expression can be supplied to serve as instructions on how to retrieve the target table at interrogation-time. There are two ways to specify an association to a target table: (1) as a table-prep formula, which is a right-hand side (RHS) formula expression -(e.g., \verb{~ \{
\}}), or (2) as a function (e.g., -\verb{function() \{
\}}).} +(e.g., \verb{~ \{ \}}), or (2) as a function (e.g., +\verb{function() \{ \}}).} \item{tbl_name}{\emph{A table name} @@ -412,16 +412,16 @@ to actually perform the validations and gather intel. \if{html}{\out{
}}\preformatted{agent <- agent \%>\% - col_exists(columns = vars(date, date_time)) \%>\% + col_exists(columns = date, date_time) \%>\% col_vals_regex( - columns = vars(b), + columns = b, regex = "[0-9]-[a-z]\{3\}-[0-9]\{3\}" ) \%>\% rows_distinct() \%>\% - col_vals_gt(columns = vars(d), value = 100) \%>\% - col_vals_lte(columns = vars(c), value = 5) \%>\% + col_vals_gt(columns = d, value = 100) \%>\% + col_vals_lte(columns = c, value = 5) \%>\% col_vals_between( - columns = vars(c), + columns = c, left = vars(a), right = vars(d), na_pass = TRUE ) \%>\% diff --git a/man/create_informant.Rd b/man/create_informant.Rd index aa94a8176..81c808395 100644 --- a/man/create_informant.Rd +++ b/man/create_informant.Rd @@ -17,15 +17,15 @@ create_informant( \arguments{ \item{tbl}{\emph{Table or expression for reading in one} -\verb{obj:|
} // \strong{required} +\verb{obj:|} // \strong{required} The input table. This can be a data frame, a tibble, a \code{tbl_dbi} object, or a \code{tbl_spark} object. Alternatively, an expression can be supplied to serve as instructions on how to retrieve the target table at incorporation-time. There are two ways to specify an association to a target table: (1) as a table-prep formula, which is a right-hand side (RHS) formula expression -(e.g., \verb{~ \{
\}}), or (2) as a function (e.g., -\verb{function() \{
\}}).} +(e.g., \verb{~ \{ \}}), or (2) as a function (e.g., +\verb{function() \{ \}}).} \item{tbl_name}{\emph{A table name} diff --git a/man/create_multiagent.Rd b/man/create_multiagent.Rd index 8f6cf4e6b..2740aa25e 100644 --- a/man/create_multiagent.Rd +++ b/man/create_multiagent.Rd @@ -110,7 +110,7 @@ First up, is \code{agent_1}: tbl_name = "tbl_1", label = "Example table 1." ) \%>\% - col_vals_gt(columns = vars(a), value = 4) \%>\% + col_vals_gt(columns = a, value = 4) \%>\% interrogate() }\if{html}{\out{}} @@ -122,7 +122,7 @@ Then, \code{agent_2}: tbl_name = "tbl_2", label = "Example table 2." ) \%>\% - col_is_character(columns = vars(b)) \%>\% + col_is_character(columns = b) \%>\% interrogate() }\if{html}{\out{}} diff --git a/man/deactivate_steps.Rd b/man/deactivate_steps.Rd index 4158d0cba..6a0b69f4c 100644 --- a/man/deactivate_steps.Rd +++ b/man/deactivate_steps.Rd @@ -51,9 +51,9 @@ agent_1 <- tbl_name = "small_table", label = "An example." ) \%>\% - col_exists(columns = vars(date)) \%>\% + col_exists(columns = date) \%>\% col_vals_regex( - columns = vars(b), + columns = b, regex = "[0-9]-[a-z]{3}-[0-9]" ) \%>\% interrogate() diff --git a/man/draft_validation.Rd b/man/draft_validation.Rd index d07b849ed..7eda72237 100644 --- a/man/draft_validation.Rd +++ b/man/draft_validation.Rd @@ -134,7 +134,7 @@ formally tested (so be mindful of this when using unsupported backends with Let's draft a validation plan for the \code{dplyr::storms} dataset. \if{html}{\out{
}}\preformatted{dplyr::storms -#> # A tibble: 19,066 x 13 +#> # A tibble: 19,537 x 13 #> name year month day hour lat long status category wind pressure #> #> 1 Amy 1975 6 27 0 27.5 -79 tropical d~ NA 25 1013 @@ -147,7 +147,7 @@ Let's draft a validation plan for the \code{dplyr::storms} dataset. #> 8 Amy 1975 6 28 18 34 -77 tropical d~ NA 30 1006 #> 9 Amy 1975 6 29 0 34.4 -75.8 tropical s~ NA 35 1004 #> 10 Amy 1975 6 29 6 34 -74.8 tropical s~ NA 40 1002 -#> # i 19,056 more rows +#> # i 19,527 more rows #> # i 2 more variables: tropicalstorm_force_diameter , #> # hurricane_force_diameter }\if{html}{\out{
}} @@ -170,116 +170,116 @@ agent <- ) \%>\% # Expect that column `name` is of type: character col_is_character( - columns = vars(name) + columns = name ) \%>\% # Expect that column `year` is of type: numeric col_is_numeric( - columns = vars(year) + columns = year ) \%>\% # Expect that values in `year` should be between `1975` and `2020` col_vals_between( - columns = vars(year), + columns = year, left = 1975, right = 2020 ) \%>\% # Expect that column `month` is of type: numeric col_is_numeric( - columns = vars(month) + columns = month ) \%>\% # Expect that values in `month` should be between `1` and `12` col_vals_between( - columns = vars(month), + columns = month, left = 1, right = 12 ) \%>\% # Expect that column `day` is of type: integer col_is_integer( - columns = vars(day) + columns = day ) \%>\% # Expect that values in `day` should be between `1` and `31` col_vals_between( - columns = vars(day), + columns = day, left = 1, right = 31 ) \%>\% # Expect that column `hour` is of type: numeric col_is_numeric( - columns = vars(hour) + columns = hour ) \%>\% # Expect that values in `hour` should be between `0` and `23` col_vals_between( - columns = vars(hour), + columns = hour, left = 0, right = 23 ) \%>\% # Expect that column `lat` is of type: numeric col_is_numeric( - columns = vars(lat) + columns = lat ) \%>\% # Expect that values in `lat` should be between `-90` and `90` col_vals_between( - columns = vars(lat), + columns = lat, left = -90, right = 90 ) \%>\% # Expect that column `long` is of type: numeric col_is_numeric( - columns = vars(long) + columns = long ) \%>\% # Expect that values in `long` should be between `-180` and `180` col_vals_between( - columns = vars(long), + columns = long, left = -180, right = 180 ) \%>\% # Expect that column `status` is of type: character col_is_character( - columns = vars(status) + columns = status ) \%>\% # Expect that column `category` is of type: factor col_is_factor( - columns = vars(category) + columns = category ) \%>\% # Expect that column `wind` is of type: integer col_is_integer( - columns = vars(wind) + columns = wind ) \%>\% # Expect that values in `wind` should be between `10` and `160` col_vals_between( - columns = vars(wind), + columns = wind, left = 10, right = 160 ) \%>\% # Expect that column `pressure` is of type: integer col_is_integer( - columns = vars(pressure) + columns = pressure ) \%>\% # Expect that values in `pressure` should be between `882` and `1022` col_vals_between( - columns = vars(pressure), + columns = pressure, left = 882, right = 1022 ) \%>\% # Expect that column `tropicalstorm_force_diameter` is of type: integer col_is_integer( - columns = vars(tropicalstorm_force_diameter) + columns = tropicalstorm_force_diameter ) \%>\% # Expect that values in `tropicalstorm_force_diameter` should be between # `0` and `870` col_vals_between( - columns = vars(tropicalstorm_force_diameter), + columns = tropicalstorm_force_diameter, left = 0, right = 870, na_pass = TRUE ) \%>\% # Expect that column `hurricane_force_diameter` is of type: integer col_is_integer( - columns = vars(hurricane_force_diameter) + columns = hurricane_force_diameter ) \%>\% # Expect that values in `hurricane_force_diameter` should be between # `0` and `300` col_vals_between( - columns = vars(hurricane_force_diameter), + columns = hurricane_force_diameter, left = 0, right = 300, na_pass = TRUE diff --git a/man/email_blast.Rd b/man/email_blast.Rd index 1453160ed..ff75155ed 100644 --- a/man/email_blast.Rd +++ b/man/email_blast.Rd @@ -88,8 +88,8 @@ R statement: ) ) ) \%>\% - col_vals_gt(vars(a), 1) \%>\% - col_vals_lt(vars(a), 7) + col_vals_gt(a, 1) \%>\% + col_vals_lt(a, 7) }\if{html}{\out{}} YAML representation: @@ -110,10 +110,10 @@ end_fns: ~email_blast(x, to = "joe_public@example.com", embed_report: true steps: - col_vals_gt: - columns: vars(a) + columns: c(a) value: 1.0 - col_vals_lt: - columns: vars(a) + columns: c(a) value: 7.0 }\if{html}{\out{}} } @@ -170,8 +170,8 @@ interrogation of data in \code{small_table}: ) ) ) \%>\% - col_vals_gt(vars(a), value = 1) \%>\% - col_vals_lt(vars(a), value = 7) \%>\% + col_vals_gt(a, value = 1) \%>\% + col_vals_lt(a, value = 7) \%>\% interrogate() }\if{html}{\out{}} diff --git a/man/email_create.Rd b/man/email_create.Rd index 8d5e6d65b..238148346 100644 --- a/man/email_create.Rd +++ b/man/email_create.Rd @@ -62,8 +62,8 @@ email just by printing \code{email_object}. It should appear in the Viewer. label = "An example.", actions = al ) \%>\% - col_vals_gt(vars(a), value = 1) \%>\% - col_vals_lt(vars(a), value = 7) \%>\% + col_vals_gt(a, value = 1) \%>\% + col_vals_lt(a, value = 7) \%>\% interrogate() \%>\% email_create() diff --git a/man/export_report.Rd b/man/export_report.Rd index 5f6319842..fbc703b6f 100644 --- a/man/export_report.Rd +++ b/man/export_report.Rd @@ -88,14 +88,14 @@ many validation functions as we want. Then, we \code{\link[=interrogate]{interro \if{html}{\out{
}}\preformatted{agent <- agent \%>\% - col_exists(columns = vars(date, date_time)) \%>\% + col_exists(columns = c(date, date_time)) \%>\% col_vals_regex( - columns = vars(b), + columns = b, regex = "[0-9]-[a-z]\{3\}-[0-9]\{3\}" ) \%>\% rows_distinct() \%>\% - col_vals_gt(columns = vars(d), value = 100) \%>\% - col_vals_lte(columns = vars(c), value = 5) \%>\% + col_vals_gt(columns = d, value = 100) \%>\% + col_vals_lte(columns = c, value = 5) \%>\% interrogate() }\if{html}{\out{
}} @@ -147,7 +147,7 @@ integrated into the text. fn = snip_lowest(column = "a") ) \%>\% info_columns( - columns = vars(a), + columns = a, info = "From \{low_a\} to \{high_a\}." ) \%>\% info_columns( @@ -155,7 +155,7 @@ integrated into the text. info = "Time-based values." ) \%>\% info_columns( - columns = "date", + columns = date, info = "The date part of `date_time`." ) \%>\% incorporate() diff --git a/man/figures/logo_static.png b/man/figures/logo_static.png new file mode 100644 index 000000000..dbc5fa81e Binary files /dev/null and b/man/figures/logo_static.png differ diff --git a/man/file_tbl.Rd b/man/file_tbl.Rd index 14382a5c5..2a72b1e42 100644 --- a/man/file_tbl.Rd +++ b/man/file_tbl.Rd @@ -115,7 +115,7 @@ A different strategy is to provide the data-reading function call directly to col_types = "TDdcddlc" ) ) \%>\% - col_vals_gt(columns = vars(a), value = 0) + col_vals_gt(columns = a, value = 0) }\if{html}{\out{}} All of the file-reading instructions are encapsulated in the \code{tbl} expression @@ -142,7 +142,7 @@ gets the same CSV file from the GitHub repository for the pointblank package. tbl_name = "small_table", label = "`file_tbl()` example.", ) \%>\% - col_vals_gt(columns = vars(a), value = 0) \%>\% + col_vals_gt(columns = a, value = 0) \%>\% interrogate() }\if{html}{\out{}} diff --git a/man/from_github.Rd b/man/from_github.Rd index ae2079b4d..449d5f3df 100644 --- a/man/from_github.Rd +++ b/man/from_github.Rd @@ -65,7 +65,7 @@ where GitHub URLs for raw user content are needed. # col_types = "TDdcddlc" # ) # ) \%>\% -# col_vals_gt(vars(a), 0) \%>\% +# col_vals_gt(a, 0) \%>\% # interrogate() # The `from_github()` helper function is @@ -97,8 +97,8 @@ where GitHub URLs for raw user content are needed. } \seealso{ Other Utility and Helper Functions: -\code{\link{affix_datetime}()}, \code{\link{affix_date}()}, +\code{\link{affix_datetime}()}, \code{\link{col_schema}()}, \code{\link{has_columns}()}, \code{\link{stop_if_not}()} diff --git a/man/game_revenue.Rd b/man/game_revenue.Rd index 510eae0b2..ae876a830 100644 --- a/man/game_revenue.Rd +++ b/man/game_revenue.Rd @@ -53,8 +53,8 @@ dplyr::glimpse(game_revenue) \seealso{ Other Datasets: \code{\link{game_revenue_info}}, -\code{\link{small_table_sqlite}()}, \code{\link{small_table}}, +\code{\link{small_table_sqlite}()}, \code{\link{specifications}} } \concept{Datasets} diff --git a/man/game_revenue_info.Rd b/man/game_revenue_info.Rd index 191f368f5..cfb8d5dbf 100644 --- a/man/game_revenue_info.Rd +++ b/man/game_revenue_info.Rd @@ -37,8 +37,8 @@ dplyr::glimpse(game_revenue_info) \seealso{ Other Datasets: \code{\link{game_revenue}}, -\code{\link{small_table_sqlite}()}, \code{\link{small_table}}, +\code{\link{small_table_sqlite}()}, \code{\link{specifications}} } \concept{Datasets} diff --git a/man/get_agent_report.Rd b/man/get_agent_report.Rd index ca3613cbe..e0c8a5366 100644 --- a/man/get_agent_report.Rd +++ b/man/get_agent_report.Rd @@ -211,7 +211,7 @@ greater than \code{4}. tbl_name = "small_table", label = "An example." ) \%>\% - col_vals_gt(columns = vars(a), value = 4) \%>\% + col_vals_gt(columns = a, value = 4) \%>\% interrogate() }\if{html}{\out{}} diff --git a/man/get_agent_x_list.Rd b/man/get_agent_x_list.Rd index 0f9acaaa1..653787c3f 100644 --- a/man/get_agent_x_list.Rd +++ b/man/get_agent_x_list.Rd @@ -136,8 +136,8 @@ validation step functions, then interrogate. tbl = tbl, actions = al ) \%>\% - col_vals_gt(columns = vars(a), value = 7) \%>\% - col_is_numeric(columns = vars(a)) \%>\% + col_vals_gt(columns = a, value = 7) \%>\% + col_is_numeric(columns = a) \%>\% interrogate() }\if{html}{\out{}} diff --git a/man/get_data_extracts.Rd b/man/get_data_extracts.Rd index 01d6c9fba..f86631c63 100644 --- a/man/get_data_extracts.Rd +++ b/man/get_data_extracts.Rd @@ -63,9 +63,9 @@ part of the \code{small_table} object. Use \code{\link[=interrogate]{interrogate dplyr::select(a:f), label = "`get_data_extracts()`" ) \%>\% - col_vals_gt(vars(d), value = 1000) \%>\% + col_vals_gt(d, value = 1000) \%>\% col_vals_between( - columns = vars(c), + columns = c, left = vars(a), right = vars(d), na_pass = TRUE ) \%>\% diff --git a/man/get_multiagent_report.Rd b/man/get_multiagent_report.Rd index 05847840d..d37215ecd 100644 --- a/man/get_multiagent_report.Rd +++ b/man/get_multiagent_report.Rd @@ -158,32 +158,32 @@ steps are created and the agent will interrogate the \code{small_table}. actions = al ) \%>\% col_vals_gt( - columns = vars(date_time), + columns = date_time, value = vars(date), na_pass = TRUE ) \%>\% col_vals_gt( - columns = vars(b), + columns = b, value = vars(g), na_pass = TRUE ) \%>\% rows_distinct() \%>\% col_vals_equal( - columns = vars(d), + columns = d, value = vars(d), na_pass = TRUE ) \%>\% col_vals_between( - columns = vars(c), + columns = c, left = vars(a), right = vars(d) ) \%>\% col_vals_not_between( - columns = vars(c), + columns = c, left = 10, right = 20, na_pass = TRUE ) \%>\% - rows_distinct(columns = vars(d, e, f)) \%>\% - col_is_integer(columns = vars(a)) \%>\% + rows_distinct(columns = d, e, f) \%>\% + col_is_integer(columns = a) \%>\% interrogate() }\if{html}{\out{}} @@ -192,9 +192,9 @@ two more (the last of which is inactive). \if{html}{\out{
}}\preformatted{agent_2 <- agent_1 \%>\% - col_exists(columns = vars(date, date_time)) \%>\% + col_exists(columns = date, date_time) \%>\% col_vals_regex( - columns = vars(b), + columns = b, regex = "[0-9]-[a-z]\{3\}-[0-9]\{3\}", active = FALSE ) \%>\% @@ -207,7 +207,7 @@ one, and deactivates the first. \if{html}{\out{
}}\preformatted{agent_3 <- agent_2 \%>\% col_vals_in_set( - columns = vars(f), + columns = f, set = c("low", "mid", "high") ) \%>\% remove_steps(i = 5) \%>\% diff --git a/man/get_sundered_data.Rd b/man/get_sundered_data.Rd index c2fdce8d7..e605a0a3d 100644 --- a/man/get_sundered_data.Rd +++ b/man/get_sundered_data.Rd @@ -84,9 +84,9 @@ validation plan into action. dplyr::select(a:f), label = "`get_sundered_data()`" ) \%>\% - col_vals_gt(columns = vars(d), value = 1000) \%>\% + col_vals_gt(columns = d, value = 1000) \%>\% col_vals_between( - columns = vars(c), + columns = c, left = vars(a), right = vars(d), na_pass = TRUE ) \%>\% diff --git a/man/get_tt_param.Rd b/man/get_tt_param.Rd index 3135f94d9..03db34e79 100644 --- a/man/get_tt_param.Rd +++ b/man/get_tt_param.Rd @@ -94,7 +94,7 @@ the first quarter of the year, we can supply a value from \code{stats_tbl} to keep = "right" ) \%>\% test_col_vals_lte( - columns = vars(session_duration), + columns = session_duration, value = get_tt_param( tbl = stats_tbl, param = "max", diff --git a/man/has_columns.Rd b/man/has_columns.Rd index a524d66c5..312c4b08d 100644 --- a/man/has_columns.Rd +++ b/man/has_columns.Rd @@ -16,10 +16,10 @@ The input table. This can be a data frame, tibble, a \code{tbl_dbi} object, or a \item{columns}{\emph{The target columns} -`vector\if{html}{\out{}}|vars(\if{html}{\out{}})`` // \strong{required} +\verb{} // \emph{required} -One or more column names that are to be checked for existence in the table -\code{x}.} +One or more columns or column-selecting expressions. Each element is +checked for a match in the table \code{x}.} } \value{ A length-1 logical vector. @@ -28,9 +28,9 @@ A length-1 logical vector. This utility function can help you easily determine whether a column of a specified name is present in a table object. This function works well enough on a table object but it can also be used as part of a formula in any -validation function's \code{active} argument. Using \code{active = ~ . \%>\% has_columns("column_1")} means that the validation step will be inactive if +validation function's \code{active} argument. Using \code{active = ~ . \%>\% has_columns(column_1)} means that the validation step will be inactive if the target table doesn't contain a column named \code{column_1}. We can also use -multiple columns in \code{vars()} so having \code{active = ~ . \%>\% has_columns(vars(column_1, column_2))} in a validation step will make it +multiple columns in \code{c()}, so having \code{active = ~ . \%>\% has_columns(c(column_1, column_2))} in a validation step will make it inactive at \code{\link[=interrogate]{interrogate()}} time unless the columns \code{column_1} and \code{column_2} are both present. } @@ -60,10 +60,9 @@ and the \code{a} through \code{f} columns. }\if{html}{\out{
}} With \code{has_columns()} we can check for column existence by using it directly -on the table. A column name can be verified as present by using it in double -quotes. +on the table. -\if{html}{\out{
}}\preformatted{small_table \%>\% has_columns(columns = "date") +\if{html}{\out{
}}\preformatted{small_table \%>\% has_columns(columns = date) }\if{html}{\out{
}} \if{html}{\out{
}}\preformatted{## [1] TRUE @@ -72,15 +71,15 @@ quotes. Multiple column names can be supplied. The following is \code{TRUE} because both columns are present in \code{small_table}. -\if{html}{\out{
}}\preformatted{small_table \%>\% has_columns(columns = c("a", "b")) +\if{html}{\out{
}}\preformatted{small_table \%>\% has_columns(columns = c(a, b)) }\if{html}{\out{
}} \if{html}{\out{
}}\preformatted{## [1] TRUE }\if{html}{\out{
}} -It's possible to supply column names in \code{vars()} as well: +It's possible to use a tidyselect helper as well: -\if{html}{\out{
}}\preformatted{small_table \%>\% has_columns(columns = vars(a, b)) +\if{html}{\out{
}}\preformatted{small_table \%>\% has_columns(columns = c(a, starts_with("b"))) }\if{html}{\out{
}} \if{html}{\out{
}}\preformatted{## [1] TRUE @@ -89,12 +88,24 @@ It's possible to supply column names in \code{vars()} as well: Because column \code{h} isn't present, this returns \code{FALSE} (all specified columns need to be present to obtain \code{TRUE}). -\if{html}{\out{
}}\preformatted{small_table \%>\% has_columns(columns = vars(a, h)) +\if{html}{\out{
}}\preformatted{small_table \%>\% has_columns(columns = c(a, h)) }\if{html}{\out{
}} \if{html}{\out{
}}\preformatted{## [1] FALSE }\if{html}{\out{
}} +The same holds in the case of tidyselect helpers. Because no columns start +with \code{"h"}, including \code{starts_with("h")} returns \code{FALSE} for the entire +check. + +\if{html}{\out{
}}\preformatted{small_table \%>\% has_columns(columns = starts_with("h")) +small_table \%>\% has_columns(columns = c(a, starts_with("h"))) +}\if{html}{\out{
}} + +\if{html}{\out{
}}\preformatted{## [1] FALSE +## [1] FALSE +}\if{html}{\out{
}} + The \code{has_columns()} function can be useful in expressions that involve the target table, especially if it is uncertain that the table will contain a column that's involved in a validation. @@ -110,17 +121,17 @@ statement there we would get an evaluation failure in the agent report). tbl_name = "small_table" ) \%>\% col_vals_gt( - columns = vars(c), value = vars(a), - active = ~ . \%>\% has_columns(vars(a, c)) + columns = c, value = vars(a), + active = ~ . \%>\% has_columns(c(a, c)) ) \%>\% col_vals_lt( - columns = vars(h), value = vars(d), + columns = h, value = vars(d), preconditions = ~ . \%>\% dplyr::mutate(h = d - a), - active = ~ . \%>\% has_columns(vars(a, d)) + active = ~ . \%>\% has_columns(c(a, d)) ) \%>\% col_is_character( - columns = vars(j), - active = ~ . \%>\% has_columns("j") + columns = j, + active = ~ . \%>\% has_columns(j) ) \%>\% interrogate() }\if{html}{\out{
}} @@ -146,8 +157,8 @@ x_list$eval_warning \seealso{ Other Utility and Helper Functions: -\code{\link{affix_datetime}()}, \code{\link{affix_date}()}, +\code{\link{affix_datetime}()}, \code{\link{col_schema}()}, \code{\link{from_github}()}, \code{\link{stop_if_not}()} diff --git a/man/incorporate.Rd b/man/incorporate.Rd index ea49f51cc..e8fec901b 100644 --- a/man/incorporate.Rd +++ b/man/incorporate.Rd @@ -76,7 +76,7 @@ use \code{incorporate()} to work the snippets into the info text. fn = ~ . \%>\% ncol() ) \%>\% info_columns( - columns = vars(a), + columns = a, info = "In the range of 1 to 10. ((SIMPLE))" ) \%>\% info_columns( @@ -84,7 +84,7 @@ use \code{incorporate()} to work the snippets into the info text. info = "Time-based values (e.g., `Sys.time()`)." ) \%>\% info_columns( - columns = "date", + columns = date, info = "The date part of `date_time`. ((CALC))" ) \%>\% info_section( diff --git a/man/info_columns.Rd b/man/info_columns.Rd index ed05f1719..b4f47e783 100644 --- a/man/info_columns.Rd +++ b/man/info_columns.Rd @@ -16,7 +16,7 @@ use of the \code{\link[=create_informant]{create_informant()}} function.} \item{columns}{\emph{The target columns} -`vector\if{html}{\out{}}|vars(\if{html}{\out{}})`` // \strong{required} +\verb{vector|vars()} // \strong{required} The column or set of columns to focus on. Can be defined as a column name in quotes (e.g., \code{""}), one or more column names in \code{vars()} @@ -114,19 +114,19 @@ the YAML representation. \if{html}{\out{
}}\preformatted{# R statement informant \%>\% info_columns( - columns = "date_time", + columns = date_time, info = "*info text* 1." ) \%>\% info_columns( - columns = "date", + columns = date, info = "*info text* 2." ) \%>\% info_columns( - columns = "item_count", + columns = item_count, info = "*info text* 3. Statistics: \{snippet_1\}." ) \%>\% info_columns( - columns = vars(date, date_time), + columns = c(date, date_time), info = "UTC time." ) @@ -185,7 +185,7 @@ existing if it lands in the same area). \if{html}{\out{
}}\preformatted{informant <- informant \%>\% info_columns( - columns = vars(a), + columns = a, info = "In the range of 1 to 10. ((SIMPLE))" ) \%>\% info_columns( @@ -193,7 +193,7 @@ existing if it lands in the same area). info = "Time-based values (e.g., `Sys.time()`)." ) \%>\% info_columns( - columns = "date", + columns = date, info = "The date part of `date_time`. ((CALC))" ) }\if{html}{\out{
}} diff --git a/man/info_columns_from_tbl.Rd b/man/info_columns_from_tbl.Rd index 7ee183c27..82dc6dd88 100644 --- a/man/info_columns_from_tbl.Rd +++ b/man/info_columns_from_tbl.Rd @@ -116,11 +116,11 @@ and \code{acquisition} columns and view the updated report. \if{html}{\out{
}}\preformatted{informant <- informant \%>\% info_columns( - columns = "item_revenue", + columns = item_revenue, info = "Revenue reported in USD." ) \%>\% info_columns( - columns = "acquisition", + columns = acquisition, `top list` = "\{top5_aq\}" ) \%>\% info_snippet( diff --git a/man/info_section.Rd b/man/info_section.Rd index 77b8c2e03..99aedaa75 100644 --- a/man/info_section.Rd +++ b/man/info_section.Rd @@ -16,7 +16,7 @@ use of the \code{\link[=create_informant]{create_informant()}} function.} \item{section_name}{\emph{The section name} -`scalar\if{html}{\out{}}`` // \strong{required} +\verb{scalar} // \strong{required} The name of the section for which this information pertains.} @@ -192,8 +192,8 @@ section and its own information. \seealso{ Other Information Functions: -\code{\link{info_columns_from_tbl}()}, \code{\link{info_columns}()}, +\code{\link{info_columns_from_tbl}()}, \code{\link{info_snippet}()}, \code{\link{info_tabular}()}, \code{\link{snip_highest}()}, diff --git a/man/info_snippet.Rd b/man/info_snippet.Rd index 82d9a3e91..3bded7f26 100644 --- a/man/info_snippet.Rd +++ b/man/info_snippet.Rd @@ -16,7 +16,7 @@ use of the \code{\link[=create_informant]{create_informant()}} function.} \item{snippet_name}{\emph{The snippet name} -`scalar\if{html}{\out{}}`` // \strong{required} +\verb{scalar} // \strong{required} The name for snippet, which is used for interpolating the result of the snippet formula into \emph{info text} defined by an \verb{info_*()} function.} @@ -80,7 +80,7 @@ demonstrate their relationship here). \if{html}{\out{
}}\preformatted{# R statement informant \%>\% info_columns( - columns = "date_time", + columns = date_time, `Latest Date` = "The latest date is \{latest_date\}." ) \%>\% info_snippet( @@ -135,7 +135,7 @@ the highest value in that column). fn = snip_highest(column = "a") ) \%>\% info_columns( - columns = vars(a), + columns = a, info = "In the range of 1 to \{max_a\}. ((SIMPLE))" ) \%>\% info_columns( @@ -143,7 +143,7 @@ the highest value in that column). info = "Time-based values (e.g., `Sys.time()`)." ) \%>\% info_columns( - columns = "date", + columns = date, info = "The date part of `date_time`. ((CALC))" ) \%>\% info_section( @@ -194,8 +194,8 @@ informant \seealso{ Other Information Functions: -\code{\link{info_columns_from_tbl}()}, \code{\link{info_columns}()}, +\code{\link{info_columns_from_tbl}()}, \code{\link{info_section}()}, \code{\link{info_tabular}()}, \code{\link{snip_highest}()}, diff --git a/man/info_tabular.Rd b/man/info_tabular.Rd index 1b0bbcba7..4d78d3f56 100644 --- a/man/info_tabular.Rd +++ b/man/info_tabular.Rd @@ -175,8 +175,8 @@ Upon printing the \code{informant} object, we see the additions made to the \seealso{ Other Information Functions: -\code{\link{info_columns_from_tbl}()}, \code{\link{info_columns}()}, +\code{\link{info_columns_from_tbl}()}, \code{\link{info_section}()}, \code{\link{info_snippet}()}, \code{\link{snip_highest}()}, diff --git a/man/interrogate.Rd b/man/interrogate.Rd index 2a3f94fb0..1a16c3efe 100644 --- a/man/interrogate.Rd +++ b/man/interrogate.Rd @@ -7,10 +7,13 @@ interrogate( agent, extract_failed = TRUE, + extract_tbl_checked = TRUE, get_first_n = NULL, sample_n = NULL, sample_frac = NULL, - sample_limit = 5000 + sample_limit = 5000, + show_step_label = FALSE, + progress = interactive() ) } \arguments{ @@ -29,6 +32,15 @@ An option to collect rows that didn't pass a particular validation step. The default is \code{TRUE} and further options allow for fine control of how these rows are collected.} +\item{extract_tbl_checked}{\emph{Collect validation results from each step} + +\verb{scalar} // \emph{default:} \code{TRUE} + +An option to collect processed data frames produced by executing the +validation steps. This information is necessary for some functions +(e.g., \code{get_sundered_data()}), but may grow to a large size. To opt out +of attaching this data to the agent, set this argument to \code{FALSE}.} + \item{get_first_n}{\emph{Get the first n values} \verb{scalar} // \emph{default:} \code{NULL} (\code{optional}) @@ -63,6 +75,19 @@ option will apply a hard limit to the returned rows.} A value that limits the possible number of rows returned when sampling non-passing rows using the \code{sample_frac} option.} + +\item{show_step_label}{\emph{Show step labels in progress} + +\verb{scalar} // \emph{default:} \code{FALSE} + +Whether to show the \code{label} value of each validation step in the console.} + +\item{progress}{\emph{Show interrogation progress} + +\verb{scalar} // \emph{default:} \code{interactive()} + +Whether to show the progress of an agent's interrogation in the console. +Defaults to \code{TRUE} in interactive sessions.} } \value{ A \code{ptblank_agent} object. @@ -106,7 +131,7 @@ process. tbl = tbl, label = "`interrogate()` example" ) \%>\% - col_vals_gt(columns = vars(a), value = 5) \%>\% + col_vals_gt(columns = a, value = 5) \%>\% interrogate() }\if{html}{\out{
}} diff --git a/man/log4r_step.Rd b/man/log4r_step.Rd index 0ef02bab7..7404623c4 100644 --- a/man/log4r_step.Rd +++ b/man/log4r_step.Rd @@ -129,8 +129,8 @@ then \code{\link[=interrogate]{interrogate()}} the data. label = "An example.", actions = al ) \%>\% - col_vals_gt(columns = vars(d), 300) \%>\% - col_vals_in_set(columns = vars(f), c("low", "high")) \%>\% + col_vals_gt(columns = d, 300) \%>\% + col_vals_in_set(columns = f, c("low", "high")) \%>\% interrogate() agent diff --git a/man/reexports.Rd b/man/reexports.Rd index 1330c7128..af3bc8b97 100644 --- a/man/reexports.Rd +++ b/man/reexports.Rd @@ -7,11 +7,6 @@ \alias{case_when} \alias{between} \alias{expr} -\alias{starts_with} -\alias{ends_with} -\alias{contains} -\alias{matches} -\alias{everything} \alias{creds} \alias{creds_anonymous} \alias{creds_key} @@ -28,7 +23,5 @@ below to see their documentation. \item{dplyr}{\code{\link[dplyr]{between}}, \code{\link[dplyr]{case_when}}, \code{\link[dplyr]{vars}}} \item{rlang}{\code{\link[rlang]{expr}}} - - \item{tidyselect}{\code{\link[tidyselect:starts_with]{contains}}, \code{\link[tidyselect:starts_with]{ends_with}}, \code{\link[tidyselect]{everything}}, \code{\link[tidyselect:starts_with]{matches}}, \code{\link[tidyselect]{starts_with}}} }} diff --git a/man/remove_steps.Rd b/man/remove_steps.Rd index 49d4df3b5..ff4aa4af4 100644 --- a/man/remove_steps.Rd +++ b/man/remove_steps.Rd @@ -51,9 +51,9 @@ agent_1 <- tbl_name = "small_table", label = "An example." ) \%>\% - col_exists(columns = vars(date)) \%>\% + col_exists(columns = date) \%>\% col_vals_regex( - columns = vars(b), + columns = b, regex = "[0-9]-[a-z]{3}-[0-9]" ) \%>\% interrogate() diff --git a/man/row_count_match.Rd b/man/row_count_match.Rd index 9ffae4436..feb0e5887 100644 --- a/man/row_count_match.Rd +++ b/man/row_count_match.Rd @@ -52,10 +52,9 @@ Either a literal value for the number of rows, or, a table to compare against the target table in terms of row count values. If supplying a comparison table, it can either be a table object such as a data frame, a tibble, a \code{tbl_dbi} object, or a \code{tbl_spark} object. Alternatively, a -table-prep formula (\verb{~
}) or a function (`function()\if{html}{\out{ -
`) can be used to lazily read in the comparison table - at interrogation time. -}}} +table-prep formula (\verb{~ }) or a function +(\verb{function() }) can be used to lazily read in the +comparison table at interrogation time.} \item{preconditions}{\emph{Input table modification prior to validation} @@ -101,12 +100,13 @@ produce (influenced by the number of \code{columns} provided), (2) be an ID string not used in any previous validation step, and (3) be a vector with unique values.} -\item{label}{\emph{An optional label for the validation step} +\item{label}{\emph{Optional label for the validation step} -\verb{scalar} // \emph{default:} \code{NULL} (\code{optional}) +\verb{vector} // \emph{default:} \code{NULL} (\code{optional}) -An optional label for the validation step. This label appears in the -\emph{agent} report and, for the best appearance, it should be kept quite short.} +Optional label for the validation step. This label appears in the \emph{agent} +report and, for the best appearance, it should be kept quite short. See +the \emph{Labels} section for more information.} \item{brief}{\emph{Brief description for the validation step} @@ -133,7 +133,7 @@ be used with \code{.} (serving as the input data table) to evaluate to a single logical value. With this approach, the \strong{pointblank} function \code{\link[=has_columns]{has_columns()}} can be used to determine whether to make a validation step active on the basis of one or more columns existing in the table -(e.g., \code{~ . \%>\% has_columns(vars(d, e))}).} +(e.g., \code{~ . \%>\% has_columns(c(d, e))}).} \item{tbl_compare}{\emph{\link{Deprecated} Comparison table} @@ -270,6 +270,22 @@ depending on the situation (the first produces a warning, the other \code{stop()}s). } +\section{Labels}{ + + +\code{label} may be a single string or a character vector that matches the number +of expanded steps. \code{label} also supports \code{{glue}} syntax and exposes the +following dynamic variables contextualized to the current step: +\itemize{ +\item \code{"{.step}"}: The validation step name +\item \code{"{.seg_col}"}: The current segment's column name +\item \code{"{.seg_val}"}: The current segment's value/group +} + +The glue context also supports ordinary expressions for further flexibility +(e.g., \code{"{toupper(.step)}"}) as long as they return a length-1 string. +} + \section{Briefs}{ @@ -459,12 +475,12 @@ Other validation functions: \code{\link{col_vals_decreasing}()}, \code{\link{col_vals_equal}()}, \code{\link{col_vals_expr}()}, -\code{\link{col_vals_gte}()}, \code{\link{col_vals_gt}()}, +\code{\link{col_vals_gte}()}, \code{\link{col_vals_in_set}()}, \code{\link{col_vals_increasing}()}, -\code{\link{col_vals_lte}()}, \code{\link{col_vals_lt}()}, +\code{\link{col_vals_lte}()}, \code{\link{col_vals_make_set}()}, \code{\link{col_vals_make_subset}()}, \code{\link{col_vals_not_between}()}, diff --git a/man/rows_complete.Rd b/man/rows_complete.Rd index 8152b3297..3a3c9af3e 100644 --- a/man/rows_complete.Rd +++ b/man/rows_complete.Rd @@ -8,7 +8,7 @@ \usage{ rows_complete( x, - columns = NULL, + columns = tidyselect::everything(), preconditions = NULL, segments = NULL, actions = NULL, @@ -20,12 +20,17 @@ rows_complete( expect_rows_complete( object, - columns = NULL, + columns = tidyselect::everything(), preconditions = NULL, threshold = 1 ) -test_rows_complete(object, columns = NULL, preconditions = NULL, threshold = 1) +test_rows_complete( + object, + columns = tidyselect::everything(), + preconditions = NULL, + threshold = 1 +) } \arguments{ \item{x}{\emph{A pointblank agent or a data table} @@ -38,10 +43,11 @@ commonly created with \code{\link[=create_agent]{create_agent()}}.} \item{columns}{\emph{The target columns} -\verb{} // \strong{required} +\verb{} // \emph{default:} \code{everything()} -The column (or a set of columns, provided as a character vector) to which -this validation should be applied.} +A column-selecting expression, as one would use inside \code{dplyr::select()}. +Specifies the set of column(s) for which the completeness of rows is +checked.} \item{preconditions}{\emph{Input table modification prior to validation} @@ -87,12 +93,13 @@ produce (influenced by the number of \code{columns} provided), (2) be an ID string not used in any previous validation step, and (3) be a vector with unique values.} -\item{label}{\emph{An optional label for the validation step} +\item{label}{\emph{Optional label for the validation step} -\verb{scalar} // \emph{default:} \code{NULL} (\code{optional}) +\verb{vector} // \emph{default:} \code{NULL} (\code{optional}) -An optional label for the validation step. This label appears in the -\emph{agent} report and, for the best appearance, it should be kept quite short.} +Optional label for the validation step. This label appears in the \emph{agent} +report and, for the best appearance, it should be kept quite short. See +the \emph{Labels} section for more information.} \item{brief}{\emph{Brief description for the validation step} @@ -119,7 +126,7 @@ be used with \code{.} (serving as the input data table) to evaluate to a single logical value. With this approach, the \strong{pointblank} function \code{\link[=has_columns]{has_columns()}} can be used to determine whether to make a validation step active on the basis of one or more columns existing in the table -(e.g., \code{~ . \%>\% has_columns(vars(d, e))}).} +(e.g., \code{~ . \%>\% has_columns(c(d, e))}).} \item{object}{\emph{A data table for expectations or tests} @@ -161,10 +168,6 @@ directly on a data table or with an \emph{agent} object (technically, a be used with a data table. As a validation step or as an expectation, this will operate over the number of test units that is equal to the number of rows in the table (after any \code{preconditions} have been applied). - -We can specify the constraining column names in quotes, in \code{vars()}, and with -the following \strong{tidyselect} helper functions: \code{starts_with()}, -\code{ends_with()}, \code{contains()}, \code{matches()}, and \code{everything()}. } \section{Supported Input Tables}{ @@ -255,6 +258,23 @@ warning when a quarter of the total test units fails, the other \code{stop()}s a the same threshold level). } +\section{Labels}{ + + +\code{label} may be a single string or a character vector that matches the number +of expanded steps. \code{label} also supports \code{{glue}} syntax and exposes the +following dynamic variables contextualized to the current step: +\itemize{ +\item \code{"{.step}"}: The validation step name +\item \code{"{.col}"}: The current column name +\item \code{"{.seg_col}"}: The current segment's column name +\item \code{"{.seg_val}"}: The current segment's value/group +} + +The glue context also supports ordinary expressions for further flexibility +(e.g., \code{"{toupper(.step)}"}) as long as they return a length-1 string. +} + \section{Briefs}{ @@ -281,7 +301,7 @@ R statement: \if{html}{\out{
}}\preformatted{agent \%>\% rows_complete( - columns = vars(a, b), + columns = c(a, b), preconditions = ~ . \%>\% dplyr::filter(a < 10), segments = b ~ c("group_1", "group_2"), actions = action_levels(warn_at = 0.1, stop_at = 0.2), @@ -294,7 +314,7 @@ YAML representation: \if{html}{\out{
}}\preformatted{steps: - rows_complete: - columns: vars(a, b) + columns: c(a, b) preconditions: ~. \%>\% dplyr::filter(a < 10) segments: b ~ c("group_1", "group_2") actions: @@ -343,7 +363,7 @@ only complete rows (i.e., all rows have no \code{NA} values). \if{html}{\out{
}}\preformatted{agent <- create_agent(tbl = tbl) \%>\% - rows_complete(columns = vars(a, b)) \%>\% + rows_complete(columns = c(a, b)) \%>\% interrogate() }\if{html}{\out{
}} @@ -365,7 +385,7 @@ through but should \code{stop()} if there is a single test unit failing. The behavior of side effects can be customized with the \code{actions} option. \if{html}{\out{
}}\preformatted{tbl \%>\% - rows_complete(columns = vars(a, b)) \%>\% + rows_complete(columns = c(a, b)) \%>\% dplyr::pull(a) #> [1] 5 7 6 5 8 7 }\if{html}{\out{
}} @@ -376,7 +396,7 @@ behavior of side effects can be customized with the \code{actions} option. With the \verb{expect_*()} form, we would typically perform one validation at a time. This is primarily used in \strong{testthat} tests. -\if{html}{\out{
}}\preformatted{expect_rows_complete(tbl, columns = vars(a, b)) +\if{html}{\out{
}}\preformatted{expect_rows_complete(tbl, columns = c(a, b)) }\if{html}{\out{
}} } @@ -385,7 +405,7 @@ time. This is primarily used in \strong{testthat} tests. With the \verb{test_*()} form, we should get a single logical value returned to us. -\if{html}{\out{
}}\preformatted{test_rows_complete(tbl, columns = vars(a, b)) +\if{html}{\out{
}}\preformatted{test_rows_complete(tbl, columns = c(a, b)) #> [1] TRUE }\if{html}{\out{
}} } @@ -412,12 +432,12 @@ Other validation functions: \code{\link{col_vals_decreasing}()}, \code{\link{col_vals_equal}()}, \code{\link{col_vals_expr}()}, -\code{\link{col_vals_gte}()}, \code{\link{col_vals_gt}()}, +\code{\link{col_vals_gte}()}, \code{\link{col_vals_in_set}()}, \code{\link{col_vals_increasing}()}, -\code{\link{col_vals_lte}()}, \code{\link{col_vals_lt}()}, +\code{\link{col_vals_lte}()}, \code{\link{col_vals_make_set}()}, \code{\link{col_vals_make_subset}()}, \code{\link{col_vals_not_between}()}, diff --git a/man/rows_distinct.Rd b/man/rows_distinct.Rd index 4af7c79ec..5372bf17a 100644 --- a/man/rows_distinct.Rd +++ b/man/rows_distinct.Rd @@ -8,7 +8,7 @@ \usage{ rows_distinct( x, - columns = NULL, + columns = tidyselect::everything(), preconditions = NULL, segments = NULL, actions = NULL, @@ -20,12 +20,17 @@ rows_distinct( expect_rows_distinct( object, - columns = NULL, + columns = tidyselect::everything(), preconditions = NULL, threshold = 1 ) -test_rows_distinct(object, columns = NULL, preconditions = NULL, threshold = 1) +test_rows_distinct( + object, + columns = tidyselect::everything(), + preconditions = NULL, + threshold = 1 +) } \arguments{ \item{x}{\emph{A pointblank agent or a data table} @@ -38,10 +43,11 @@ commonly created with \code{\link[=create_agent]{create_agent()}}.} \item{columns}{\emph{The target columns} -\verb{} // \strong{required} +\verb{} // \emph{default:} \code{everything()} -The column (or a set of columns, provided as a character vector) to which -this validation should be applied.} +A column-selecting expression, as one would use inside \code{dplyr::select()}. +Specifies the set of column(s) for which the distinctness of rows is +checked.} \item{preconditions}{\emph{Input table modification prior to validation} @@ -87,12 +93,13 @@ produce (influenced by the number of \code{columns} provided), (2) be an ID string not used in any previous validation step, and (3) be a vector with unique values.} -\item{label}{\emph{An optional label for the validation step} +\item{label}{\emph{Optional label for the validation step} -\verb{scalar} // \emph{default:} \code{NULL} (\code{optional}) +\verb{vector} // \emph{default:} \code{NULL} (\code{optional}) -An optional label for the validation step. This label appears in the -\emph{agent} report and, for the best appearance, it should be kept quite short.} +Optional label for the validation step. This label appears in the \emph{agent} +report and, for the best appearance, it should be kept quite short. See +the \emph{Labels} section for more information.} \item{brief}{\emph{Brief description for the validation step} @@ -119,7 +126,7 @@ be used with \code{.} (serving as the input data table) to evaluate to a single logical value. With this approach, the \strong{pointblank} function \code{\link[=has_columns]{has_columns()}} can be used to determine whether to make a validation step active on the basis of one or more columns existing in the table -(e.g., \code{~ . \%>\% has_columns(vars(d, e))}).} +(e.g., \code{~ . \%>\% has_columns(c(d, e))}).} \item{object}{\emph{A data table for expectations or tests} @@ -162,10 +169,6 @@ expectation and test functions can only be used with a data table. As a validation step or as an expectation, this will operate over the number of test units that is equal to the number of rows in the table (after any \code{preconditions} have been applied). - -We can specify the constraining column names in quotes, in \code{vars()}, and with -the following \strong{tidyselect} helper functions: \code{starts_with()}, -\code{ends_with()}, \code{contains()}, \code{matches()}, and \code{everything()}. } \section{Supported Input Tables}{ @@ -256,6 +259,23 @@ warning when a quarter of the total test units fails, the other \code{stop()}s a the same threshold level). } +\section{Labels}{ + + +\code{label} may be a single string or a character vector that matches the number +of expanded steps. \code{label} also supports \code{{glue}} syntax and exposes the +following dynamic variables contextualized to the current step: +\itemize{ +\item \code{"{.step}"}: The validation step name +\item \code{"{.col}"}: The current column name +\item \code{"{.seg_col}"}: The current segment's column name +\item \code{"{.seg_val}"}: The current segment's value/group +} + +The glue context also supports ordinary expressions for further flexibility +(e.g., \code{"{toupper(.step)}"}) as long as they return a length-1 string. +} + \section{Briefs}{ @@ -282,7 +302,7 @@ R statement: \if{html}{\out{
}}\preformatted{agent \%>\% rows_distinct( - columns = vars(a, b), + columns = c(a, b), preconditions = ~ . \%>\% dplyr::filter(a < 10), segments = b ~ c("group_1", "group_2"), actions = action_levels(warn_at = 0.1, stop_at = 0.2), @@ -295,7 +315,7 @@ YAML representation: \if{html}{\out{
}}\preformatted{steps: - rows_distinct: - columns: vars(a, b) + columns: c(a, b) preconditions: ~. \%>\% dplyr::filter(a < 10) segments: b ~ c("group_1", "group_2") actions: @@ -344,7 +364,7 @@ duplicate rows (i.e., all rows are distinct). \if{html}{\out{
}}\preformatted{agent <- create_agent(tbl = tbl) \%>\% - rows_distinct(columns = vars(a, b)) \%>\% + rows_distinct(columns = c(a, b)) \%>\% interrogate() }\if{html}{\out{
}} @@ -366,7 +386,7 @@ through but should \code{stop()} if there is a single test unit failing. The behavior of side effects can be customized with the \code{actions} option. \if{html}{\out{
}}\preformatted{tbl \%>\% - rows_distinct(columns = vars(a, b)) \%>\% + rows_distinct(columns = c(a, b)) \%>\% dplyr::pull(a) #> [1] 5 7 6 5 8 7 }\if{html}{\out{
}} @@ -377,7 +397,7 @@ behavior of side effects can be customized with the \code{actions} option. With the \verb{expect_*()} form, we would typically perform one validation at a time. This is primarily used in \strong{testthat} tests. -\if{html}{\out{
}}\preformatted{expect_rows_distinct(tbl, columns = vars(a, b)) +\if{html}{\out{
}}\preformatted{expect_rows_distinct(tbl, columns = c(a, b)) }\if{html}{\out{
}} } @@ -386,7 +406,7 @@ time. This is primarily used in \strong{testthat} tests. With the \verb{test_*()} form, we should get a single logical value returned to us. -\if{html}{\out{
}}\preformatted{test_rows_distinct(tbl, columns = vars(a, b)) +\if{html}{\out{
}}\preformatted{test_rows_distinct(tbl, columns = c(a, b)) #> [1] TRUE }\if{html}{\out{
}} } @@ -413,12 +433,12 @@ Other validation functions: \code{\link{col_vals_decreasing}()}, \code{\link{col_vals_equal}()}, \code{\link{col_vals_expr}()}, -\code{\link{col_vals_gte}()}, \code{\link{col_vals_gt}()}, +\code{\link{col_vals_gte}()}, \code{\link{col_vals_in_set}()}, \code{\link{col_vals_increasing}()}, -\code{\link{col_vals_lte}()}, \code{\link{col_vals_lt}()}, +\code{\link{col_vals_lte}()}, \code{\link{col_vals_make_set}()}, \code{\link{col_vals_make_subset}()}, \code{\link{col_vals_not_between}()}, diff --git a/man/serially.Rd b/man/serially.Rd index 447b0f925..db3f4c161 100644 --- a/man/serially.Rd +++ b/man/serially.Rd @@ -55,7 +55,7 @@ within the series. A finishing validation function call (e.g., \code{\link[=col_vals_increasing]{col_vals_increasing()}}, etc.) can optionally be inserted at the end of the series, serving as a validation step that only undergoes interrogation if the prior tests adequately pass. An example of this is -\verb{~ test_column_exists(., vars(a)), ~ col_vals_not_null(., vars(a))}).} +\verb{~ test_column_exists(., a), ~ col_vals_not_null(., a)}).} \item{.list}{\emph{Alternative to \code{...}} @@ -97,12 +97,13 @@ produce (influenced by the number of \code{columns} provided), (2) be an ID string not used in any previous validation step, and (3) be a vector with unique values.} -\item{label}{\emph{An optional label for the validation step} +\item{label}{\emph{Optional label for the validation step} -\verb{scalar} // \emph{default:} \code{NULL} (\code{optional}) +\verb{vector} // \emph{default:} \code{NULL} (\code{optional}) -An optional label for the validation step. This label appears in the -\emph{agent} report and, for the best appearance, it should be kept quite short.} +Optional label for the validation step. This label appears in the \emph{agent} +report and, for the best appearance, it should be kept quite short. See +the \emph{Labels} section for more information.} \item{brief}{\emph{Brief description for the validation step} @@ -129,7 +130,7 @@ be used with \code{.} (serving as the input data table) to evaluate to a single logical value. With this approach, the \strong{pointblank} function \code{\link[=has_columns]{has_columns()}} can be used to determine whether to make a validation step active on the basis of one or more columns existing in the table -(e.g., \code{~ . \%>\% has_columns(vars(d, e))}).} +(e.g., \code{~ . \%>\% has_columns(c(d, e))}).} \item{object}{\emph{A data table for expectations or tests} @@ -191,9 +192,9 @@ or any \code{segments}) Here's an example of how to arrange expressions: -\if{html}{\out{
}}\preformatted{~ test_col_exists(., columns = vars(count)), -~ test_col_is_numeric(., columns = vars(count)), -~ col_vals_gt(., columns = vars(count), value = 2) +\if{html}{\out{
}}\preformatted{~ test_col_exists(., columns = count), +~ test_col_is_numeric(., columns = count), +~ col_vals_gt(., columns = count, value = 2) }\if{html}{\out{
}} This series concentrates on the column called \code{count} and first checks @@ -234,12 +235,17 @@ formally tested (so be mindful of this when using unsupported backends with \section{Column Names}{ -If providing multiple column names in any of the supplied validation steps, -the result will be an expansion of sub-validation steps to that number of -column names. Aside from column names in quotes and in \code{vars()}, -\strong{tidyselect} helper functions are available for specifying columns. They -are: \code{starts_with()}, \code{ends_with()}, \code{contains()}, \code{matches()}, and -\code{everything()}. +\code{columns} may be a single column (as symbol \code{a} or string \code{"a"}) or a vector +of columns (\code{c(a, b, c)} or \code{c("a", "b", "c")}). \code{{tidyselect}} helpers +are also supported, such as \code{contains("date")} and \code{where(is.double)}. If +passing an \emph{external vector} of columns, it should be wrapped in \code{all_of()}. + +When multiple columns are selected by \code{columns}, the result will be an +expansion of validation steps to that number of columns (e.g., +\code{c(col_a, col_b)} will result in the entry of two validation steps). + +Previously, columns could be specified in \code{vars()}. This continues to work, +but \code{c()} offers the same capability and supersedes \code{vars()} in \code{columns}. } \section{Preconditions}{ @@ -280,6 +286,20 @@ quarter of the total test units fails, the other \code{stop()}s at the same threshold level). } +\section{Labels}{ + + +\code{label} may be a single string or a character vector that matches the number +of expanded steps. \code{label} also supports \code{{glue}} syntax and exposes the +following dynamic variables contextualized to the current step: +\itemize{ +\item \code{"{.step}"}: The validation step name +} + +The glue context also supports ordinary expressions for further flexibility +(e.g., \code{"{toupper(.step)}"}) as long as they return a length-1 string. +} + \section{Briefs}{ @@ -306,9 +326,9 @@ R statement: \if{html}{\out{
}}\preformatted{agent \%>\% serially( - ~ col_vals_lt(., columns = vars(a), value = 8), - ~ col_vals_gt(., columns = vars(c), value = vars(a)), - ~ col_vals_not_null(., columns = vars(b)), + ~ test_col_vals_lt(., columns = a, value = 8), + ~ test_col_vals_gt(., columns = c, value = vars(a)), + ~ col_vals_not_null(., columns = b), preconditions = ~ . \%>\% dplyr::filter(a < 10), actions = action_levels(warn_at = 0.1, stop_at = 0.2), label = "The `serially()` step.", @@ -321,9 +341,9 @@ YAML representation: \if{html}{\out{
}}\preformatted{steps: - serially: fns: - - ~col_vals_lt(., columns = vars(a), value = 8) - - ~col_vals_gt(., columns = vars(c), value = vars(a)) - - ~col_vals_not_null(., vars(b)) + - ~test_col_vals_lt(., columns = a, value = 8) + - ~test_col_vals_gt(., columns = c, value = vars(a)) + - ~col_vals_not_null(., columns = b) preconditions: ~. \%>\% dplyr::filter(a < 10) actions: warn_fraction: 0.1 @@ -375,9 +395,9 @@ validation). \if{html}{\out{
}}\preformatted{agent_1 <- create_agent(tbl = tbl) \%>\% serially( - ~ test_col_is_numeric(., columns = vars(a, b)), - ~ test_col_vals_not_null(., columns = vars(a, b)), - ~ col_vals_gt(., columns = vars(b), value = vars(a)) + ~ test_col_is_numeric(., columns = c(a, b)), + ~ test_col_vals_not_null(., columns = c(a, b)), + ~ col_vals_gt(., columns = b, value = vars(a)) ) \%>\% interrogate() }\if{html}{\out{
}} @@ -401,8 +421,8 @@ serial tests are performed. \if{html}{\out{
}}\preformatted{agent_2 <- create_agent(tbl = tbl) \%>\% serially( - ~ test_col_is_numeric(., columns = vars(a, b)), - ~ test_col_vals_not_null(., columns = vars(a, b)) + ~ test_col_is_numeric(., columns = c(a, b)), + ~ test_col_vals_not_null(., columns = c(a, b)) ) \%>\% interrogate() }\if{html}{\out{
}} @@ -424,9 +444,9 @@ behavior of side effects can be customized with the \code{actions} option. \if{html}{\out{
}}\preformatted{tbl \%>\% serially( - ~ test_col_is_numeric(., columns = vars(a, b)), - ~ test_col_vals_not_null(., columns = vars(a, b)), - ~ col_vals_gt(., columns = vars(b), value = vars(a)) + ~ test_col_is_numeric(., columns = c(a, b)), + ~ test_col_vals_not_null(., columns = c(a, b)), + ~ col_vals_gt(., columns = b, value = vars(a)) ) #> # A tibble: 3 x 3 #> a b c @@ -444,9 +464,9 @@ time. This is primarily used in \strong{testthat} tests. \if{html}{\out{
}}\preformatted{expect_serially( tbl, - ~ test_col_is_numeric(., columns = vars(a, b)), - ~ test_col_vals_not_null(., columns = vars(a, b)), - ~ col_vals_gt(., columns = vars(b), value = vars(a)) + ~ test_col_is_numeric(., columns = c(a, b)), + ~ test_col_vals_not_null(., columns = c(a, b)), + ~ col_vals_gt(., columns = b, value = vars(a)) ) }\if{html}{\out{
}} } @@ -458,9 +478,9 @@ us. \if{html}{\out{
}}\preformatted{tbl \%>\% test_serially( - ~ test_col_is_numeric(., columns = vars(a, b)), - ~ test_col_vals_not_null(., columns = vars(a, b)), - ~ col_vals_gt(., columns = vars(b), value = vars(a)) + ~ test_col_is_numeric(., columns = c(a, b)), + ~ test_col_vals_not_null(., columns = c(a, b)), + ~ col_vals_gt(., columns = b, value = vars(a)) ) #> [1] TRUE }\if{html}{\out{
}} @@ -488,12 +508,12 @@ Other validation functions: \code{\link{col_vals_decreasing}()}, \code{\link{col_vals_equal}()}, \code{\link{col_vals_expr}()}, -\code{\link{col_vals_gte}()}, \code{\link{col_vals_gt}()}, +\code{\link{col_vals_gte}()}, \code{\link{col_vals_in_set}()}, \code{\link{col_vals_increasing}()}, -\code{\link{col_vals_lte}()}, \code{\link{col_vals_lt}()}, +\code{\link{col_vals_lte}()}, \code{\link{col_vals_make_set}()}, \code{\link{col_vals_make_subset}()}, \code{\link{col_vals_not_between}()}, diff --git a/man/set_tbl.Rd b/man/set_tbl.Rd index e417ae6fe..33b575e96 100644 --- a/man/set_tbl.Rd +++ b/man/set_tbl.Rd @@ -16,7 +16,7 @@ An \emph{agent} object of class \code{ptblank_agent}, or, an \emph{informant} of \item{tbl}{\emph{Table or expression for reading in one} -\verb{obj:|
} // \strong{required} +\verb{obj:|} // \strong{required} The input table for the \emph{agent} or the \emph{informant}. This can be a data frame, a tibble, a \code{tbl_dbi} object, or a \code{tbl_spark} object. @@ -24,8 +24,8 @@ Alternatively, an expression can be supplied to serve as instructions on how to retrieve the target table at interrogation- or incorporation-time. There are two ways to specify an association to a target table: (1) as a table-prep formula, which is a right-hand side (RHS) formula expression -(e.g., \verb{~ \{
\}}), or (2) as a function (e.g., -\verb{function() \{
\}}).} +(e.g., \verb{~ \{ \}}), or (2) as a function (e.g., +\verb{function() \{ \}}).} \item{tbl_name}{\emph{A table name} @@ -71,9 +71,9 @@ Apply the actions, add some validation steps and then interrogate the data. label = "An example.", actions = al ) \%>\% - col_exists(columns = vars(date, date_time)) \%>\% + col_exists(columns = c(date, date_time)) \%>\% col_vals_regex( - columns = vars(b), + columns = b, regex = "[0-9]-[a-z]\{3\}-[0-9]\{3\}" ) \%>\% rows_distinct() \%>\% diff --git a/man/small_table.Rd b/man/small_table.Rd index 9167f80b4..412bb6727 100644 --- a/man/small_table.Rd +++ b/man/small_table.Rd @@ -41,8 +41,8 @@ dplyr::glimpse(small_table) } \seealso{ Other Datasets: -\code{\link{game_revenue_info}}, \code{\link{game_revenue}}, +\code{\link{game_revenue_info}}, \code{\link{small_table_sqlite}()}, \code{\link{specifications}} } diff --git a/man/small_table_sqlite.Rd b/man/small_table_sqlite.Rd index 6b1f3c31a..0f94d55f3 100644 --- a/man/small_table_sqlite.Rd +++ b/man/small_table_sqlite.Rd @@ -27,8 +27,8 @@ and \strong{RSQLite} packages. These packages can be installed by using } \seealso{ Other Datasets: -\code{\link{game_revenue_info}}, \code{\link{game_revenue}}, +\code{\link{game_revenue_info}}, \code{\link{small_table}}, \code{\link{specifications}} } diff --git a/man/snip_highest.Rd b/man/snip_highest.Rd index cd175b8ed..5715b604f 100644 --- a/man/snip_highest.Rd +++ b/man/snip_highest.Rd @@ -9,7 +9,7 @@ snip_highest(column) \arguments{ \item{column}{\emph{The target column} -`scalar\if{html}{\out{}}`` // \strong{required} +\verb{scalar} // \strong{required} The name of the column that contains the target values.} } @@ -37,7 +37,7 @@ the snippet into the info text. Note here that the order of the label = "An example." ) \%>\% info_columns( - columns = "a", + columns = a, `Highest Value` = "Highest value is \{highest_a\}." ) \%>\% info_snippet( @@ -66,8 +66,8 @@ We can print the \code{informant} object to see the information report. \seealso{ Other Information Functions: -\code{\link{info_columns_from_tbl}()}, \code{\link{info_columns}()}, +\code{\link{info_columns_from_tbl}()}, \code{\link{info_section}()}, \code{\link{info_snippet}()}, \code{\link{info_tabular}()}, diff --git a/man/snip_list.Rd b/man/snip_list.Rd index ca10e5460..d740c2c37 100644 --- a/man/snip_list.Rd +++ b/man/snip_list.Rd @@ -14,13 +14,14 @@ snip_list( oxford = TRUE, as_code = TRUE, quot_str = NULL, + na_rm = FALSE, lang = NULL ) } \arguments{ \item{column}{\emph{The target column} -`scalar\if{html}{\out{}}`` // \strong{required} +\verb{scalar} // \strong{required} The name of the column that contains the target values.} @@ -90,6 +91,12 @@ derived from \code{character} or \code{factor} values; numbers, dates, and logic values won't have quotation marks. We can explicitly use quotations (or not) with either \code{TRUE} or \code{FALSE} here.} +\item{na_rm}{\emph{Remove NA values from list} + +\verb{scalar} // \emph{default:} \code{FALSE} + +An option for whether NA values should be counted as an item in the list.} + \item{lang}{\emph{Reporting language} \verb{scalar} // \emph{default:} \code{NULL} (\code{optional}) @@ -128,7 +135,7 @@ the \code{\link[=info_columns]{info_columns()}} and \code{\link[=info_snippet]{i label = "An example." ) \%>\% info_columns( - columns = "f", + columns = f, `Items` = "This column contains \{values_f\}." ) \%>\% info_snippet( @@ -157,8 +164,8 @@ We can print the \code{informant} object to see the information report. \seealso{ Other Information Functions: -\code{\link{info_columns_from_tbl}()}, \code{\link{info_columns}()}, +\code{\link{info_columns_from_tbl}()}, \code{\link{info_section}()}, \code{\link{info_snippet}()}, \code{\link{info_tabular}()}, diff --git a/man/snip_lowest.Rd b/man/snip_lowest.Rd index 92822d12c..3ecf350fe 100644 --- a/man/snip_lowest.Rd +++ b/man/snip_lowest.Rd @@ -9,7 +9,7 @@ snip_lowest(column) \arguments{ \item{column}{\emph{The target column} -`scalar\if{html}{\out{}}`` // \strong{required} +\verb{scalar} // \strong{required} The name of the column that contains the target values.} } @@ -37,7 +37,7 @@ the snippet into the info text. Note here that the order of the label = "An example." ) \%>\% info_columns( - columns = "a", + columns = a, `Lowest Value` = "Lowest value is \{lowest_a\}." ) \%>\% info_snippet( @@ -66,8 +66,8 @@ We can print the \code{informant} object to see the information report. \seealso{ Other Information Functions: -\code{\link{info_columns_from_tbl}()}, \code{\link{info_columns}()}, +\code{\link{info_columns_from_tbl}()}, \code{\link{info_section}()}, \code{\link{info_snippet}()}, \code{\link{info_tabular}()}, diff --git a/man/snip_stats.Rd b/man/snip_stats.Rd index 5fc90ddf3..e45f3a55f 100644 --- a/man/snip_stats.Rd +++ b/man/snip_stats.Rd @@ -9,7 +9,7 @@ snip_stats(column, type = c("5num", "7num", "bowley")) \arguments{ \item{column}{\emph{The target column} -`scalar\if{html}{\out{}}`` // \strong{required} +\verb{scalar} // \strong{required} The name of the column that contains the target values.} @@ -55,7 +55,7 @@ the snippet into the info text. Note here that the order of the label = "An example." ) \%>\% info_columns( - columns = "d", + columns = d, `Stats` = "Stats (fivenum): \{stats_d\}." ) \%>\% info_snippet( @@ -84,8 +84,8 @@ We can print the \code{informant} object to see the information report. \seealso{ Other Information Functions: -\code{\link{info_columns_from_tbl}()}, \code{\link{info_columns}()}, +\code{\link{info_columns_from_tbl}()}, \code{\link{info_section}()}, \code{\link{info_snippet}()}, \code{\link{info_tabular}()}, diff --git a/man/specially.Rd b/man/specially.Rd index c84da92f9..290bd6bcd 100644 --- a/man/specially.Rd +++ b/man/specially.Rd @@ -72,12 +72,13 @@ produce (influenced by the number of \code{columns} provided), (2) be an ID string not used in any previous validation step, and (3) be a vector with unique values.} -\item{label}{\emph{An optional label for the validation step} +\item{label}{\emph{Optional label for the validation step} -\verb{scalar} // \emph{default:} \code{NULL} (\code{optional}) +\verb{vector} // \emph{default:} \code{NULL} (\code{optional}) -An optional label for the validation step. This label appears in the -\emph{agent} report and, for the best appearance, it should be kept quite short.} +Optional label for the validation step. This label appears in the \emph{agent} +report and, for the best appearance, it should be kept quite short. See +the \emph{Labels} section for more information.} \item{brief}{\emph{Brief description for the validation step} @@ -104,7 +105,7 @@ be used with \code{.} (serving as the input data table) to evaluate to a single logical value. With this approach, the \strong{pointblank} function \code{\link[=has_columns]{has_columns()}} can be used to determine whether to make a validation step active on the basis of one or more columns existing in the table -(e.g., \code{~ . \%>\% has_columns(vars(d, e))}).} +(e.g., \code{~ . \%>\% has_columns(c(d, e))}).} \item{object}{\emph{A data table for expectations or tests} @@ -209,6 +210,20 @@ quarter of the total test units fails, the other \code{stop()}s at the same threshold level). } +\section{Labels}{ + + +\code{label} may be a single string or a character vector that matches the number +of expanded steps. \code{label} also supports \code{{glue}} syntax and exposes the +following dynamic variables contextualized to the current step: +\itemize{ +\item \code{"{.step}"}: The validation step name +} + +The glue context also supports ordinary expressions for further flexibility +(e.g., \code{"{toupper(.step)}"}) as long as they return a length-1 string. +} + \section{Briefs}{ @@ -437,12 +452,12 @@ Other validation functions: \code{\link{col_vals_decreasing}()}, \code{\link{col_vals_equal}()}, \code{\link{col_vals_expr}()}, -\code{\link{col_vals_gte}()}, \code{\link{col_vals_gt}()}, +\code{\link{col_vals_gte}()}, \code{\link{col_vals_in_set}()}, \code{\link{col_vals_increasing}()}, -\code{\link{col_vals_lte}()}, \code{\link{col_vals_lt}()}, +\code{\link{col_vals_lte}()}, \code{\link{col_vals_make_set}()}, \code{\link{col_vals_make_subset}()}, \code{\link{col_vals_not_between}()}, diff --git a/man/specifications.Rd b/man/specifications.Rd index 0d66e76b0..bf105407c 100644 --- a/man/specifications.Rd +++ b/man/specifications.Rd @@ -57,10 +57,10 @@ dplyr::glimpse(specifications) } \seealso{ Other Datasets: -\code{\link{game_revenue_info}}, \code{\link{game_revenue}}, -\code{\link{small_table_sqlite}()}, -\code{\link{small_table}} +\code{\link{game_revenue_info}}, +\code{\link{small_table}}, +\code{\link{small_table_sqlite}()} } \concept{Datasets} \keyword{datasets} diff --git a/man/stop_if_not.Rd b/man/stop_if_not.Rd index 173ccab9d..fa1f4d70c 100644 --- a/man/stop_if_not.Rd +++ b/man/stop_if_not.Rd @@ -46,8 +46,8 @@ stop_if_not(1 < 20:25 - 18) } \seealso{ Other Utility and Helper Functions: -\code{\link{affix_datetime}()}, \code{\link{affix_date}()}, +\code{\link{affix_datetime}()}, \code{\link{col_schema}()}, \code{\link{from_github}()}, \code{\link{has_columns}()} diff --git a/man/tbl_match.Rd b/man/tbl_match.Rd index b69e7999b..b5fa6817e 100644 --- a/man/tbl_match.Rd +++ b/man/tbl_match.Rd @@ -38,8 +38,8 @@ commonly created with \code{\link[=create_agent]{create_agent()}}.} A table to compare against the target table. This can either be a table object, a table-prep formula. This can be a table object such as a data frame, a tibble, a \code{tbl_dbi} object, or a \code{tbl_spark} object. -Alternatively, a table-prep formula (\verb{~
}) or a -function (\verb{function()
}) can be used to lazily read in +Alternatively, a table-prep formula (\verb{~ }) or a +function (\verb{function() }) can be used to lazily read in the table at interrogation time.} \item{preconditions}{\emph{Input table modification prior to validation} @@ -86,12 +86,13 @@ produce (influenced by the number of \code{columns} provided), (2) be an ID string not used in any previous validation step, and (3) be a vector with unique values.} -\item{label}{\emph{An optional label for the validation step} +\item{label}{\emph{Optional label for the validation step} -\verb{scalar} // \emph{default:} \code{NULL} (\code{optional}) +\verb{vector} // \emph{default:} \code{NULL} (\code{optional}) -An optional label for the validation step. This label appears in the -\emph{agent} report and, for the best appearance, it should be kept quite short.} +Optional label for the validation step. This label appears in the \emph{agent} +report and, for the best appearance, it should be kept quite short. See +the \emph{Labels} section for more information.} \item{brief}{\emph{Brief description for the validation step} @@ -118,7 +119,7 @@ be used with \code{.} (serving as the input data table) to evaluate to a single logical value. With this approach, the \strong{pointblank} function \code{\link[=has_columns]{has_columns()}} can be used to determine whether to make a validation step active on the basis of one or more columns existing in the table -(e.g., \code{~ . \%>\% has_columns(vars(d, e))}).} +(e.g., \code{~ . \%>\% has_columns(c(d, e))}).} \item{object}{\emph{A data table for expectations or tests} @@ -245,6 +246,22 @@ depending on the situation (the first produces a warning, the other \code{stop()}s). } +\section{Labels}{ + + +\code{label} may be a single string or a character vector that matches the number +of expanded steps. \code{label} also supports \code{{glue}} syntax and exposes the +following dynamic variables contextualized to the current step: +\itemize{ +\item \code{"{.step}"}: The validation step name +\item \code{"{.seg_col}"}: The current segment's column name +\item \code{"{.seg_val}"}: The current segment's value/group +} + +The glue context also supports ordinary expressions for further flexibility +(e.g., \code{"{toupper(.step)}"}) as long as they return a length-1 string. +} + \section{Briefs}{ @@ -434,12 +451,12 @@ Other validation functions: \code{\link{col_vals_decreasing}()}, \code{\link{col_vals_equal}()}, \code{\link{col_vals_expr}()}, -\code{\link{col_vals_gte}()}, \code{\link{col_vals_gt}()}, +\code{\link{col_vals_gte}()}, \code{\link{col_vals_in_set}()}, \code{\link{col_vals_increasing}()}, -\code{\link{col_vals_lte}()}, \code{\link{col_vals_lt}()}, +\code{\link{col_vals_lte}()}, \code{\link{col_vals_make_set}()}, \code{\link{col_vals_make_subset}()}, \code{\link{col_vals_not_between}()}, diff --git a/man/tbl_source.Rd b/man/tbl_source.Rd index d41c86712..d7ae0b390 100644 --- a/man/tbl_source.Rd +++ b/man/tbl_source.Rd @@ -55,7 +55,7 @@ some validation steps, and interrogate the table shortly thereafter. label = "`tbl_source()` example", actions = action_levels(warn_at = 0.10) ) \%>\% - col_exists(columns = vars(date, date_time)) \%>\% + col_exists(columns = c(date, date_time)) \%>\% interrogate() }\if{html}{\out{}} diff --git a/man/tbl_store.Rd b/man/tbl_store.Rd index 550b6eb17..1323e7f05 100644 --- a/man/tbl_store.Rd +++ b/man/tbl_store.Rd @@ -91,7 +91,7 @@ to YAML: label = "An example that uses a table store.", actions = action_levels(warn_at = 0.10) ) \%>\% - col_exists(vars(date, date_time)) \%>\% + col_exists(c(date, date_time)) \%>\% write_yaml() }\if{html}{\out{}} @@ -105,7 +105,7 @@ actions: locale: en steps: - col_exists: - columns: vars(date, date_time) + columns: c(date, date_time) }\if{html}{\out{}} Now, whenever the \code{sml_table_high} table needs to be validated, it can be diff --git a/man/tt_string_info.Rd b/man/tt_string_info.Rd index a0a0e38fb..1fa4231f1 100644 --- a/man/tt_string_info.Rd +++ b/man/tt_string_info.Rd @@ -52,11 +52,11 @@ numbers of characters (\code{15} and \code{24}, respectively) throughout the tab \if{html}{\out{
}}\preformatted{tt_string_info(tbl = game_revenue) \%>\% col_vals_equal( - columns = vars(player_id), + columns = player_id, value = 15 ) \%>\% col_vals_equal( - columns = vars(session_id), + columns = session_id, value = 24 ) #> # A tibble: 3 x 7 @@ -75,7 +75,7 @@ of the \code{small_table} dataset is no greater than \code{4}. \if{html}{\out{
}}\preformatted{tt_string_info(tbl = small_table) \%>\% test_col_vals_lte( - columns = vars(f), + columns = f, value = 4 ) #> [1] TRUE diff --git a/man/tt_summary_stats.Rd b/man/tt_summary_stats.Rd index 724ee26bb..ccc1e3bb5 100644 --- a/man/tt_summary_stats.Rd +++ b/man/tt_summary_stats.Rd @@ -65,7 +65,7 @@ ensure that the maximum revenue for individual purchases in the \if{html}{\out{
}}\preformatted{tt_summary_stats(tbl = game_revenue) \%>\% col_vals_lt( - columns = vars(item_revenue), + columns = item_revenue, value = 150, segments = .param. ~ "max" ) @@ -92,7 +92,7 @@ that the median revenue is somewhere between $8 and $12. dplyr::filter(item_type == "iap") \%>\% tt_summary_stats() \%>\% col_vals_between( - columns = vars(item_revenue), + columns = item_revenue, left = 8, right = 12, segments = .param. ~ "med" ) @@ -132,7 +132,7 @@ step that isolates the row of the median statistic. rows_complete() \%>\% rows_distinct() \%>\% col_vals_between( - columns = vars(item_revenue), + columns = item_revenue, left = 8, right = 12, preconditions = ~ . \%>\% dplyr::filter(item_type == "iap") \%>\% diff --git a/man/tt_tbl_colnames.Rd b/man/tt_tbl_colnames.Rd index 29d5ca449..154f40ade 100644 --- a/man/tt_tbl_colnames.Rd +++ b/man/tt_tbl_colnames.Rd @@ -55,7 +55,7 @@ table. Here, we check that \code{game_revenue} table, included in the \if{html}{\out{
}}\preformatted{tt_tbl_colnames(tbl = game_revenue) \%>\% test_col_vals_make_subset( - columns = vars(value), + columns = value, set = c("acquisition", "country") ) #> [1] TRUE @@ -70,7 +70,7 @@ combination of \code{tt_tbl_colnames()}, then \code{\link[=tt_string_info]{tt_st tt_tbl_colnames() \%>\% tt_string_info() \%>\% test_col_vals_lt( - columns = vars(value), + columns = value, value = 15 ) #> [1] FALSE diff --git a/man/tt_tbl_dims.Rd b/man/tt_tbl_dims.Rd index b605c91bd..5abafbb14 100644 --- a/man/tt_tbl_dims.Rd +++ b/man/tt_tbl_dims.Rd @@ -44,7 +44,7 @@ dimensions. Here, we check that \code{game_revenue} has at least \code{1500} row \if{html}{\out{
}}\preformatted{tt_tbl_dims(tbl = game_revenue) \%>\% dplyr::filter(.param. == "rows") \%>\% test_col_vals_gt( - columns = vars(value), + columns = value, value = 1500 ) #> [1] TRUE @@ -56,7 +56,7 @@ We can check \code{small_table} to ensure that number of columns is less than \if{html}{\out{
}}\preformatted{tt_tbl_dims(tbl = small_table) \%>\% dplyr::filter(.param. == "columns") \%>\% test_col_vals_lt( - columns = vars(value), + columns = value, value = 10 ) #> [1] TRUE diff --git a/man/write_testthat_file.Rd b/man/write_testthat_file.Rd index 0401b2e0a..59b901a4f 100644 --- a/man/write_testthat_file.Rd +++ b/man/write_testthat_file.Rd @@ -124,7 +124,7 @@ test_that("column `date_time` exists", \{ expect_col_exists( tbl, - columns = vars(date_time), + columns = date_time, threshold = 1 ) \}) @@ -133,7 +133,7 @@ test_that("values in `c` should be <= `5`", \{ expect_col_vals_lte( tbl, - columns = vars(c), + columns = c, value = 5, threshold = 0.25 ) @@ -150,8 +150,8 @@ agent <- tbl = ~ small_table, actions = action_levels(stop_at = 0.25) ) \%>\% - col_exists(vars(date_time)) \%>\% - col_vals_lte(vars(c), value = 5) + col_exists(date_time) \%>\% + col_vals_lte(c, value = 5) write_testthat_file( agent = agent, @@ -209,13 +209,13 @@ bit more useful after interrogation. label = "An example.", actions = al ) \%>\% - col_exists(vars(date, date_time)) \%>\% + col_exists(c(date, date_time)) \%>\% col_vals_regex( - vars(b), + b, regex = "[0-9]-[a-z]\{3\}-[0-9]\{3\}" ) \%>\% - col_vals_gt(vars(d), value = 100) \%>\% - col_vals_lte(vars(c), value = 5) \%>\% + col_vals_gt(d, value = 100) \%>\% + col_vals_lte(c, value = 5) \%>\% interrogate() }\if{html}{\out{
}} @@ -246,7 +246,7 @@ test_that("column `date` exists", \{ expect_col_exists( tbl, - columns = vars(date), + columns = date, threshold = 1 ) \}) @@ -255,7 +255,7 @@ test_that("column `date_time` exists", \{ expect_col_exists( tbl, - columns = vars(date_time), + columns = date_time, threshold = 1 ) \}) @@ -265,7 +265,7 @@ test_that("values in `b` should match the regular expression: expect_col_vals_regex( tbl, - columns = vars(b), + columns = b, regex = "[0-9]-[a-z]\{3\}-[0-9]\{3\}", threshold = 0.25 ) @@ -275,7 +275,7 @@ test_that("values in `d` should be > `100`", \{ expect_col_vals_gt( tbl, - columns = vars(d), + columns = d, value = 100, threshold = 0.25 ) @@ -285,7 +285,7 @@ test_that("values in `c` should be <= `5`", \{ expect_col_vals_lte( tbl, - columns = vars(c), + columns = c, value = 5, threshold = 0.25 ) diff --git a/man/x_write_disk.Rd b/man/x_write_disk.Rd index 0d5115820..0cd26a3a2 100644 --- a/man/x_write_disk.Rd +++ b/man/x_write_disk.Rd @@ -122,14 +122,14 @@ using as many validation functions as we want. After that, use \if{html}{\out{
}}\preformatted{agent <- agent \%>\% - col_exists(columns = vars(date, date_time)) \%>\% + col_exists(columns = c(date, date_time)) \%>\% col_vals_regex( - columns = vars(b), + columns = b, regex = "[0-9]-[a-z]\{3\}-[0-9]\{3\}" ) \%>\% rows_distinct() \%>\% - col_vals_gt(columns = vars(d), value = 100) \%>\% - col_vals_lte(columns = vars(c), value = 5) \%>\% + col_vals_gt(columns = d, value = 100) \%>\% + col_vals_lte(columns = c, value = 5) \%>\% interrogate() }\if{html}{\out{
}} @@ -184,7 +184,7 @@ integrated into the text. fn = snip_lowest(column = "a") ) \%>\% info_columns( - columns = vars(a), + columns = a, info = "From \{low_a\} to \{high_a\}." ) \%>\% info_columns( @@ -192,7 +192,7 @@ integrated into the text. info = "Time-based values." ) \%>\% info_columns( - columns = "date", + columns = date, info = "The date part of `date_time`." ) \%>\% incorporate() @@ -226,13 +226,13 @@ validation steps, and \code{\link[=interrogate]{interrogate()}}. actions = al ) \%>\% col_vals_gt( - columns = vars(b), - value = vars(g), + columns = b, + value = g, na_pass = TRUE, label = "b > g" ) \%>\% col_is_character( - columns = vars(b, f), + columns = c(b, f), label = "Verifying character-type columns" ) \%>\% interrogate() diff --git a/man/yaml_agent_show_exprs.Rd b/man/yaml_agent_show_exprs.Rd index 3a205b0d7..2aea4582e 100644 --- a/man/yaml_agent_show_exprs.Rd +++ b/man/yaml_agent_show_exprs.Rd @@ -46,14 +46,14 @@ retrieval of the target table. notify_at = 0.35 ) ) \%>\% - col_exists(columns = vars(date, date_time)) \%>\% + col_exists(columns = c(date, date_time)) \%>\% col_vals_regex( - columns = vars(b), + columns = b, regex = "[0-9]-[a-z]\{3\}-[0-9]\{3\}" ) \%>\% rows_distinct() \%>\% - col_vals_gt(columns = vars(d), value = 100) \%>\% - col_vals_lte(columns = vars(c), value = 5) + col_vals_gt(columns = d, value = 100) \%>\% + col_vals_lte(columns = c, value = 5) }\if{html}{\out{
}} The agent can be written to a \strong{pointblank} YAML file with \code{\link[=yaml_write]{yaml_write()}}. @@ -95,19 +95,19 @@ we can use \code{yaml_agent_show_exprs()}. label = "A simple example with the `small_table`." ) \%>\% col_exists( - columns = vars(date, date_time) + columns = c(date, date_time) ) \%>\% col_vals_regex( - columns = vars(b), + columns = b, regex = "[0-9]-[a-z]\{3\}-[0-9]\{3\}" ) \%>\% rows_distinct() \%>\% col_vals_gt( - columns = vars(d), + columns = d, value = 100 ) \%>\% col_vals_lte( - columns = vars(c), + columns = c, value = 5 ) }\if{html}{\out{
}} diff --git a/man/yaml_agent_string.Rd b/man/yaml_agent_string.Rd index c1b1a16f3..9819df6b8 100644 --- a/man/yaml_agent_string.Rd +++ b/man/yaml_agent_string.Rd @@ -17,10 +17,9 @@ provided in \code{agent}.} \item{path}{An optional path to the YAML file (combined with \code{filename}).} \item{expanded}{Should the written validation expressions for an \emph{agent} be -expanded such that \strong{tidyselect} and \code{\link[=vars]{vars()}} expressions for columns are -evaluated, yielding a validation function per column? By default, this is -\code{FALSE} so expressions as written will be retained in the YAML -representation.} +expanded such that \strong{tidyselect} expressions for columns are evaluated, +yielding a validation function per column? By default, this is \code{FALSE} +so expressions as written will be retained in the YAML representation.} } \value{ Nothing is returned. Instead, text is printed to the console. diff --git a/man/yaml_write.Rd b/man/yaml_write.Rd index 5270b82f9..61430df77 100644 --- a/man/yaml_write.Rd +++ b/man/yaml_write.Rd @@ -54,9 +54,9 @@ An optional path to which the YAML file should be saved (combined with \verb{scalar} // \emph{default:} \code{FALSE} Should the written validation expressions for an \emph{agent} be expanded such -that \strong{tidyselect} and \code{\link[=vars]{vars()}} expressions for columns are evaluated, -yielding a validation function per column? By default, this is \code{FALSE} so -expressions as written will be retained in the YAML representation.} +that \strong{tidyselect} expressions for columns are evaluated, yielding a +validation function per column? By default, this is \code{FALSE} so expressions +as written will be retained in the YAML representation.} \item{quiet}{\emph{Inform (or not) upon file writing} @@ -144,14 +144,14 @@ using as many validation functions as we want. \if{html}{\out{
}}\preformatted{agent <- agent \%>\% - col_exists(columns = vars(date, date_time)) \%>\% + col_exists(columns = c(date, date_time)) \%>\% col_vals_regex( - columns = vars(b), + columns = b, regex = "[0-9]-[a-z]\{3\}-[0-9]\{3\}" ) \%>\% rows_distinct() \%>\% - col_vals_gt(columns = vars(d), value = 100) \%>\% - col_vals_lte(columns = vars(c), value = 5) + col_vals_gt(columns = d, value = 100) \%>\% + col_vals_lte(columns = c, value = 5) }\if{html}{\out{
}} The agent can be written to a \strong{pointblank}-readable YAML file with the @@ -180,17 +180,17 @@ actions: notify_fraction: 0.35 steps: - col_exists: - columns: vars(date, date_time) + columns: c(date, date_time) - col_vals_regex: - columns: vars(b) + columns: c(b) regex: '[0-9]-[a-z]\{3\}-[0-9]\{3\}' - rows_distinct: columns: ~ - col_vals_gt: - columns: vars(d) + columns: c(d) value: 100.0 - col_vals_lte: - columns: vars(c) + columns: c(c) value: 5.0 }\if{html}{\out{
}} @@ -280,7 +280,7 @@ using as many \verb{info_*()} functions as we want. \if{html}{\out{
}}\preformatted{informant <- informant \%>\% info_columns( - columns = vars(a), + columns = a, info = "In the range of 1 to 10. (SIMPLE)" ) \%>\% info_columns( @@ -288,7 +288,7 @@ using as many \verb{info_*()} functions as we want. info = "Time-based values (e.g., `Sys.time()`)." ) \%>\% info_columns( - columns = "date", + columns = date, info = "The date part of `date_time`. (CALC)" ) }\if{html}{\out{
}} diff --git a/pkgdown/_pkgdown.yml b/pkgdown/_pkgdown.yml index b927d7179..7e60e5686 100644 --- a/pkgdown/_pkgdown.yml +++ b/pkgdown/_pkgdown.yml @@ -7,6 +7,7 @@ home: template: bootstrap: 5 + light-switch: true development: mode: release diff --git a/pkgdown/extra.css b/pkgdown/extra.css index d906c52bc..2f782aad2 100644 --- a/pkgdown/extra.css +++ b/pkgdown/extra.css @@ -1,5 +1,5 @@ body { - font-family: ui-rounded, 'Hiragino Maru Gothic ProN', Quicksand, Comfortaa, Manjari, 'Arial Rounded MT', 'Arial Rounded MT Bold', Roboto, -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Arial, sans-serif; + font-family: Inter, Roboto, 'Helvetica Neue', 'Arial Nova', 'Nimbus Sans', Arial, sans-serif; } code { diff --git a/scripts/lint_package.R b/scripts/lint_package.R index 0ec646b33..fa0e3956b 100644 --- a/scripts/lint_package.R +++ b/scripts/lint_package.R @@ -1,16 +1 @@ -library(lintr) - -lintr::lint_package( - linters = linters_with_defaults( - object_usage_linter = NULL, - trailing_whitespace_linter = NULL, - cyclocomp_linter = NULL - ), - exclusions = c( - list.files("tests", recursive = TRUE, full.names = TRUE), - list.files("man", recursive = TRUE, full.names = TRUE), - list.files("vignettes", recursive = TRUE, full.names = TRUE), - list.files("data-raw", recursive = TRUE, full.names = TRUE), - list.files("inst", recursive = TRUE, full.names = TRUE) - ) -) +lintr::lint_package() diff --git a/tests/manual_tests/test-quarto-render.R b/tests/manual_tests/test-quarto-render.R new file mode 100644 index 000000000..936c1cea4 --- /dev/null +++ b/tests/manual_tests/test-quarto-render.R @@ -0,0 +1,16 @@ +# Ensure that rendering reports in Quarto do not produce `data-qmd` attributes +# since the reports are not *data* tables + +quarto::quarto_render("tests/manual_tests/test-quarto-render.qmd") +stopifnot(file.exists("tests/manual_tests/test-quarto-render.html")) +utils::browseURL("tests/manual_tests/test-quarto-render.html") + +test_qmd <- xml2::read_html("tests/manual_tests/test-quarto-render.html") + +data_qmd_divs <- xml2::xml_find_all(test_qmd, "//div[@data-qmd]") +data_qmd_divs + +stopifnot(length(data_qmd_divs) == 0) + +unlink("tests/manual_tests/test-quarto-render.html") +unlink("tests/manual_tests/test-quarto-render_files/*", recursive = TRUE) \ No newline at end of file diff --git a/tests/manual_tests/test-quarto-render.qmd b/tests/manual_tests/test-quarto-render.qmd new file mode 100644 index 000000000..f6714d9dd --- /dev/null +++ b/tests/manual_tests/test-quarto-render.qmd @@ -0,0 +1,40 @@ +--- +title: "Rendering reports in a Quarto document" +format: html +--- + +```{r} +library(pointblank) +``` + +## agent report + +```{r} +agent <- small_table[, "a"] %>% + create_agent() %>% + col_exists(a) %>% + interrogate() +agent +get_agent_report(agent) +``` + + +## informant report + +```{r} +informant <- small_table[, "a"] %>% + create_informant() %>% + info_columns(a, info = "a column") +informant +get_informant_report(informant) +``` + +## multiagent report + +```{r} +multiagent <- create_multiagent(agent, agent) +multiagent +get_multiagent_report(multiagent, display_mode = "long") +get_multiagent_report(multiagent, display_mode = "wide") +``` + diff --git a/tests/testthat/_snaps/draft_validation.md b/tests/testthat/_snaps/draft_validation.md index b2767de83..31e6bf3b2 100644 --- a/tests/testthat/_snaps/draft_validation.md +++ b/tests/testthat/_snaps/draft_validation.md @@ -3,418 +3,411 @@ Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `latitude` is of type: numeric\n col_is_numeric(\n columns = vars(latitude)\n ) %>%\n # Expect that values in `latitude` should be between `-90` and `90`\n col_vals_between(\n columns = vars(latitude),\n left = -90,\n right = 90\n ) %>%\n # Expect that column `month` is of type: factor\n col_is_factor(\n columns = vars(month)\n ) %>%\n # Expect that column `tst` is of type: character\n col_is_character(\n columns = vars(tst)\n ) %>%\n # Expect that column `sza` is of type: numeric\n col_is_numeric(\n columns = vars(sza)\n ) %>%\n # Expect that values in `sza` should be between `1.9` and `89.7`\n col_vals_between(\n columns = vars(sza),\n left = 1.9,\n right = 89.7,\n na_pass = TRUE\n ) %>%\n # Expect entirely distinct rows across all columns\n rows_distinct() %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n latitude = \"numeric\",\n month = \"factor\",\n tst = \"character\",\n sza = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `latitude` is of type: numeric\n col_is_numeric(\n columns = c(\"latitude\")\n ) %>%\n # Expect that values in `latitude` should be between `-90` and `90`\n col_vals_between(\n columns = c(\"latitude\"),\n left = -90,\n right = 90\n ) %>%\n # Expect that column `month` is of type: factor\n col_is_factor(\n columns = c(\"month\")\n ) %>%\n # Expect that column `tst` is of type: character\n col_is_character(\n columns = c(\"tst\")\n ) %>%\n # Expect that column `sza` is of type: numeric\n col_is_numeric(\n columns = c(\"sza\")\n ) %>%\n # Expect that values in `sza` should be between `1.9` and `89.7`\n col_vals_between(\n columns = c(\"sza\"),\n left = 1.9,\n right = 89.7,\n na_pass = TRUE\n ) %>%\n # Expect entirely distinct rows across `latitude, month, tst, sza`\n rows_distinct(\n columns = c(\"latitude\", \"month\", \"tst\", \"sza\")\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n latitude = \"numeric\",\n month = \"factor\",\n tst = \"character\",\n sza = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `mfr` is of type: character\n col_is_character(\n columns = vars(mfr)\n ) %>%\n # Expect that column `model` is of type: character\n col_is_character(\n columns = vars(model)\n ) %>%\n # Expect that column `year` is of type: numeric\n col_is_numeric(\n columns = vars(year)\n ) %>%\n # Expect that values in `year` should be between `2014` and `2017`\n col_vals_between(\n columns = vars(year),\n left = 2014,\n right = 2017\n ) %>%\n # Expect that column `trim` is of type: character\n col_is_character(\n columns = vars(trim)\n ) %>%\n # Expect that column `bdy_style` is of type: character\n col_is_character(\n columns = vars(bdy_style)\n ) %>%\n # Expect that column `hp` is of type: numeric\n col_is_numeric(\n columns = vars(hp)\n ) %>%\n # Expect that values in `hp` should be between `259` and `949`\n col_vals_between(\n columns = vars(hp),\n left = 259,\n right = 949\n ) %>%\n # Expect that column `hp_rpm` is of type: numeric\n col_is_numeric(\n columns = vars(hp_rpm)\n ) %>%\n # Expect that values in `hp_rpm` should be between `5000` and `9000`\n col_vals_between(\n columns = vars(hp_rpm),\n left = 5000,\n right = 9000\n ) %>%\n # Expect that column `trq` is of type: numeric\n col_is_numeric(\n columns = vars(trq)\n ) %>%\n # Expect that values in `trq` should be between `243` and `664`\n col_vals_between(\n columns = vars(trq),\n left = 243,\n right = 664\n ) %>%\n # Expect that column `trq_rpm` is of type: numeric\n col_is_numeric(\n columns = vars(trq_rpm)\n ) %>%\n # Expect that values in `trq_rpm` should be between `1400` and `6750`\n col_vals_between(\n columns = vars(trq_rpm),\n left = 1400,\n right = 6750,\n na_pass = TRUE\n ) %>%\n # Expect that column `mpg_c` is of type: numeric\n col_is_numeric(\n columns = vars(mpg_c)\n ) %>%\n # Expect that values in `mpg_c` should be between `11` and `28`\n col_vals_between(\n columns = vars(mpg_c),\n left = 11,\n right = 28,\n na_pass = TRUE\n ) %>%\n # Expect that column `mpg_h` is of type: numeric\n col_is_numeric(\n columns = vars(mpg_h)\n ) %>%\n # Expect that values in `mpg_h` should be between `16` and `30`\n col_vals_between(\n columns = vars(mpg_h),\n left = 16,\n right = 30,\n na_pass = TRUE\n ) %>%\n # Expect that column `drivetrain` is of type: character\n col_is_character(\n columns = vars(drivetrain)\n ) %>%\n # Expect that column `trsmn` is of type: character\n col_is_character(\n columns = vars(trsmn)\n ) %>%\n # Expect that column `ctry_origin` is of type: character\n col_is_character(\n columns = vars(ctry_origin)\n ) %>%\n # Expect that values in `ctry_origin` should be in the set of `United States`, `Italy`, `Japan` (and 2 more)\n col_vals_in_set(\n columns = vars(ctry_origin),\n set = c(\"United States\", \"Italy\", \"Japan\", \"United Kingdom\", \"Germany\")\n ) %>%\n # Expect that column `msrp` is of type: numeric\n col_is_numeric(\n columns = vars(msrp)\n ) %>%\n # Expect that values in `msrp` should be between `53900` and `1416362`\n col_vals_between(\n columns = vars(msrp),\n left = 53900,\n right = 1416362\n ) %>%\n # Expect entirely distinct rows across all columns\n rows_distinct() %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n mfr = \"character\",\n model = \"character\",\n year = \"numeric\",\n trim = \"character\",\n bdy_style = \"character\",\n hp = \"numeric\",\n hp_rpm = \"numeric\",\n trq = \"numeric\",\n trq_rpm = \"numeric\",\n mpg_c = \"numeric\",\n mpg_h = \"numeric\",\n drivetrain = \"character\",\n trsmn = \"character\",\n ctry_origin = \"character\",\n msrp = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `mfr` is of type: character\n col_is_character(\n columns = c(\"mfr\")\n ) %>%\n # Expect that column `model` is of type: character\n col_is_character(\n columns = c(\"model\")\n ) %>%\n # Expect that column `year` is of type: numeric\n col_is_numeric(\n columns = c(\"year\")\n ) %>%\n # Expect that values in `year` should be between `2014` and `2017`\n col_vals_between(\n columns = c(\"year\"),\n left = 2014,\n right = 2017\n ) %>%\n # Expect that column `trim` is of type: character\n col_is_character(\n columns = c(\"trim\")\n ) %>%\n # Expect that column `bdy_style` is of type: character\n col_is_character(\n columns = c(\"bdy_style\")\n ) %>%\n # Expect that column `hp` is of type: numeric\n col_is_numeric(\n columns = c(\"hp\")\n ) %>%\n # Expect that values in `hp` should be between `259` and `949`\n col_vals_between(\n columns = c(\"hp\"),\n left = 259,\n right = 949\n ) %>%\n # Expect that column `hp_rpm` is of type: numeric\n col_is_numeric(\n columns = c(\"hp_rpm\")\n ) %>%\n # Expect that values in `hp_rpm` should be between `5000` and `9000`\n col_vals_between(\n columns = c(\"hp_rpm\"),\n left = 5000,\n right = 9000\n ) %>%\n # Expect that column `trq` is of type: numeric\n col_is_numeric(\n columns = c(\"trq\")\n ) %>%\n # Expect that values in `trq` should be between `243` and `664`\n col_vals_between(\n columns = c(\"trq\"),\n left = 243,\n right = 664\n ) %>%\n # Expect that column `trq_rpm` is of type: numeric\n col_is_numeric(\n columns = c(\"trq_rpm\")\n ) %>%\n # Expect that values in `trq_rpm` should be between `1400` and `6750`\n col_vals_between(\n columns = c(\"trq_rpm\"),\n left = 1400,\n right = 6750,\n na_pass = TRUE\n ) %>%\n # Expect that column `mpg_c` is of type: numeric\n col_is_numeric(\n columns = c(\"mpg_c\")\n ) %>%\n # Expect that values in `mpg_c` should be between `11` and `28`\n col_vals_between(\n columns = c(\"mpg_c\"),\n left = 11,\n right = 28,\n na_pass = TRUE\n ) %>%\n # Expect that column `mpg_h` is of type: numeric\n col_is_numeric(\n columns = c(\"mpg_h\")\n ) %>%\n # Expect that values in `mpg_h` should be between `16` and `30`\n col_vals_between(\n columns = c(\"mpg_h\"),\n left = 16,\n right = 30,\n na_pass = TRUE\n ) %>%\n # Expect that column `drivetrain` is of type: character\n col_is_character(\n columns = c(\"drivetrain\")\n ) %>%\n # Expect that column `trsmn` is of type: character\n col_is_character(\n columns = c(\"trsmn\")\n ) %>%\n # Expect that column `ctry_origin` is of type: character\n col_is_character(\n columns = c(\"ctry_origin\")\n ) %>%\n # Expect that values in `ctry_origin` should be in the set of `United States`, `Italy`, `Japan` (and 2 more)\n col_vals_in_set(\n columns = c(\"ctry_origin\"),\n set = c(\"United States\", \"Italy\", \"Japan\", \"United Kingdom\", \"Germany\")\n ) %>%\n # Expect that column `msrp` is of type: numeric\n col_is_numeric(\n columns = c(\"msrp\")\n ) %>%\n # Expect that values in `msrp` should be between `53900` and `1416362`\n col_vals_between(\n columns = c(\"msrp\"),\n left = 53900,\n right = 1416362\n ) %>%\n # Expect entirely distinct rows across `mfr, model, year, trim, bdy_style, hp, hp_rpm, trq, trq_rpm, mpg_c, mpg_h, drivetrain, trsmn, ctry_origin, msrp`\n rows_distinct(\n columns = c(\"mfr\", \"model\", \"year\", \"trim\", \"bdy_style\", \"hp\", \"hp_rpm\", \"trq\", \"trq_rpm\", \"mpg_c\", \"mpg_h\", \"drivetrain\", \"trsmn\", \"ctry_origin\", \"msrp\")\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n mfr = \"character\",\n model = \"character\",\n year = \"numeric\",\n trim = \"character\",\n bdy_style = \"character\",\n hp = \"numeric\",\n hp_rpm = \"numeric\",\n trq = \"numeric\",\n trq_rpm = \"numeric\",\n mpg_c = \"numeric\",\n mpg_h = \"numeric\",\n drivetrain = \"character\",\n trsmn = \"character\",\n ctry_origin = \"character\",\n msrp = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `open` is of type: numeric\n col_is_numeric(\n columns = vars(open)\n ) %>%\n # Expect that values in `open` should be between `16.66` and `2130.3601`\n col_vals_between(\n columns = vars(open),\n left = 16.66,\n right = 2130.3601\n ) %>%\n # Expect that column `high` is of type: numeric\n col_is_numeric(\n columns = vars(high)\n ) %>%\n # Expect that values in `high` should be between `16.66` and `2134.72`\n col_vals_between(\n columns = vars(high),\n left = 16.66,\n right = 2134.72\n ) %>%\n # Expect that column `low` is of type: numeric\n col_is_numeric(\n columns = vars(low)\n ) %>%\n # Expect that values in `low` should be between `16.66` and `2126.0601`\n col_vals_between(\n columns = vars(low),\n left = 16.66,\n right = 2126.0601\n ) %>%\n # Expect that column `close` is of type: numeric\n col_is_numeric(\n columns = vars(close)\n ) %>%\n # Expect that values in `close` should be between `16.66` and `2130.8201`\n col_vals_between(\n columns = vars(close),\n left = 16.66,\n right = 2130.8201\n ) %>%\n # Expect that column `volume` is of type: numeric\n col_is_numeric(\n columns = vars(volume)\n ) %>%\n # Expect that values in `volume` should be between `680000` and `11456230400`\n col_vals_between(\n columns = vars(volume),\n left = 680000,\n right = 11456230000\n ) %>%\n # Expect that column `adj_close` is of type: numeric\n col_is_numeric(\n columns = vars(adj_close)\n ) %>%\n # Expect that values in `adj_close` should be between `16.66` and `2130.8201`\n col_vals_between(\n columns = vars(adj_close),\n left = 16.66,\n right = 2130.8201\n ) %>%\n # Expect entirely distinct rows across all columns\n rows_distinct() %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n date = \"Date\",\n open = \"numeric\",\n high = \"numeric\",\n low = \"numeric\",\n close = \"numeric\",\n volume = \"numeric\",\n adj_close = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `open` is of type: numeric\n col_is_numeric(\n columns = c(\"open\")\n ) %>%\n # Expect that values in `open` should be between `16.66` and `2130.3601`\n col_vals_between(\n columns = c(\"open\"),\n left = 16.66,\n right = 2130.3601\n ) %>%\n # Expect that column `high` is of type: numeric\n col_is_numeric(\n columns = c(\"high\")\n ) %>%\n # Expect that values in `high` should be between `16.66` and `2134.72`\n col_vals_between(\n columns = c(\"high\"),\n left = 16.66,\n right = 2134.72\n ) %>%\n # Expect that column `low` is of type: numeric\n col_is_numeric(\n columns = c(\"low\")\n ) %>%\n # Expect that values in `low` should be between `16.66` and `2126.0601`\n col_vals_between(\n columns = c(\"low\"),\n left = 16.66,\n right = 2126.0601\n ) %>%\n # Expect that column `close` is of type: numeric\n col_is_numeric(\n columns = c(\"close\")\n ) %>%\n # Expect that values in `close` should be between `16.66` and `2130.8201`\n col_vals_between(\n columns = c(\"close\"),\n left = 16.66,\n right = 2130.8201\n ) %>%\n # Expect that column `volume` is of type: numeric\n col_is_numeric(\n columns = c(\"volume\")\n ) %>%\n # Expect that values in `volume` should be between `680000` and `11456230400`\n col_vals_between(\n columns = c(\"volume\"),\n left = 680000,\n right = 11456230000\n ) %>%\n # Expect that column `adj_close` is of type: numeric\n col_is_numeric(\n columns = c(\"adj_close\")\n ) %>%\n # Expect that values in `adj_close` should be between `16.66` and `2130.8201`\n col_vals_between(\n columns = c(\"adj_close\"),\n left = 16.66,\n right = 2130.8201\n ) %>%\n # Expect entirely distinct rows across `date, open, high, low, close, volume, adj_close`\n rows_distinct(\n columns = c(\"date\", \"open\", \"high\", \"low\", \"close\", \"volume\", \"adj_close\")\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n date = \"Date\",\n open = \"numeric\",\n high = \"numeric\",\n low = \"numeric\",\n close = \"numeric\",\n volume = \"numeric\",\n adj_close = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `id` is of type: character\n col_is_character(\n columns = vars(id)\n ) %>%\n # Expect that column `date` is of type: character\n col_is_character(\n columns = vars(date)\n ) %>%\n # Expect that column `time` is of type: character\n col_is_character(\n columns = vars(time)\n ) %>%\n # Expect that column `name` is of type: character\n col_is_character(\n columns = vars(name)\n ) %>%\n # Expect that column `size` is of type: character\n col_is_character(\n columns = vars(size)\n ) %>%\n # Expect that column `type` is of type: character\n col_is_character(\n columns = vars(type)\n ) %>%\n # Expect that column `price` is of type: numeric\n col_is_numeric(\n columns = vars(price)\n ) %>%\n # Expect that values in `price` should be between `9.75` and `35.95`\n col_vals_between(\n columns = vars(price),\n left = 9.75,\n right = 35.95\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n id = \"character\",\n date = \"character\",\n time = \"character\",\n name = \"character\",\n size = \"character\",\n type = \"character\",\n price = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `id` is of type: character\n col_is_character(\n columns = c(\"id\")\n ) %>%\n # Expect that column `date` is of type: character\n col_is_character(\n columns = c(\"date\")\n ) %>%\n # Expect that column `time` is of type: character\n col_is_character(\n columns = c(\"time\")\n ) %>%\n # Expect that column `name` is of type: character\n col_is_character(\n columns = c(\"name\")\n ) %>%\n # Expect that column `size` is of type: character\n col_is_character(\n columns = c(\"size\")\n ) %>%\n # Expect that column `type` is of type: character\n col_is_character(\n columns = c(\"type\")\n ) %>%\n # Expect that column `price` is of type: numeric\n col_is_numeric(\n columns = c(\"price\")\n ) %>%\n # Expect that values in `price` should be between `9.75` and `35.95`\n col_vals_between(\n columns = c(\"price\"),\n left = 9.75,\n right = 35.95\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n id = \"character\",\n date = \"character\",\n time = \"character\",\n name = \"character\",\n size = \"character\",\n type = \"character\",\n price = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `num` is of type: numeric\n col_is_numeric(\n columns = vars(num)\n ) %>%\n # Expect that values in `num` should be between `0.1111` and `8880000`\n col_vals_between(\n columns = vars(num),\n left = 0.1111,\n right = 8880000,\n na_pass = TRUE\n ) %>%\n # Expect that column `char` is of type: character\n col_is_character(\n columns = vars(char)\n ) %>%\n # Expect that column `fctr` is of type: factor\n col_is_factor(\n columns = vars(fctr)\n ) %>%\n # Expect that column `date` is of type: character\n col_is_character(\n columns = vars(date)\n ) %>%\n # Expect that column `time` is of type: character\n col_is_character(\n columns = vars(time)\n ) %>%\n # Expect that column `datetime` is of type: character\n col_is_character(\n columns = vars(datetime)\n ) %>%\n # Expect that column `currency` is of type: numeric\n col_is_numeric(\n columns = vars(currency)\n ) %>%\n # Expect that values in `currency` should be between `0.44` and `65100`\n col_vals_between(\n columns = vars(currency),\n left = 0.44,\n right = 65100,\n na_pass = TRUE\n ) %>%\n # Expect that column `row` is of type: character\n col_is_character(\n columns = vars(row)\n ) %>%\n # Expect that column `group` is of type: character\n col_is_character(\n columns = vars(group)\n ) %>%\n # Expect entirely distinct rows across all columns\n rows_distinct() %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n num = \"numeric\",\n char = \"character\",\n fctr = \"factor\",\n date = \"character\",\n time = \"character\",\n datetime = \"character\",\n currency = \"numeric\",\n row = \"character\",\n group = \"character\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `num` is of type: numeric\n col_is_numeric(\n columns = c(\"num\")\n ) %>%\n # Expect that values in `num` should be between `0.1111` and `8880000`\n col_vals_between(\n columns = c(\"num\"),\n left = 0.1111,\n right = 8880000,\n na_pass = TRUE\n ) %>%\n # Expect that column `char` is of type: character\n col_is_character(\n columns = c(\"char\")\n ) %>%\n # Expect that column `fctr` is of type: factor\n col_is_factor(\n columns = c(\"fctr\")\n ) %>%\n # Expect that column `date` is of type: character\n col_is_character(\n columns = c(\"date\")\n ) %>%\n # Expect that column `time` is of type: character\n col_is_character(\n columns = c(\"time\")\n ) %>%\n # Expect that column `datetime` is of type: character\n col_is_character(\n columns = c(\"datetime\")\n ) %>%\n # Expect that column `currency` is of type: numeric\n col_is_numeric(\n columns = c(\"currency\")\n ) %>%\n # Expect that values in `currency` should be between `0.44` and `65100`\n col_vals_between(\n columns = c(\"currency\"),\n left = 0.44,\n right = 65100,\n na_pass = TRUE\n ) %>%\n # Expect that column `row` is of type: character\n col_is_character(\n columns = c(\"row\")\n ) %>%\n # Expect that column `group` is of type: character\n col_is_character(\n columns = c(\"group\")\n ) %>%\n # Expect entirely distinct rows across `num, char, fctr, date, time, datetime, currency, row, group`\n rows_distinct(\n columns = c(\"num\", \"char\", \"fctr\", \"date\", \"time\", \"datetime\", \"currency\", \"row\", \"group\")\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n num = \"numeric\",\n char = \"character\",\n fctr = \"factor\",\n date = \"character\",\n time = \"character\",\n datetime = \"character\",\n currency = \"numeric\",\n row = \"character\",\n group = \"character\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `carat` is of type: numeric\n col_is_numeric(\n columns = vars(carat)\n ) %>%\n # Expect that values in `carat` should be between `0.2` and `5.01`\n col_vals_between(\n columns = vars(carat),\n left = 0.2,\n right = 5.01\n ) %>%\n # Expect that column `cut` is of type: factor\n col_is_factor(\n columns = vars(cut)\n ) %>%\n # Expect that column `color` is of type: factor\n col_is_factor(\n columns = vars(color)\n ) %>%\n # Expect that column `clarity` is of type: factor\n col_is_factor(\n columns = vars(clarity)\n ) %>%\n # Expect that column `depth` is of type: numeric\n col_is_numeric(\n columns = vars(depth)\n ) %>%\n # Expect that values in `depth` should be between `43` and `79`\n col_vals_between(\n columns = vars(depth),\n left = 43,\n right = 79\n ) %>%\n # Expect that column `table` is of type: numeric\n col_is_numeric(\n columns = vars(table)\n ) %>%\n # Expect that values in `table` should be between `43` and `95`\n col_vals_between(\n columns = vars(table),\n left = 43,\n right = 95\n ) %>%\n # Expect that column `price` is of type: integer\n col_is_integer(\n columns = vars(price)\n ) %>%\n # Expect that values in `price` should be between `326` and `18823`\n col_vals_between(\n columns = vars(price),\n left = 326,\n right = 18823\n ) %>%\n # Expect that column `x` is of type: numeric\n col_is_numeric(\n columns = vars(x)\n ) %>%\n # Expect that values in `x` should be between `0` and `10.74`\n col_vals_between(\n columns = vars(x),\n left = 0,\n right = 10.74\n ) %>%\n # Expect that column `y` is of type: numeric\n col_is_numeric(\n columns = vars(y)\n ) %>%\n # Expect that values in `y` should be between `0` and `58.9`\n col_vals_between(\n columns = vars(y),\n left = 0,\n right = 58.9\n ) %>%\n # Expect that column `z` is of type: numeric\n col_is_numeric(\n columns = vars(z)\n ) %>%\n # Expect that values in `z` should be between `0` and `31.8`\n col_vals_between(\n columns = vars(z),\n left = 0,\n right = 31.8\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n carat = \"numeric\",\n cut = c(\"ordered\", \"factor\"),\n color = c(\"ordered\", \"factor\"),\n clarity = c(\"ordered\", \"factor\"),\n depth = \"numeric\",\n table = \"numeric\",\n price = \"integer\",\n x = \"numeric\",\n y = \"numeric\",\n z = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `carat` is of type: numeric\n col_is_numeric(\n columns = c(\"carat\")\n ) %>%\n # Expect that values in `carat` should be between `0.2` and `5.01`\n col_vals_between(\n columns = c(\"carat\"),\n left = 0.2,\n right = 5.01\n ) %>%\n # Expect that column `cut` is of type: factor\n col_is_factor(\n columns = c(\"cut\")\n ) %>%\n # Expect that column `color` is of type: factor\n col_is_factor(\n columns = c(\"color\")\n ) %>%\n # Expect that column `clarity` is of type: factor\n col_is_factor(\n columns = c(\"clarity\")\n ) %>%\n # Expect that column `depth` is of type: numeric\n col_is_numeric(\n columns = c(\"depth\")\n ) %>%\n # Expect that values in `depth` should be between `43` and `79`\n col_vals_between(\n columns = c(\"depth\"),\n left = 43,\n right = 79\n ) %>%\n # Expect that column `table` is of type: numeric\n col_is_numeric(\n columns = c(\"table\")\n ) %>%\n # Expect that values in `table` should be between `43` and `95`\n col_vals_between(\n columns = c(\"table\"),\n left = 43,\n right = 95\n ) %>%\n # Expect that column `price` is of type: integer\n col_is_integer(\n columns = c(\"price\")\n ) %>%\n # Expect that values in `price` should be between `326` and `18823`\n col_vals_between(\n columns = c(\"price\"),\n left = 326,\n right = 18823\n ) %>%\n # Expect that column `x` is of type: numeric\n col_is_numeric(\n columns = c(\"x\")\n ) %>%\n # Expect that values in `x` should be between `0` and `10.74`\n col_vals_between(\n columns = c(\"x\"),\n left = 0,\n right = 10.74\n ) %>%\n # Expect that column `y` is of type: numeric\n col_is_numeric(\n columns = c(\"y\")\n ) %>%\n # Expect that values in `y` should be between `0` and `58.9`\n col_vals_between(\n columns = c(\"y\"),\n left = 0,\n right = 58.9\n ) %>%\n # Expect that column `z` is of type: numeric\n col_is_numeric(\n columns = c(\"z\")\n ) %>%\n # Expect that values in `z` should be between `0` and `31.8`\n col_vals_between(\n columns = c(\"z\"),\n left = 0,\n right = 31.8\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n carat = \"numeric\",\n cut = c(\"ordered\", \"factor\"),\n color = c(\"ordered\", \"factor\"),\n clarity = c(\"ordered\", \"factor\"),\n depth = \"numeric\",\n table = \"numeric\",\n price = \"integer\",\n x = \"numeric\",\n y = \"numeric\",\n z = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `variable` is of type: character\n col_is_character(\n columns = vars(variable)\n ) %>%\n # Expect that column `value` is of type: numeric\n col_is_numeric(\n columns = vars(value)\n ) %>%\n # Expect that values in `value` should be between `2.2` and `320402.295`\n col_vals_between(\n columns = vars(value),\n left = 2.2,\n right = 320402.295\n ) %>%\n # Expect that column `value01` is of type: numeric\n col_is_numeric(\n columns = vars(value01)\n ) %>%\n # Expect that values in `value01` should be between `0` and `1`\n col_vals_between(\n columns = vars(value01),\n left = 0,\n right = 1\n ) %>%\n # Expect entirely distinct rows across all columns\n rows_distinct() %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n date = \"Date\",\n variable = \"character\",\n value = \"numeric\",\n value01 = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `variable` is of type: character\n col_is_character(\n columns = c(\"variable\")\n ) %>%\n # Expect that column `value` is of type: numeric\n col_is_numeric(\n columns = c(\"value\")\n ) %>%\n # Expect that values in `value` should be between `2.2` and `320402.295`\n col_vals_between(\n columns = c(\"value\"),\n left = 2.2,\n right = 320402.295\n ) %>%\n # Expect that column `value01` is of type: numeric\n col_is_numeric(\n columns = c(\"value01\")\n ) %>%\n # Expect that values in `value01` should be between `0` and `1`\n col_vals_between(\n columns = c(\"value01\"),\n left = 0,\n right = 1\n ) %>%\n # Expect entirely distinct rows across `date, variable, value, value01`\n rows_distinct(\n columns = c(\"date\", \"variable\", \"value\", \"value01\")\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n date = \"Date\",\n variable = \"character\",\n value = \"numeric\",\n value01 = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `eruptions` is of type: numeric\n col_is_numeric(\n columns = vars(eruptions)\n ) %>%\n # Expect that values in `eruptions` should be between `1.6` and `5.1`\n col_vals_between(\n columns = vars(eruptions),\n left = 1.6,\n right = 5.1\n ) %>%\n # Expect that column `waiting` is of type: numeric\n col_is_numeric(\n columns = vars(waiting)\n ) %>%\n # Expect that values in `waiting` should be between `43` and `96`\n col_vals_between(\n columns = vars(waiting),\n left = 43,\n right = 96\n ) %>%\n # Expect that column `density` is of type: numeric\n col_is_numeric(\n columns = vars(density)\n ) %>%\n # Expect that values in `density` should be between `1.25924972782687e-24` and `0.0369877986891108`\n col_vals_between(\n columns = vars(density),\n left = 1.2592497e-24,\n right = 0.0369878\n ) %>%\n # Expect entirely distinct rows across all columns\n rows_distinct() %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n eruptions = \"numeric\",\n waiting = \"numeric\",\n density = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `eruptions` is of type: numeric\n col_is_numeric(\n columns = c(\"eruptions\")\n ) %>%\n # Expect that values in `eruptions` should be between `1.6` and `5.1`\n col_vals_between(\n columns = c(\"eruptions\"),\n left = 1.6,\n right = 5.1\n ) %>%\n # Expect that column `waiting` is of type: numeric\n col_is_numeric(\n columns = c(\"waiting\")\n ) %>%\n # Expect that values in `waiting` should be between `43` and `96`\n col_vals_between(\n columns = c(\"waiting\"),\n left = 43,\n right = 96\n ) %>%\n # Expect that column `density` is of type: numeric\n col_is_numeric(\n columns = c(\"density\")\n ) %>%\n # Expect that values in `density` should be between `1.25924972782687e-24` and `0.0369877986891108`\n col_vals_between(\n columns = c(\"density\"),\n left = 1.2592497e-24,\n right = 0.0369878\n ) %>%\n # Expect entirely distinct rows across `eruptions, waiting, density`\n rows_distinct(\n columns = c(\"eruptions\", \"waiting\", \"density\")\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n eruptions = \"numeric\",\n waiting = \"numeric\",\n density = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `L` is of type: numeric\n col_is_numeric(\n columns = vars(L)\n ) %>%\n # Expect that values in `L` should be between `0` and `9341.57022199546`\n col_vals_between(\n columns = vars(L),\n left = 0,\n right = 9341.570222\n ) %>%\n # Expect that column `u` is of type: numeric\n col_is_numeric(\n columns = vars(u)\n ) %>%\n # Expect that values in `u` should be between `-7971.69318804991` and `18325.9445754841`\n col_vals_between(\n columns = vars(u),\n left = -7971.693188,\n right = 18325.9445755\n ) %>%\n # Expect that column `v` is of type: numeric\n col_is_numeric(\n columns = vars(v)\n ) %>%\n # Expect that values in `v` should be between `-15649.9250273997` and `10194.4413048169`\n col_vals_between(\n columns = vars(v),\n left = -15649.9250274,\n right = 10194.4413048\n ) %>%\n # Expect that column `col` is of type: character\n col_is_character(\n columns = vars(col)\n ) %>%\n # Expect entirely distinct rows across all columns\n rows_distinct() %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n L = \"numeric\",\n u = \"numeric\",\n v = \"numeric\",\n col = \"character\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `L` is of type: numeric\n col_is_numeric(\n columns = c(\"L\")\n ) %>%\n # Expect that values in `L` should be between `0` and `9341.57022199546`\n col_vals_between(\n columns = c(\"L\"),\n left = 0,\n right = 9341.570222\n ) %>%\n # Expect that column `u` is of type: numeric\n col_is_numeric(\n columns = c(\"u\")\n ) %>%\n # Expect that values in `u` should be between `-7971.69318804991` and `18325.9445754841`\n col_vals_between(\n columns = c(\"u\"),\n left = -7971.693188,\n right = 18325.9445755\n ) %>%\n # Expect that column `v` is of type: numeric\n col_is_numeric(\n columns = c(\"v\")\n ) %>%\n # Expect that values in `v` should be between `-15649.9250273997` and `10194.4413048169`\n col_vals_between(\n columns = c(\"v\"),\n left = -15649.9250274,\n right = 10194.4413048\n ) %>%\n # Expect that column `col` is of type: character\n col_is_character(\n columns = c(\"col\")\n ) %>%\n # Expect entirely distinct rows across `L, u, v, col`\n rows_distinct(\n columns = c(\"L\", \"u\", \"v\", \"col\")\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n L = \"numeric\",\n u = \"numeric\",\n v = \"numeric\",\n col = \"character\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `PID` is of type: integer\n col_is_integer(\n columns = vars(PID)\n ) %>%\n # Expect that values in `PID` should be between `561` and `3052`\n col_vals_between(\n columns = vars(PID),\n left = 561,\n right = 3052\n ) %>%\n # Expect that column `county` is of type: character\n col_is_character(\n columns = vars(county)\n ) %>%\n # Expect that column `state` is of type: character\n col_is_character(\n columns = vars(state)\n ) %>%\n # Expect that column `area` is of type: numeric\n col_is_numeric(\n columns = vars(area)\n ) %>%\n # Expect that values in `area` should be between `0.005` and `0.11`\n col_vals_between(\n columns = vars(area),\n left = 0.005,\n right = 0.11\n ) %>%\n # Expect that column `poptotal` is of type: integer\n col_is_integer(\n columns = vars(poptotal)\n ) %>%\n # Expect that values in `poptotal` should be between `1701` and `5105067`\n col_vals_between(\n columns = vars(poptotal),\n left = 1701,\n right = 5105067\n ) %>%\n # Expect that column `popdensity` is of type: numeric\n col_is_numeric(\n columns = vars(popdensity)\n ) %>%\n # Expect that values in `popdensity` should be between `85.05` and `88018.3966`\n col_vals_between(\n columns = vars(popdensity),\n left = 85.05,\n right = 88018.3966\n ) %>%\n # Expect that column `popwhite` is of type: integer\n col_is_integer(\n columns = vars(popwhite)\n ) %>%\n # Expect that values in `popwhite` should be between `416` and `3204947`\n col_vals_between(\n columns = vars(popwhite),\n left = 416,\n right = 3204947\n ) %>%\n # Expect that column `popblack` is of type: integer\n col_is_integer(\n columns = vars(popblack)\n ) %>%\n # Expect that values in `popblack` should be between `0` and `1317147`\n col_vals_between(\n columns = vars(popblack),\n left = 0,\n right = 1317147\n ) %>%\n # Expect that column `popamerindian` is of type: integer\n col_is_integer(\n columns = vars(popamerindian)\n ) %>%\n # Expect that values in `popamerindian` should be between `4` and `10289`\n col_vals_between(\n columns = vars(popamerindian),\n left = 4,\n right = 10289\n ) %>%\n # Expect that column `popasian` is of type: integer\n col_is_integer(\n columns = vars(popasian)\n ) %>%\n # Expect that values in `popasian` should be between `0` and `188565`\n col_vals_between(\n columns = vars(popasian),\n left = 0,\n right = 188565\n ) %>%\n # Expect that column `popother` is of type: integer\n col_is_integer(\n columns = vars(popother)\n ) %>%\n # Expect that values in `popother` should be between `0` and `384119`\n col_vals_between(\n columns = vars(popother),\n left = 0,\n right = 384119\n ) %>%\n # Expect that column `percwhite` is of type: numeric\n col_is_numeric(\n columns = vars(percwhite)\n ) %>%\n # Expect that values in `percwhite` should be between `10.6940874` and `99.8228207`\n col_vals_between(\n columns = vars(percwhite),\n left = 10.6940874,\n right = 99.8228207\n ) %>%\n # Expect that column `percblack` is of type: numeric\n col_is_numeric(\n columns = vars(percblack)\n ) %>%\n # Expect that values in `percblack` should be between `0` and `40.2099838`\n col_vals_between(\n columns = vars(percblack),\n left = 0,\n right = 40.2099838\n ) %>%\n # Expect that column `percamerindan` is of type: numeric\n col_is_numeric(\n columns = vars(percamerindan)\n ) %>%\n # Expect that values in `percamerindan` should be between `0.05623243` and `89.1773779`\n col_vals_between(\n columns = vars(percamerindan),\n left = 0.0562324,\n right = 89.1773779\n ) %>%\n # Expect that column `percasian` is of type: numeric\n col_is_numeric(\n columns = vars(percasian)\n ) %>%\n # Expect that values in `percasian` should be between `0` and `5.07045209`\n col_vals_between(\n columns = vars(percasian),\n left = 0,\n right = 5.0704521\n ) %>%\n # Expect that column `percother` is of type: numeric\n col_is_numeric(\n columns = vars(percother)\n ) %>%\n # Expect that values in `percother` should be between `0` and `7.52426951`\n col_vals_between(\n columns = vars(percother),\n left = 0,\n right = 7.5242695\n ) %>%\n # Expect that column `popadults` is of type: integer\n col_is_integer(\n columns = vars(popadults)\n ) %>%\n # Expect that values in `popadults` should be between `1287` and `3291995`\n col_vals_between(\n columns = vars(popadults),\n left = 1287,\n right = 3291995\n ) %>%\n # Expect that column `perchsd` is of type: numeric\n col_is_numeric(\n columns = vars(perchsd)\n ) %>%\n # Expect that values in `perchsd` should be between `46.912261` and `88.8986737`\n col_vals_between(\n columns = vars(perchsd),\n left = 46.912261,\n right = 88.8986737\n ) %>%\n # Expect that column `percollege` is of type: numeric\n col_is_numeric(\n columns = vars(percollege)\n ) %>%\n # Expect that values in `percollege` should be between `7.33610822` and `48.0785102`\n col_vals_between(\n columns = vars(percollege),\n left = 7.3361082,\n right = 48.0785102\n ) %>%\n # Expect that column `percprof` is of type: numeric\n col_is_numeric(\n columns = vars(percprof)\n ) %>%\n # Expect that values in `percprof` should be between `0.52029136` and `20.7913213`\n col_vals_between(\n columns = vars(percprof),\n left = 0.5202914,\n right = 20.7913213\n ) %>%\n # Expect that column `poppovertyknown` is of type: integer\n col_is_integer(\n columns = vars(poppovertyknown)\n ) %>%\n # Expect that values in `poppovertyknown` should be between `1696` and `5023523`\n col_vals_between(\n columns = vars(poppovertyknown),\n left = 1696,\n right = 5023523\n ) %>%\n # Expect that column `percpovertyknown` is of type: numeric\n col_is_numeric(\n columns = vars(percpovertyknown)\n ) %>%\n # Expect that values in `percpovertyknown` should be between `80.9024412` and `99.8603839`\n col_vals_between(\n columns = vars(percpovertyknown),\n left = 80.9024412,\n right = 99.8603839\n ) %>%\n # Expect that column `percbelowpoverty` is of type: numeric\n col_is_numeric(\n columns = vars(percbelowpoverty)\n ) %>%\n # Expect that values in `percbelowpoverty` should be between `2.1801676` and `48.6910995`\n col_vals_between(\n columns = vars(percbelowpoverty),\n left = 2.1801676,\n right = 48.6910995\n ) %>%\n # Expect that column `percchildbelowpovert` is of type: numeric\n col_is_numeric(\n columns = vars(percchildbelowpovert)\n ) %>%\n # Expect that values in `percchildbelowpovert` should be between `1.91895478` and `64.3084767`\n col_vals_between(\n columns = vars(percchildbelowpovert),\n left = 1.9189548,\n right = 64.3084767\n ) %>%\n # Expect that column `percadultpoverty` is of type: numeric\n col_is_numeric(\n columns = vars(percadultpoverty)\n ) %>%\n # Expect that values in `percadultpoverty` should be between `1.9385043` and `43.3124644`\n col_vals_between(\n columns = vars(percadultpoverty),\n left = 1.9385043,\n right = 43.3124644\n ) %>%\n # Expect that column `percelderlypoverty` is of type: numeric\n col_is_numeric(\n columns = vars(percelderlypoverty)\n ) %>%\n # Expect that values in `percelderlypoverty` should be between `3.54706685` and `31.1619718`\n col_vals_between(\n columns = vars(percelderlypoverty),\n left = 3.5470669,\n right = 31.1619718\n ) %>%\n # Expect that column `inmetro` is of type: integer\n col_is_integer(\n columns = vars(inmetro)\n ) %>%\n # Expect that values in `inmetro` should be between `0` and `1`\n col_vals_between(\n columns = vars(inmetro),\n left = 0,\n right = 1\n ) %>%\n # Expect that column `category` is of type: character\n col_is_character(\n columns = vars(category)\n ) %>%\n # Expect entirely distinct rows across all columns\n rows_distinct() %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n PID = \"integer\",\n county = \"character\",\n state = \"character\",\n area = \"numeric\",\n poptotal = \"integer\",\n popdensity = \"numeric\",\n popwhite = \"integer\",\n popblack = \"integer\",\n popamerindian = \"integer\",\n popasian = \"integer\",\n popother = \"integer\",\n percwhite = \"numeric\",\n percblack = \"numeric\",\n percamerindan = \"numeric\",\n percasian = \"numeric\",\n percother = \"numeric\",\n popadults = \"integer\",\n perchsd = \"numeric\",\n percollege = \"numeric\",\n percprof = \"numeric\",\n poppovertyknown = \"integer\",\n percpovertyknown = \"numeric\",\n percbelowpoverty = \"numeric\",\n percchildbelowpovert = \"numeric\",\n percadultpoverty = \"numeric\",\n percelderlypoverty = \"numeric\",\n inmetro = \"integer\",\n category = \"character\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `PID` is of type: integer\n col_is_integer(\n columns = c(\"PID\")\n ) %>%\n # Expect that values in `PID` should be between `561` and `3052`\n col_vals_between(\n columns = c(\"PID\"),\n left = 561,\n right = 3052\n ) %>%\n # Expect that column `county` is of type: character\n col_is_character(\n columns = c(\"county\")\n ) %>%\n # Expect that column `state` is of type: character\n col_is_character(\n columns = c(\"state\")\n ) %>%\n # Expect that column `area` is of type: numeric\n col_is_numeric(\n columns = c(\"area\")\n ) %>%\n # Expect that values in `area` should be between `0.005` and `0.11`\n col_vals_between(\n columns = c(\"area\"),\n left = 0.005,\n right = 0.11\n ) %>%\n # Expect that column `poptotal` is of type: integer\n col_is_integer(\n columns = c(\"poptotal\")\n ) %>%\n # Expect that values in `poptotal` should be between `1701` and `5105067`\n col_vals_between(\n columns = c(\"poptotal\"),\n left = 1701,\n right = 5105067\n ) %>%\n # Expect that column `popdensity` is of type: numeric\n col_is_numeric(\n columns = c(\"popdensity\")\n ) %>%\n # Expect that values in `popdensity` should be between `85.05` and `88018.3966`\n col_vals_between(\n columns = c(\"popdensity\"),\n left = 85.05,\n right = 88018.3966\n ) %>%\n # Expect that column `popwhite` is of type: integer\n col_is_integer(\n columns = c(\"popwhite\")\n ) %>%\n # Expect that values in `popwhite` should be between `416` and `3204947`\n col_vals_between(\n columns = c(\"popwhite\"),\n left = 416,\n right = 3204947\n ) %>%\n # Expect that column `popblack` is of type: integer\n col_is_integer(\n columns = c(\"popblack\")\n ) %>%\n # Expect that values in `popblack` should be between `0` and `1317147`\n col_vals_between(\n columns = c(\"popblack\"),\n left = 0,\n right = 1317147\n ) %>%\n # Expect that column `popamerindian` is of type: integer\n col_is_integer(\n columns = c(\"popamerindian\")\n ) %>%\n # Expect that values in `popamerindian` should be between `4` and `10289`\n col_vals_between(\n columns = c(\"popamerindian\"),\n left = 4,\n right = 10289\n ) %>%\n # Expect that column `popasian` is of type: integer\n col_is_integer(\n columns = c(\"popasian\")\n ) %>%\n # Expect that values in `popasian` should be between `0` and `188565`\n col_vals_between(\n columns = c(\"popasian\"),\n left = 0,\n right = 188565\n ) %>%\n # Expect that column `popother` is of type: integer\n col_is_integer(\n columns = c(\"popother\")\n ) %>%\n # Expect that values in `popother` should be between `0` and `384119`\n col_vals_between(\n columns = c(\"popother\"),\n left = 0,\n right = 384119\n ) %>%\n # Expect that column `percwhite` is of type: numeric\n col_is_numeric(\n columns = c(\"percwhite\")\n ) %>%\n # Expect that values in `percwhite` should be between `10.6940874` and `99.8228207`\n col_vals_between(\n columns = c(\"percwhite\"),\n left = 10.6940874,\n right = 99.8228207\n ) %>%\n # Expect that column `percblack` is of type: numeric\n col_is_numeric(\n columns = c(\"percblack\")\n ) %>%\n # Expect that values in `percblack` should be between `0` and `40.2099838`\n col_vals_between(\n columns = c(\"percblack\"),\n left = 0,\n right = 40.2099838\n ) %>%\n # Expect that column `percamerindan` is of type: numeric\n col_is_numeric(\n columns = c(\"percamerindan\")\n ) %>%\n # Expect that values in `percamerindan` should be between `0.05623243` and `89.1773779`\n col_vals_between(\n columns = c(\"percamerindan\"),\n left = 0.0562324,\n right = 89.1773779\n ) %>%\n # Expect that column `percasian` is of type: numeric\n col_is_numeric(\n columns = c(\"percasian\")\n ) %>%\n # Expect that values in `percasian` should be between `0` and `5.07045209`\n col_vals_between(\n columns = c(\"percasian\"),\n left = 0,\n right = 5.0704521\n ) %>%\n # Expect that column `percother` is of type: numeric\n col_is_numeric(\n columns = c(\"percother\")\n ) %>%\n # Expect that values in `percother` should be between `0` and `7.52426951`\n col_vals_between(\n columns = c(\"percother\"),\n left = 0,\n right = 7.5242695\n ) %>%\n # Expect that column `popadults` is of type: integer\n col_is_integer(\n columns = c(\"popadults\")\n ) %>%\n # Expect that values in `popadults` should be between `1287` and `3291995`\n col_vals_between(\n columns = c(\"popadults\"),\n left = 1287,\n right = 3291995\n ) %>%\n # Expect that column `perchsd` is of type: numeric\n col_is_numeric(\n columns = c(\"perchsd\")\n ) %>%\n # Expect that values in `perchsd` should be between `46.912261` and `88.8986737`\n col_vals_between(\n columns = c(\"perchsd\"),\n left = 46.912261,\n right = 88.8986737\n ) %>%\n # Expect that column `percollege` is of type: numeric\n col_is_numeric(\n columns = c(\"percollege\")\n ) %>%\n # Expect that values in `percollege` should be between `7.33610822` and `48.0785102`\n col_vals_between(\n columns = c(\"percollege\"),\n left = 7.3361082,\n right = 48.0785102\n ) %>%\n # Expect that column `percprof` is of type: numeric\n col_is_numeric(\n columns = c(\"percprof\")\n ) %>%\n # Expect that values in `percprof` should be between `0.52029136` and `20.7913213`\n col_vals_between(\n columns = c(\"percprof\"),\n left = 0.5202914,\n right = 20.7913213\n ) %>%\n # Expect that column `poppovertyknown` is of type: integer\n col_is_integer(\n columns = c(\"poppovertyknown\")\n ) %>%\n # Expect that values in `poppovertyknown` should be between `1696` and `5023523`\n col_vals_between(\n columns = c(\"poppovertyknown\"),\n left = 1696,\n right = 5023523\n ) %>%\n # Expect that column `percpovertyknown` is of type: numeric\n col_is_numeric(\n columns = c(\"percpovertyknown\")\n ) %>%\n # Expect that values in `percpovertyknown` should be between `80.9024412` and `99.8603839`\n col_vals_between(\n columns = c(\"percpovertyknown\"),\n left = 80.9024412,\n right = 99.8603839\n ) %>%\n # Expect that column `percbelowpoverty` is of type: numeric\n col_is_numeric(\n columns = c(\"percbelowpoverty\")\n ) %>%\n # Expect that values in `percbelowpoverty` should be between `2.1801676` and `48.6910995`\n col_vals_between(\n columns = c(\"percbelowpoverty\"),\n left = 2.1801676,\n right = 48.6910995\n ) %>%\n # Expect that column `percchildbelowpovert` is of type: numeric\n col_is_numeric(\n columns = c(\"percchildbelowpovert\")\n ) %>%\n # Expect that values in `percchildbelowpovert` should be between `1.91895478` and `64.3084767`\n col_vals_between(\n columns = c(\"percchildbelowpovert\"),\n left = 1.9189548,\n right = 64.3084767\n ) %>%\n # Expect that column `percadultpoverty` is of type: numeric\n col_is_numeric(\n columns = c(\"percadultpoverty\")\n ) %>%\n # Expect that values in `percadultpoverty` should be between `1.9385043` and `43.3124644`\n col_vals_between(\n columns = c(\"percadultpoverty\"),\n left = 1.9385043,\n right = 43.3124644\n ) %>%\n # Expect that column `percelderlypoverty` is of type: numeric\n col_is_numeric(\n columns = c(\"percelderlypoverty\")\n ) %>%\n # Expect that values in `percelderlypoverty` should be between `3.54706685` and `31.1619718`\n col_vals_between(\n columns = c(\"percelderlypoverty\"),\n left = 3.5470669,\n right = 31.1619718\n ) %>%\n # Expect that column `inmetro` is of type: integer\n col_is_integer(\n columns = c(\"inmetro\")\n ) %>%\n # Expect that values in `inmetro` should be between `0` and `1`\n col_vals_between(\n columns = c(\"inmetro\"),\n left = 0,\n right = 1\n ) %>%\n # Expect that column `category` is of type: character\n col_is_character(\n columns = c(\"category\")\n ) %>%\n # Expect entirely distinct rows across `PID, county, state, area, poptotal, popdensity, popwhite, popblack, popamerindian, popasian, popother, percwhite, percblack, percamerindan, percasian, percother, popadults, perchsd, percollege, percprof, poppovertyknown, percpovertyknown, percbelowpoverty, percchildbelowpovert, percadultpoverty, percelderlypoverty, inmetro, category`\n rows_distinct(\n columns = c(\"PID\", \"county\", \"state\", \"area\", \"poptotal\", \"popdensity\", \"popwhite\", \"popblack\", \"popamerindian\", \"popasian\", \"popother\", \"percwhite\", \"percblack\", \"percamerindan\", \"percasian\", \"percother\", \"popadults\", \"perchsd\", \"percollege\", \"percprof\", \"poppovertyknown\", \"percpovertyknown\", \"percbelowpoverty\", \"percchildbelowpovert\", \"percadultpoverty\", \"percelderlypoverty\", \"inmetro\", \"category\")\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n PID = \"integer\",\n county = \"character\",\n state = \"character\",\n area = \"numeric\",\n poptotal = \"integer\",\n popdensity = \"numeric\",\n popwhite = \"integer\",\n popblack = \"integer\",\n popamerindian = \"integer\",\n popasian = \"integer\",\n popother = \"integer\",\n percwhite = \"numeric\",\n percblack = \"numeric\",\n percamerindan = \"numeric\",\n percasian = \"numeric\",\n percother = \"numeric\",\n popadults = \"integer\",\n perchsd = \"numeric\",\n percollege = \"numeric\",\n percprof = \"numeric\",\n poppovertyknown = \"integer\",\n percpovertyknown = \"numeric\",\n percbelowpoverty = \"numeric\",\n percchildbelowpovert = \"numeric\",\n percadultpoverty = \"numeric\",\n percelderlypoverty = \"numeric\",\n inmetro = \"integer\",\n category = \"character\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `manufacturer` is of type: character\n col_is_character(\n columns = vars(manufacturer)\n ) %>%\n # Expect that column `model` is of type: character\n col_is_character(\n columns = vars(model)\n ) %>%\n # Expect that column `displ` is of type: numeric\n col_is_numeric(\n columns = vars(displ)\n ) %>%\n # Expect that values in `displ` should be between `1.6` and `7`\n col_vals_between(\n columns = vars(displ),\n left = 1.6,\n right = 7\n ) %>%\n # Expect that column `year` is of type: integer\n col_is_integer(\n columns = vars(year)\n ) %>%\n # Expect that values in `year` should be between `1999` and `2008`\n col_vals_between(\n columns = vars(year),\n left = 1999,\n right = 2008\n ) %>%\n # Expect that column `cyl` is of type: integer\n col_is_integer(\n columns = vars(cyl)\n ) %>%\n # Expect that values in `cyl` should be between `4` and `8`\n col_vals_between(\n columns = vars(cyl),\n left = 4,\n right = 8\n ) %>%\n # Expect that column `trans` is of type: character\n col_is_character(\n columns = vars(trans)\n ) %>%\n # Expect that column `drv` is of type: character\n col_is_character(\n columns = vars(drv)\n ) %>%\n # Expect that column `cty` is of type: integer\n col_is_integer(\n columns = vars(cty)\n ) %>%\n # Expect that values in `cty` should be between `9` and `35`\n col_vals_between(\n columns = vars(cty),\n left = 9,\n right = 35\n ) %>%\n # Expect that column `hwy` is of type: integer\n col_is_integer(\n columns = vars(hwy)\n ) %>%\n # Expect that values in `hwy` should be between `12` and `44`\n col_vals_between(\n columns = vars(hwy),\n left = 12,\n right = 44\n ) %>%\n # Expect that column `fl` is of type: character\n col_is_character(\n columns = vars(fl)\n ) %>%\n # Expect that column `class` is of type: character\n col_is_character(\n columns = vars(class)\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n manufacturer = \"character\",\n model = \"character\",\n displ = \"numeric\",\n year = \"integer\",\n cyl = \"integer\",\n trans = \"character\",\n drv = \"character\",\n cty = \"integer\",\n hwy = \"integer\",\n fl = \"character\",\n class = \"character\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `manufacturer` is of type: character\n col_is_character(\n columns = c(\"manufacturer\")\n ) %>%\n # Expect that column `model` is of type: character\n col_is_character(\n columns = c(\"model\")\n ) %>%\n # Expect that column `displ` is of type: numeric\n col_is_numeric(\n columns = c(\"displ\")\n ) %>%\n # Expect that values in `displ` should be between `1.6` and `7`\n col_vals_between(\n columns = c(\"displ\"),\n left = 1.6,\n right = 7\n ) %>%\n # Expect that column `year` is of type: integer\n col_is_integer(\n columns = c(\"year\")\n ) %>%\n # Expect that values in `year` should be between `1999` and `2008`\n col_vals_between(\n columns = c(\"year\"),\n left = 1999,\n right = 2008\n ) %>%\n # Expect that column `cyl` is of type: integer\n col_is_integer(\n columns = c(\"cyl\")\n ) %>%\n # Expect that values in `cyl` should be between `4` and `8`\n col_vals_between(\n columns = c(\"cyl\"),\n left = 4,\n right = 8\n ) %>%\n # Expect that column `trans` is of type: character\n col_is_character(\n columns = c(\"trans\")\n ) %>%\n # Expect that column `drv` is of type: character\n col_is_character(\n columns = c(\"drv\")\n ) %>%\n # Expect that column `cty` is of type: integer\n col_is_integer(\n columns = c(\"cty\")\n ) %>%\n # Expect that values in `cty` should be between `9` and `35`\n col_vals_between(\n columns = c(\"cty\"),\n left = 9,\n right = 35\n ) %>%\n # Expect that column `hwy` is of type: integer\n col_is_integer(\n columns = c(\"hwy\")\n ) %>%\n # Expect that values in `hwy` should be between `12` and `44`\n col_vals_between(\n columns = c(\"hwy\"),\n left = 12,\n right = 44\n ) %>%\n # Expect that column `fl` is of type: character\n col_is_character(\n columns = c(\"fl\")\n ) %>%\n # Expect that column `class` is of type: character\n col_is_character(\n columns = c(\"class\")\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n manufacturer = \"character\",\n model = \"character\",\n displ = \"numeric\",\n year = \"integer\",\n cyl = \"integer\",\n trans = \"character\",\n drv = \"character\",\n cty = \"integer\",\n hwy = \"integer\",\n fl = \"character\",\n class = \"character\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `name` is of type: character\n col_is_character(\n columns = vars(name)\n ) %>%\n # Expect that column `genus` is of type: character\n col_is_character(\n columns = vars(genus)\n ) %>%\n # Expect that column `vore` is of type: character\n col_is_character(\n columns = vars(vore)\n ) %>%\n # Expect that column `order` is of type: character\n col_is_character(\n columns = vars(order)\n ) %>%\n # Expect that column `conservation` is of type: character\n col_is_character(\n columns = vars(conservation)\n ) %>%\n # Expect that column `sleep_total` is of type: numeric\n col_is_numeric(\n columns = vars(sleep_total)\n ) %>%\n # Expect that values in `sleep_total` should be between `1.9` and `19.9`\n col_vals_between(\n columns = vars(sleep_total),\n left = 1.9,\n right = 19.9\n ) %>%\n # Expect that column `sleep_rem` is of type: numeric\n col_is_numeric(\n columns = vars(sleep_rem)\n ) %>%\n # Expect that values in `sleep_rem` should be between `0.1` and `6.6`\n col_vals_between(\n columns = vars(sleep_rem),\n left = 0.1,\n right = 6.6,\n na_pass = TRUE\n ) %>%\n # Expect that column `sleep_cycle` is of type: numeric\n col_is_numeric(\n columns = vars(sleep_cycle)\n ) %>%\n # Expect that values in `sleep_cycle` should be between `0.116666667` and `1.5`\n col_vals_between(\n columns = vars(sleep_cycle),\n left = 0.1166667,\n right = 1.5,\n na_pass = TRUE\n ) %>%\n # Expect that column `awake` is of type: numeric\n col_is_numeric(\n columns = vars(awake)\n ) %>%\n # Expect that values in `awake` should be between `4.1` and `22.1`\n col_vals_between(\n columns = vars(awake),\n left = 4.1,\n right = 22.1\n ) %>%\n # Expect that column `brainwt` is of type: numeric\n col_is_numeric(\n columns = vars(brainwt)\n ) %>%\n # Expect that values in `brainwt` should be between `0.00014` and `5.712`\n col_vals_between(\n columns = vars(brainwt),\n left = 0.00014,\n right = 5.712,\n na_pass = TRUE\n ) %>%\n # Expect that column `bodywt` is of type: numeric\n col_is_numeric(\n columns = vars(bodywt)\n ) %>%\n # Expect that values in `bodywt` should be between `0.005` and `6654`\n col_vals_between(\n columns = vars(bodywt),\n left = 0.005,\n right = 6654\n ) %>%\n # Expect entirely distinct rows across all columns\n rows_distinct() %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n name = \"character\",\n genus = \"character\",\n vore = \"character\",\n order = \"character\",\n conservation = \"character\",\n sleep_total = \"numeric\",\n sleep_rem = \"numeric\",\n sleep_cycle = \"numeric\",\n awake = \"numeric\",\n brainwt = \"numeric\",\n bodywt = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `name` is of type: character\n col_is_character(\n columns = c(\"name\")\n ) %>%\n # Expect that column `genus` is of type: character\n col_is_character(\n columns = c(\"genus\")\n ) %>%\n # Expect that column `vore` is of type: character\n col_is_character(\n columns = c(\"vore\")\n ) %>%\n # Expect that column `order` is of type: character\n col_is_character(\n columns = c(\"order\")\n ) %>%\n # Expect that column `conservation` is of type: character\n col_is_character(\n columns = c(\"conservation\")\n ) %>%\n # Expect that column `sleep_total` is of type: numeric\n col_is_numeric(\n columns = c(\"sleep_total\")\n ) %>%\n # Expect that values in `sleep_total` should be between `1.9` and `19.9`\n col_vals_between(\n columns = c(\"sleep_total\"),\n left = 1.9,\n right = 19.9\n ) %>%\n # Expect that column `sleep_rem` is of type: numeric\n col_is_numeric(\n columns = c(\"sleep_rem\")\n ) %>%\n # Expect that values in `sleep_rem` should be between `0.1` and `6.6`\n col_vals_between(\n columns = c(\"sleep_rem\"),\n left = 0.1,\n right = 6.6,\n na_pass = TRUE\n ) %>%\n # Expect that column `sleep_cycle` is of type: numeric\n col_is_numeric(\n columns = c(\"sleep_cycle\")\n ) %>%\n # Expect that values in `sleep_cycle` should be between `0.116666667` and `1.5`\n col_vals_between(\n columns = c(\"sleep_cycle\"),\n left = 0.1166667,\n right = 1.5,\n na_pass = TRUE\n ) %>%\n # Expect that column `awake` is of type: numeric\n col_is_numeric(\n columns = c(\"awake\")\n ) %>%\n # Expect that values in `awake` should be between `4.1` and `22.1`\n col_vals_between(\n columns = c(\"awake\"),\n left = 4.1,\n right = 22.1\n ) %>%\n # Expect that column `brainwt` is of type: numeric\n col_is_numeric(\n columns = c(\"brainwt\")\n ) %>%\n # Expect that values in `brainwt` should be between `0.00014` and `5.712`\n col_vals_between(\n columns = c(\"brainwt\"),\n left = 0.00014,\n right = 5.712,\n na_pass = TRUE\n ) %>%\n # Expect that column `bodywt` is of type: numeric\n col_is_numeric(\n columns = c(\"bodywt\")\n ) %>%\n # Expect that values in `bodywt` should be between `0.005` and `6654`\n col_vals_between(\n columns = c(\"bodywt\"),\n left = 0.005,\n right = 6654\n ) %>%\n # Expect entirely distinct rows across `name, genus, vore, order, conservation, sleep_total, sleep_rem, sleep_cycle, awake, brainwt, bodywt`\n rows_distinct(\n columns = c(\"name\", \"genus\", \"vore\", \"order\", \"conservation\", \"sleep_total\", \"sleep_rem\", \"sleep_cycle\", \"awake\", \"brainwt\", \"bodywt\")\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n name = \"character\",\n genus = \"character\",\n vore = \"character\",\n order = \"character\",\n conservation = \"character\",\n sleep_total = \"numeric\",\n sleep_rem = \"numeric\",\n sleep_cycle = \"numeric\",\n awake = \"numeric\",\n brainwt = \"numeric\",\n bodywt = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `name` is of type: character\n col_is_character(\n columns = vars(name)\n ) %>%\n # Expect that column `party` is of type: character\n col_is_character(\n columns = vars(party)\n ) %>%\n # Expect entirely distinct rows across all columns\n rows_distinct() %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n name = \"character\",\n start = \"Date\",\n end = \"Date\",\n party = \"character\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `name` is of type: character\n col_is_character(\n columns = c(\"name\")\n ) %>%\n # Expect that column `party` is of type: character\n col_is_character(\n columns = c(\"party\")\n ) %>%\n # Expect entirely distinct rows across `name, start, end, party`\n rows_distinct(\n columns = c(\"name\", \"start\", \"end\", \"party\")\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n name = \"character\",\n start = \"Date\",\n end = \"Date\",\n party = \"character\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `lat` is of type: numeric\n col_is_numeric(\n columns = vars(lat)\n ) %>%\n # Expect that values in `lat` should be between `-90` and `90`\n col_vals_between(\n columns = vars(lat),\n left = -90,\n right = 90\n ) %>%\n # Expect that column `long` is of type: numeric\n col_is_numeric(\n columns = vars(long)\n ) %>%\n # Expect that values in `long` should be between `-180` and `180`\n col_vals_between(\n columns = vars(long),\n left = -180,\n right = 180\n ) %>%\n # Expect that column `delta_long` is of type: numeric\n col_is_numeric(\n columns = vars(delta_long)\n ) %>%\n # Expect that values in `delta_long` should be between `-180` and `180`\n col_vals_between(\n columns = vars(delta_long),\n left = -180,\n right = 180\n ) %>%\n # Expect that column `delta_lat` is of type: numeric\n col_is_numeric(\n columns = vars(delta_lat)\n ) %>%\n # Expect that values in `delta_lat` should be between `-90` and `90`\n col_vals_between(\n columns = vars(delta_lat),\n left = -90,\n right = 90\n ) %>%\n # Expect entirely distinct rows across all columns\n rows_distinct() %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n lat = \"numeric\",\n long = \"numeric\",\n delta_long = \"numeric\",\n delta_lat = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `lat` is of type: numeric\n col_is_numeric(\n columns = c(\"lat\")\n ) %>%\n # Expect that values in `lat` should be between `-90` and `90`\n col_vals_between(\n columns = c(\"lat\"),\n left = -90,\n right = 90\n ) %>%\n # Expect that column `long` is of type: numeric\n col_is_numeric(\n columns = c(\"long\")\n ) %>%\n # Expect that values in `long` should be between `-180` and `180`\n col_vals_between(\n columns = c(\"long\"),\n left = -180,\n right = 180\n ) %>%\n # Expect that column `delta_long` is of type: numeric\n col_is_numeric(\n columns = c(\"delta_long\")\n ) %>%\n # Expect that values in `delta_long` should be between `-180` and `180`\n col_vals_between(\n columns = c(\"delta_long\"),\n left = -180,\n right = 180\n ) %>%\n # Expect that column `delta_lat` is of type: numeric\n col_is_numeric(\n columns = c(\"delta_lat\")\n ) %>%\n # Expect that values in `delta_lat` should be between `-90` and `90`\n col_vals_between(\n columns = c(\"delta_lat\"),\n left = -90,\n right = 90\n ) %>%\n # Expect entirely distinct rows across `lat, long, delta_long, delta_lat`\n rows_distinct(\n columns = c(\"lat\", \"long\", \"delta_long\", \"delta_lat\")\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n lat = \"numeric\",\n long = \"numeric\",\n delta_long = \"numeric\",\n delta_lat = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `city` is of type: character\n col_is_character(\n columns = vars(city)\n ) %>%\n # Expect that column `year` is of type: integer\n col_is_integer(\n columns = vars(year)\n ) %>%\n # Expect that values in `year` should be between `2000` and `2015`\n col_vals_between(\n columns = vars(year),\n left = 2000,\n right = 2015\n ) %>%\n # Expect that column `month` is of type: integer\n col_is_integer(\n columns = vars(month)\n ) %>%\n # Expect that values in `month` should be between `1` and `12`\n col_vals_between(\n columns = vars(month),\n left = 1,\n right = 12\n ) %>%\n # Expect that column `sales` is of type: numeric\n col_is_numeric(\n columns = vars(sales)\n ) %>%\n # Expect that values in `sales` should be between `6` and `8945`\n col_vals_between(\n columns = vars(sales),\n left = 6,\n right = 8945,\n na_pass = TRUE\n ) %>%\n # Expect that column `volume` is of type: numeric\n col_is_numeric(\n columns = vars(volume)\n ) %>%\n # Expect that values in `volume` should be between `835000` and `2568156780`\n col_vals_between(\n columns = vars(volume),\n left = 835000,\n right = 2568156800,\n na_pass = TRUE\n ) %>%\n # Expect that column `median` is of type: numeric\n col_is_numeric(\n columns = vars(median)\n ) %>%\n # Expect that values in `median` should be between `50000` and `304200`\n col_vals_between(\n columns = vars(median),\n left = 50000,\n right = 304200,\n na_pass = TRUE\n ) %>%\n # Expect that column `listings` is of type: numeric\n col_is_numeric(\n columns = vars(listings)\n ) %>%\n # Expect that values in `listings` should be between `0` and `43107`\n col_vals_between(\n columns = vars(listings),\n left = 0,\n right = 43107,\n na_pass = TRUE\n ) %>%\n # Expect that column `inventory` is of type: numeric\n col_is_numeric(\n columns = vars(inventory)\n ) %>%\n # Expect that values in `inventory` should be between `0` and `55.9`\n col_vals_between(\n columns = vars(inventory),\n left = 0,\n right = 55.9,\n na_pass = TRUE\n ) %>%\n # Expect that column `date` is of type: numeric\n col_is_numeric(\n columns = vars(date)\n ) %>%\n # Expect that values in `date` should be between `2000` and `2015.5`\n col_vals_between(\n columns = vars(date),\n left = 2000,\n right = 2015.5\n ) %>%\n # Expect entirely distinct rows across all columns\n rows_distinct() %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n city = \"character\",\n year = \"integer\",\n month = \"integer\",\n sales = \"numeric\",\n volume = \"numeric\",\n median = \"numeric\",\n listings = \"numeric\",\n inventory = \"numeric\",\n date = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `city` is of type: character\n col_is_character(\n columns = c(\"city\")\n ) %>%\n # Expect that column `year` is of type: integer\n col_is_integer(\n columns = c(\"year\")\n ) %>%\n # Expect that values in `year` should be between `2000` and `2015`\n col_vals_between(\n columns = c(\"year\"),\n left = 2000,\n right = 2015\n ) %>%\n # Expect that column `month` is of type: integer\n col_is_integer(\n columns = c(\"month\")\n ) %>%\n # Expect that values in `month` should be between `1` and `12`\n col_vals_between(\n columns = c(\"month\"),\n left = 1,\n right = 12\n ) %>%\n # Expect that column `sales` is of type: numeric\n col_is_numeric(\n columns = c(\"sales\")\n ) %>%\n # Expect that values in `sales` should be between `6` and `8945`\n col_vals_between(\n columns = c(\"sales\"),\n left = 6,\n right = 8945,\n na_pass = TRUE\n ) %>%\n # Expect that column `volume` is of type: numeric\n col_is_numeric(\n columns = c(\"volume\")\n ) %>%\n # Expect that values in `volume` should be between `835000` and `2568156780`\n col_vals_between(\n columns = c(\"volume\"),\n left = 835000,\n right = 2568156800,\n na_pass = TRUE\n ) %>%\n # Expect that column `median` is of type: numeric\n col_is_numeric(\n columns = c(\"median\")\n ) %>%\n # Expect that values in `median` should be between `50000` and `304200`\n col_vals_between(\n columns = c(\"median\"),\n left = 50000,\n right = 304200,\n na_pass = TRUE\n ) %>%\n # Expect that column `listings` is of type: numeric\n col_is_numeric(\n columns = c(\"listings\")\n ) %>%\n # Expect that values in `listings` should be between `0` and `43107`\n col_vals_between(\n columns = c(\"listings\"),\n left = 0,\n right = 43107,\n na_pass = TRUE\n ) %>%\n # Expect that column `inventory` is of type: numeric\n col_is_numeric(\n columns = c(\"inventory\")\n ) %>%\n # Expect that values in `inventory` should be between `0` and `55.9`\n col_vals_between(\n columns = c(\"inventory\"),\n left = 0,\n right = 55.9,\n na_pass = TRUE\n ) %>%\n # Expect that column `date` is of type: numeric\n col_is_numeric(\n columns = c(\"date\")\n ) %>%\n # Expect that values in `date` should be between `2000` and `2015.5`\n col_vals_between(\n columns = c(\"date\"),\n left = 2000,\n right = 2015.5\n ) %>%\n # Expect entirely distinct rows across `city, year, month, sales, volume, median, listings, inventory, date`\n rows_distinct(\n columns = c(\"city\", \"year\", \"month\", \"sales\", \"volume\", \"median\", \"listings\", \"inventory\", \"date\")\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n city = \"character\",\n year = \"integer\",\n month = \"integer\",\n sales = \"numeric\",\n volume = \"numeric\",\n median = \"numeric\",\n listings = \"numeric\",\n inventory = \"numeric\",\n date = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `name` is of type: character\n col_is_character(\n columns = vars(name)\n ) %>%\n # Expect that column `plays` is of type: character\n col_is_character(\n columns = vars(plays)\n ) %>%\n # Expect entirely distinct rows across all columns\n rows_distinct() %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n name = \"character\",\n plays = \"character\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `name` is of type: character\n col_is_character(\n columns = c(\"name\")\n ) %>%\n # Expect that column `plays` is of type: character\n col_is_character(\n columns = c(\"plays\")\n ) %>%\n # Expect entirely distinct rows across `name, plays`\n rows_distinct(\n columns = c(\"name\", \"plays\")\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n name = \"character\",\n plays = \"character\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `name` is of type: character\n col_is_character(\n columns = vars(name)\n ) %>%\n # Expect that column `band` is of type: character\n col_is_character(\n columns = vars(band)\n ) %>%\n # Expect entirely distinct rows across all columns\n rows_distinct() %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n name = \"character\",\n band = \"character\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `name` is of type: character\n col_is_character(\n columns = c(\"name\")\n ) %>%\n # Expect that column `band` is of type: character\n col_is_character(\n columns = c(\"band\")\n ) %>%\n # Expect entirely distinct rows across `name, band`\n rows_distinct(\n columns = c(\"name\", \"band\")\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n name = \"character\",\n band = \"character\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `name` is of type: character\n col_is_character(\n columns = vars(name)\n ) %>%\n # Expect that column `height` is of type: integer\n col_is_integer(\n columns = vars(height)\n ) %>%\n # Expect that values in `height` should be between `66` and `264`\n col_vals_between(\n columns = vars(height),\n left = 66,\n right = 264,\n na_pass = TRUE\n ) %>%\n # Expect that column `mass` is of type: numeric\n col_is_numeric(\n columns = vars(mass)\n ) %>%\n # Expect that values in `mass` should be between `15` and `1358`\n col_vals_between(\n columns = vars(mass),\n left = 15,\n right = 1358,\n na_pass = TRUE\n ) %>%\n # Expect that column `hair_color` is of type: character\n col_is_character(\n columns = vars(hair_color)\n ) %>%\n # Expect that column `skin_color` is of type: character\n col_is_character(\n columns = vars(skin_color)\n ) %>%\n # Expect that column `eye_color` is of type: character\n col_is_character(\n columns = vars(eye_color)\n ) %>%\n # Expect that column `birth_year` is of type: numeric\n col_is_numeric(\n columns = vars(birth_year)\n ) %>%\n # Expect that values in `birth_year` should be between `8` and `896`\n col_vals_between(\n columns = vars(birth_year),\n left = 8,\n right = 896,\n na_pass = TRUE\n ) %>%\n # Expect that column `sex` is of type: character\n col_is_character(\n columns = vars(sex)\n ) %>%\n # Expect that column `gender` is of type: character\n col_is_character(\n columns = vars(gender)\n ) %>%\n # Expect that column `homeworld` is of type: character\n col_is_character(\n columns = vars(homeworld)\n ) %>%\n # Expect that column `species` is of type: character\n col_is_character(\n columns = vars(species)\n ) %>%\n # Expect entirely distinct rows across all columns\n rows_distinct() %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n name = \"character\",\n height = \"integer\",\n mass = \"numeric\",\n hair_color = \"character\",\n skin_color = \"character\",\n eye_color = \"character\",\n birth_year = \"numeric\",\n sex = \"character\",\n gender = \"character\",\n homeworld = \"character\",\n species = \"character\",\n films = \"list\",\n vehicles = \"list\",\n starships = \"list\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `name` is of type: character\n col_is_character(\n columns = c(\"name\")\n ) %>%\n # Expect that column `height` is of type: integer\n col_is_integer(\n columns = c(\"height\")\n ) %>%\n # Expect that values in `height` should be between `66` and `264`\n col_vals_between(\n columns = c(\"height\"),\n left = 66,\n right = 264,\n na_pass = TRUE\n ) %>%\n # Expect that column `mass` is of type: numeric\n col_is_numeric(\n columns = c(\"mass\")\n ) %>%\n # Expect that values in `mass` should be between `15` and `1358`\n col_vals_between(\n columns = c(\"mass\"),\n left = 15,\n right = 1358,\n na_pass = TRUE\n ) %>%\n # Expect that column `hair_color` is of type: character\n col_is_character(\n columns = c(\"hair_color\")\n ) %>%\n # Expect that column `skin_color` is of type: character\n col_is_character(\n columns = c(\"skin_color\")\n ) %>%\n # Expect that column `eye_color` is of type: character\n col_is_character(\n columns = c(\"eye_color\")\n ) %>%\n # Expect that column `birth_year` is of type: numeric\n col_is_numeric(\n columns = c(\"birth_year\")\n ) %>%\n # Expect that values in `birth_year` should be between `8` and `896`\n col_vals_between(\n columns = c(\"birth_year\"),\n left = 8,\n right = 896,\n na_pass = TRUE\n ) %>%\n # Expect that column `sex` is of type: character\n col_is_character(\n columns = c(\"sex\")\n ) %>%\n # Expect that column `gender` is of type: character\n col_is_character(\n columns = c(\"gender\")\n ) %>%\n # Expect that column `homeworld` is of type: character\n col_is_character(\n columns = c(\"homeworld\")\n ) %>%\n # Expect that column `species` is of type: character\n col_is_character(\n columns = c(\"species\")\n ) %>%\n # Expect entirely distinct rows across `name, height, mass, hair_color, skin_color, eye_color, birth_year, sex, gender, homeworld, species, films, vehicles, starships`\n rows_distinct(\n columns = c(\"name\", \"height\", \"mass\", \"hair_color\", \"skin_color\", \"eye_color\", \"birth_year\", \"sex\", \"gender\", \"homeworld\", \"species\", \"films\", \"vehicles\", \"starships\")\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n name = \"character\",\n height = \"integer\",\n mass = \"numeric\",\n hair_color = \"character\",\n skin_color = \"character\",\n eye_color = \"character\",\n birth_year = \"numeric\",\n sex = \"character\",\n gender = \"character\",\n homeworld = \"character\",\n species = \"character\",\n films = \"list\",\n vehicles = \"list\",\n starships = \"list\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `name` is of type: character\n col_is_character(\n columns = vars(name)\n ) %>%\n # Expect that column `year` is of type: numeric\n col_is_numeric(\n columns = vars(year)\n ) %>%\n # Expect that values in `year` should be between `1975` and `2021`\n col_vals_between(\n columns = vars(year),\n left = 1975,\n right = 2021\n ) %>%\n # Expect that column `month` is of type: numeric\n col_is_numeric(\n columns = vars(month)\n ) %>%\n # Expect that values in `month` should be between `1` and `12`\n col_vals_between(\n columns = vars(month),\n left = 1,\n right = 12\n ) %>%\n # Expect that column `day` is of type: integer\n col_is_integer(\n columns = vars(day)\n ) %>%\n # Expect that values in `day` should be between `1` and `31`\n col_vals_between(\n columns = vars(day),\n left = 1,\n right = 31\n ) %>%\n # Expect that column `hour` is of type: numeric\n col_is_numeric(\n columns = vars(hour)\n ) %>%\n # Expect that values in `hour` should be between `0` and `23`\n col_vals_between(\n columns = vars(hour),\n left = 0,\n right = 23\n ) %>%\n # Expect that column `lat` is of type: numeric\n col_is_numeric(\n columns = vars(lat)\n ) %>%\n # Expect that values in `lat` should be between `-90` and `90`\n col_vals_between(\n columns = vars(lat),\n left = -90,\n right = 90\n ) %>%\n # Expect that column `long` is of type: numeric\n col_is_numeric(\n columns = vars(long)\n ) %>%\n # Expect that values in `long` should be between `-180` and `180`\n col_vals_between(\n columns = vars(long),\n left = -180,\n right = 180\n ) %>%\n # Expect that column `status` is of type: factor\n col_is_factor(\n columns = vars(status)\n ) %>%\n # Expect that column `category` is of type: numeric\n col_is_numeric(\n columns = vars(category)\n ) %>%\n # Expect that values in `category` should be between `1` and `5`\n col_vals_between(\n columns = vars(category),\n left = 1,\n right = 5,\n na_pass = TRUE\n ) %>%\n # Expect that column `wind` is of type: integer\n col_is_integer(\n columns = vars(wind)\n ) %>%\n # Expect that values in `wind` should be between `10` and `165`\n col_vals_between(\n columns = vars(wind),\n left = 10,\n right = 165\n ) %>%\n # Expect that column `pressure` is of type: integer\n col_is_integer(\n columns = vars(pressure)\n ) %>%\n # Expect that values in `pressure` should be between `882` and `1024`\n col_vals_between(\n columns = vars(pressure),\n left = 882,\n right = 1024\n ) %>%\n # Expect that column `tropicalstorm_force_diameter` is of type: integer\n col_is_integer(\n columns = vars(tropicalstorm_force_diameter)\n ) %>%\n # Expect that values in `tropicalstorm_force_diameter` should be between `0` and `1440`\n col_vals_between(\n columns = vars(tropicalstorm_force_diameter),\n left = 0,\n right = 1440,\n na_pass = TRUE\n ) %>%\n # Expect that column `hurricane_force_diameter` is of type: integer\n col_is_integer(\n columns = vars(hurricane_force_diameter)\n ) %>%\n # Expect that values in `hurricane_force_diameter` should be between `0` and `300`\n col_vals_between(\n columns = vars(hurricane_force_diameter),\n left = 0,\n right = 300,\n na_pass = TRUE\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n name = \"character\",\n year = \"numeric\",\n month = \"numeric\",\n day = \"integer\",\n hour = \"numeric\",\n lat = \"numeric\",\n long = \"numeric\",\n status = \"factor\",\n category = \"numeric\",\n wind = \"integer\",\n pressure = \"integer\",\n tropicalstorm_force_diameter = \"integer\",\n hurricane_force_diameter = \"integer\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `artist` is of type: character\n col_is_character(\n columns = c(\"artist\")\n ) %>%\n # Expect that column `track` is of type: character\n col_is_character(\n columns = c(\"track\")\n ) %>%\n # Expect that column `wk1` is of type: numeric\n col_is_numeric(\n columns = c(\"wk1\")\n ) %>%\n # Expect that values in `wk1` should be between `15` and `100`\n col_vals_between(\n columns = c(\"wk1\"),\n left = 15,\n right = 100\n ) %>%\n # Expect that column `wk2` is of type: numeric\n col_is_numeric(\n columns = c(\"wk2\")\n ) %>%\n # Expect that values in `wk2` should be between `8` and `100`\n col_vals_between(\n columns = c(\"wk2\"),\n left = 8,\n right = 100,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk3` is of type: numeric\n col_is_numeric(\n columns = c(\"wk3\")\n ) %>%\n # Expect that values in `wk3` should be between `6` and `100`\n col_vals_between(\n columns = c(\"wk3\"),\n left = 6,\n right = 100,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk4` is of type: numeric\n col_is_numeric(\n columns = c(\"wk4\")\n ) %>%\n # Expect that values in `wk4` should be between `5` and `100`\n col_vals_between(\n columns = c(\"wk4\"),\n left = 5,\n right = 100,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk5` is of type: numeric\n col_is_numeric(\n columns = c(\"wk5\")\n ) %>%\n # Expect that values in `wk5` should be between `2` and `100`\n col_vals_between(\n columns = c(\"wk5\"),\n left = 2,\n right = 100,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk6` is of type: numeric\n col_is_numeric(\n columns = c(\"wk6\")\n ) %>%\n # Expect that values in `wk6` should be between `1` and `99`\n col_vals_between(\n columns = c(\"wk6\"),\n left = 1,\n right = 99,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk7` is of type: numeric\n col_is_numeric(\n columns = c(\"wk7\")\n ) %>%\n # Expect that values in `wk7` should be between `1` and `100`\n col_vals_between(\n columns = c(\"wk7\"),\n left = 1,\n right = 100,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk8` is of type: numeric\n col_is_numeric(\n columns = c(\"wk8\")\n ) %>%\n # Expect that values in `wk8` should be between `1` and `99`\n col_vals_between(\n columns = c(\"wk8\"),\n left = 1,\n right = 99,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk9` is of type: numeric\n col_is_numeric(\n columns = c(\"wk9\")\n ) %>%\n # Expect that values in `wk9` should be between `1` and `100`\n col_vals_between(\n columns = c(\"wk9\"),\n left = 1,\n right = 100,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk10` is of type: numeric\n col_is_numeric(\n columns = c(\"wk10\")\n ) %>%\n # Expect that values in `wk10` should be between `1` and `100`\n col_vals_between(\n columns = c(\"wk10\"),\n left = 1,\n right = 100,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk11` is of type: numeric\n col_is_numeric(\n columns = c(\"wk11\")\n ) %>%\n # Expect that values in `wk11` should be between `1` and `100`\n col_vals_between(\n columns = c(\"wk11\"),\n left = 1,\n right = 100,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk12` is of type: numeric\n col_is_numeric(\n columns = c(\"wk12\")\n ) %>%\n # Expect that values in `wk12` should be between `1` and `100`\n col_vals_between(\n columns = c(\"wk12\"),\n left = 1,\n right = 100,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk13` is of type: numeric\n col_is_numeric(\n columns = c(\"wk13\")\n ) %>%\n # Expect that values in `wk13` should be between `1` and `100`\n col_vals_between(\n columns = c(\"wk13\"),\n left = 1,\n right = 100,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk14` is of type: numeric\n col_is_numeric(\n columns = c(\"wk14\")\n ) %>%\n # Expect that values in `wk14` should be between `1` and `100`\n col_vals_between(\n columns = c(\"wk14\"),\n left = 1,\n right = 100,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk15` is of type: numeric\n col_is_numeric(\n columns = c(\"wk15\")\n ) %>%\n # Expect that values in `wk15` should be between `1` and `100`\n col_vals_between(\n columns = c(\"wk15\"),\n left = 1,\n right = 100,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk16` is of type: numeric\n col_is_numeric(\n columns = c(\"wk16\")\n ) %>%\n # Expect that values in `wk16` should be between `1` and `100`\n col_vals_between(\n columns = c(\"wk16\"),\n left = 1,\n right = 100,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk17` is of type: numeric\n col_is_numeric(\n columns = c(\"wk17\")\n ) %>%\n # Expect that values in `wk17` should be between `1` and `100`\n col_vals_between(\n columns = c(\"wk17\"),\n left = 1,\n right = 100,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk18` is of type: numeric\n col_is_numeric(\n columns = c(\"wk18\")\n ) %>%\n # Expect that values in `wk18` should be between `1` and `100`\n col_vals_between(\n columns = c(\"wk18\"),\n left = 1,\n right = 100,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk19` is of type: numeric\n col_is_numeric(\n columns = c(\"wk19\")\n ) %>%\n # Expect that values in `wk19` should be between `1` and `99`\n col_vals_between(\n columns = c(\"wk19\"),\n left = 1,\n right = 99,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk20` is of type: numeric\n col_is_numeric(\n columns = c(\"wk20\")\n ) %>%\n # Expect that values in `wk20` should be between `2` and `100`\n col_vals_between(\n columns = c(\"wk20\"),\n left = 2,\n right = 100,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk21` is of type: numeric\n col_is_numeric(\n columns = c(\"wk21\")\n ) %>%\n # Expect that values in `wk21` should be between `3` and `97`\n col_vals_between(\n columns = c(\"wk21\"),\n left = 3,\n right = 97,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk22` is of type: numeric\n col_is_numeric(\n columns = c(\"wk22\")\n ) %>%\n # Expect that values in `wk22` should be between `3` and `100`\n col_vals_between(\n columns = c(\"wk22\"),\n left = 3,\n right = 100,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk23` is of type: numeric\n col_is_numeric(\n columns = c(\"wk23\")\n ) %>%\n # Expect that values in `wk23` should be between `3` and `91`\n col_vals_between(\n columns = c(\"wk23\"),\n left = 3,\n right = 91,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk24` is of type: numeric\n col_is_numeric(\n columns = c(\"wk24\")\n ) %>%\n # Expect that values in `wk24` should be between `3` and `91`\n col_vals_between(\n columns = c(\"wk24\"),\n left = 3,\n right = 91,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk25` is of type: numeric\n col_is_numeric(\n columns = c(\"wk25\")\n ) %>%\n # Expect that values in `wk25` should be between `2` and `90`\n col_vals_between(\n columns = c(\"wk25\"),\n left = 2,\n right = 90,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk26` is of type: numeric\n col_is_numeric(\n columns = c(\"wk26\")\n ) %>%\n # Expect that values in `wk26` should be between `1` and `89`\n col_vals_between(\n columns = c(\"wk26\"),\n left = 1,\n right = 89,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk27` is of type: numeric\n col_is_numeric(\n columns = c(\"wk27\")\n ) %>%\n # Expect that values in `wk27` should be between `1` and `86`\n col_vals_between(\n columns = c(\"wk27\"),\n left = 1,\n right = 86,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk28` is of type: numeric\n col_is_numeric(\n columns = c(\"wk28\")\n ) %>%\n # Expect that values in `wk28` should be between `2` and `58`\n col_vals_between(\n columns = c(\"wk28\"),\n left = 2,\n right = 58,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk29` is of type: numeric\n col_is_numeric(\n columns = c(\"wk29\")\n ) %>%\n # Expect that values in `wk29` should be between `2` and `49`\n col_vals_between(\n columns = c(\"wk29\"),\n left = 2,\n right = 49,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk30` is of type: numeric\n col_is_numeric(\n columns = c(\"wk30\")\n ) %>%\n # Expect that values in `wk30` should be between `2` and `45`\n col_vals_between(\n columns = c(\"wk30\"),\n left = 2,\n right = 45,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk31` is of type: numeric\n col_is_numeric(\n columns = c(\"wk31\")\n ) %>%\n # Expect that values in `wk31` should be between `3` and `49`\n col_vals_between(\n columns = c(\"wk31\"),\n left = 3,\n right = 49,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk32` is of type: numeric\n col_is_numeric(\n columns = c(\"wk32\")\n ) %>%\n # Expect that values in `wk32` should be between `3` and `47`\n col_vals_between(\n columns = c(\"wk32\"),\n left = 3,\n right = 47,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk33` is of type: numeric\n col_is_numeric(\n columns = c(\"wk33\")\n ) %>%\n # Expect that values in `wk33` should be between `2` and `50`\n col_vals_between(\n columns = c(\"wk33\"),\n left = 2,\n right = 50,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk34` is of type: numeric\n col_is_numeric(\n columns = c(\"wk34\")\n ) %>%\n # Expect that values in `wk34` should be between `3` and `49`\n col_vals_between(\n columns = c(\"wk34\"),\n left = 3,\n right = 49,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk35` is of type: numeric\n col_is_numeric(\n columns = c(\"wk35\")\n ) %>%\n # Expect that values in `wk35` should be between `4` and `34`\n col_vals_between(\n columns = c(\"wk35\"),\n left = 4,\n right = 34,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk36` is of type: numeric\n col_is_numeric(\n columns = c(\"wk36\")\n ) %>%\n # Expect that values in `wk36` should be between `5` and `41`\n col_vals_between(\n columns = c(\"wk36\"),\n left = 5,\n right = 41,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk37` is of type: numeric\n col_is_numeric(\n columns = c(\"wk37\")\n ) %>%\n # Expect that values in `wk37` should be between `5` and `48`\n col_vals_between(\n columns = c(\"wk37\"),\n left = 5,\n right = 48,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk38` is of type: numeric\n col_is_numeric(\n columns = c(\"wk38\")\n ) %>%\n # Expect that values in `wk38` should be between `9` and `40`\n col_vals_between(\n columns = c(\"wk38\"),\n left = 9,\n right = 40,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk39` is of type: numeric\n col_is_numeric(\n columns = c(\"wk39\")\n ) %>%\n # Expect that values in `wk39` should be between `3` and `50`\n col_vals_between(\n columns = c(\"wk39\"),\n left = 3,\n right = 50,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk40` is of type: numeric\n col_is_numeric(\n columns = c(\"wk40\")\n ) %>%\n # Expect that values in `wk40` should be between `1` and `47`\n col_vals_between(\n columns = c(\"wk40\"),\n left = 1,\n right = 47,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk41` is of type: numeric\n col_is_numeric(\n columns = c(\"wk41\")\n ) %>%\n # Expect that values in `wk41` should be between `1` and `50`\n col_vals_between(\n columns = c(\"wk41\"),\n left = 1,\n right = 50,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk42` is of type: numeric\n col_is_numeric(\n columns = c(\"wk42\")\n ) %>%\n # Expect that values in `wk42` should be between `2` and `22`\n col_vals_between(\n columns = c(\"wk42\"),\n left = 2,\n right = 22,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk43` is of type: numeric\n col_is_numeric(\n columns = c(\"wk43\")\n ) %>%\n # Expect that values in `wk43` should be between `3` and `32`\n col_vals_between(\n columns = c(\"wk43\"),\n left = 3,\n right = 32,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk44` is of type: numeric\n col_is_numeric(\n columns = c(\"wk44\")\n ) %>%\n # Expect that values in `wk44` should be between `4` and `45`\n col_vals_between(\n columns = c(\"wk44\"),\n left = 4,\n right = 45,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk45` is of type: numeric\n col_is_numeric(\n columns = c(\"wk45\")\n ) %>%\n # Expect that values in `wk45` should be between `4` and `31`\n col_vals_between(\n columns = c(\"wk45\"),\n left = 4,\n right = 31,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk46` is of type: numeric\n col_is_numeric(\n columns = c(\"wk46\")\n ) %>%\n # Expect that values in `wk46` should be between `5` and `37`\n col_vals_between(\n columns = c(\"wk46\"),\n left = 5,\n right = 37,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk47` is of type: numeric\n col_is_numeric(\n columns = c(\"wk47\")\n ) %>%\n # Expect that values in `wk47` should be between `6` and `41`\n col_vals_between(\n columns = c(\"wk47\"),\n left = 6,\n right = 41,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk48` is of type: numeric\n col_is_numeric(\n columns = c(\"wk48\")\n ) %>%\n # Expect that values in `wk48` should be between `8` and `39`\n col_vals_between(\n columns = c(\"wk48\"),\n left = 8,\n right = 39,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk49` is of type: numeric\n col_is_numeric(\n columns = c(\"wk49\")\n ) %>%\n # Expect that values in `wk49` should be between `9` and `42`\n col_vals_between(\n columns = c(\"wk49\"),\n left = 9,\n right = 42,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk50` is of type: numeric\n col_is_numeric(\n columns = c(\"wk50\")\n ) %>%\n # Expect that values in `wk50` should be between `10` and `49`\n col_vals_between(\n columns = c(\"wk50\"),\n left = 10,\n right = 49,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk51` is of type: numeric\n col_is_numeric(\n columns = c(\"wk51\")\n ) %>%\n # Expect that values in `wk51` should be between `12` and `49`\n col_vals_between(\n columns = c(\"wk51\"),\n left = 12,\n right = 49,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk52` is of type: numeric\n col_is_numeric(\n columns = c(\"wk52\")\n ) %>%\n # Expect that values in `wk52` should be between `15` and `48`\n col_vals_between(\n columns = c(\"wk52\"),\n left = 15,\n right = 48,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk53` is of type: numeric\n col_is_numeric(\n columns = c(\"wk53\")\n ) %>%\n # Expect that values in `wk53` should be between `17` and `49`\n col_vals_between(\n columns = c(\"wk53\"),\n left = 17,\n right = 49,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk54` is of type: numeric\n col_is_numeric(\n columns = c(\"wk54\")\n ) %>%\n # Expect that values in `wk54` should be between `17` and `22`\n col_vals_between(\n columns = c(\"wk54\"),\n left = 17,\n right = 22,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk55` is of type: numeric\n col_is_numeric(\n columns = c(\"wk55\")\n ) %>%\n # Expect that values in `wk55` should be between `21` and `22`\n col_vals_between(\n columns = c(\"wk55\"),\n left = 21,\n right = 22,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk56` is of type: numeric\n col_is_numeric(\n columns = c(\"wk56\")\n ) %>%\n # Expect that values in `wk56` should be between `25` and `26`\n col_vals_between(\n columns = c(\"wk56\"),\n left = 25,\n right = 26,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk57` is of type: numeric\n col_is_numeric(\n columns = c(\"wk57\")\n ) %>%\n # Expect that values in `wk57` should be between `26` and `29`\n col_vals_between(\n columns = c(\"wk57\"),\n left = 26,\n right = 29,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk58` is of type: numeric\n col_is_numeric(\n columns = c(\"wk58\")\n ) %>%\n # Expect that values in `wk58` should be between `31` and `32`\n col_vals_between(\n columns = c(\"wk58\"),\n left = 31,\n right = 32,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk59` is of type: numeric\n col_is_numeric(\n columns = c(\"wk59\")\n ) %>%\n # Expect that values in `wk59` should be between `32` and `39`\n col_vals_between(\n columns = c(\"wk59\"),\n left = 32,\n right = 39,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk60` is of type: numeric\n col_is_numeric(\n columns = c(\"wk60\")\n ) %>%\n # Expect that values in `wk60` should be between `37` and `39`\n col_vals_between(\n columns = c(\"wk60\"),\n left = 37,\n right = 39,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk61` is of type: numeric\n col_is_numeric(\n columns = c(\"wk61\")\n ) %>%\n # Expect that values in `wk61` should be between `42` and `43`\n col_vals_between(\n columns = c(\"wk61\"),\n left = 42,\n right = 43,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk62` is of type: numeric\n col_is_numeric(\n columns = c(\"wk62\")\n ) %>%\n # Expect that values in `wk62` should be between `42` and `47`\n col_vals_between(\n columns = c(\"wk62\"),\n left = 42,\n right = 47,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk63` is of type: numeric\n col_is_numeric(\n columns = c(\"wk63\")\n ) %>%\n # Expect that values in `wk63` should be between `45` and `50`\n col_vals_between(\n columns = c(\"wk63\"),\n left = 45,\n right = 50,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk64` is of type: numeric\n col_is_numeric(\n columns = c(\"wk64\")\n ) %>%\n # Expect that values in `wk64` should be between `50` and `50`\n col_vals_between(\n columns = c(\"wk64\"),\n left = 50,\n right = 50,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk65` is of type: numeric\n col_is_numeric(\n columns = c(\"wk65\")\n ) %>%\n # Expect that values in `wk65` should be between `49` and `49`\n col_vals_between(\n columns = c(\"wk65\"),\n left = 49,\n right = 49,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk66` is of type: logical\n col_is_logical(\n columns = c(\"wk66\")\n ) %>%\n # Expect that column `wk67` is of type: logical\n col_is_logical(\n columns = c(\"wk67\")\n ) %>%\n # Expect that column `wk68` is of type: logical\n col_is_logical(\n columns = c(\"wk68\")\n ) %>%\n # Expect that column `wk69` is of type: logical\n col_is_logical(\n columns = c(\"wk69\")\n ) %>%\n # Expect that column `wk70` is of type: logical\n col_is_logical(\n columns = c(\"wk70\")\n ) %>%\n # Expect that column `wk71` is of type: logical\n col_is_logical(\n columns = c(\"wk71\")\n ) %>%\n # Expect that column `wk72` is of type: logical\n col_is_logical(\n columns = c(\"wk72\")\n ) %>%\n # Expect that column `wk73` is of type: logical\n col_is_logical(\n columns = c(\"wk73\")\n ) %>%\n # Expect that column `wk74` is of type: logical\n col_is_logical(\n columns = c(\"wk74\")\n ) %>%\n # Expect that column `wk75` is of type: logical\n col_is_logical(\n columns = c(\"wk75\")\n ) %>%\n # Expect that column `wk76` is of type: logical\n col_is_logical(\n columns = c(\"wk76\")\n ) %>%\n # Expect entirely distinct rows across `artist, track, date.entered, wk1, wk2, wk3, wk4, wk5, wk6, wk7, wk8, wk9, wk10, wk11, wk12, wk13, wk14, wk15, wk16, wk17, wk18, wk19, wk20, wk21, wk22, wk23, wk24, wk25, wk26, wk27, wk28, wk29, wk30, wk31, wk32, wk33, wk34, wk35, wk36, wk37, wk38, wk39, wk40, wk41, wk42, wk43, wk44, wk45, wk46, wk47, wk48, wk49, wk50, wk51, wk52, wk53, wk54, wk55, wk56, wk57, wk58, wk59, wk60, wk61, wk62, wk63, wk64, wk65, wk66, wk67, wk68, wk69, wk70, wk71, wk72, wk73, wk74, wk75, wk76`\n rows_distinct(\n columns = c(\"artist\", \"track\", \"date.entered\", \"wk1\", \"wk2\", \"wk3\", \"wk4\", \"wk5\", \"wk6\", \"wk7\", \"wk8\", \"wk9\", \"wk10\", \"wk11\", \"wk12\", \"wk13\", \"wk14\", \"wk15\", \"wk16\", \"wk17\", \"wk18\", \"wk19\", \"wk20\", \"wk21\", \"wk22\", \"wk23\", \"wk24\", \"wk25\", \"wk26\", \"wk27\", \"wk28\", \"wk29\", \"wk30\", \"wk31\", \"wk32\", \"wk33\", \"wk34\", \"wk35\", \"wk36\", \"wk37\", \"wk38\", \"wk39\", \"wk40\", \"wk41\", \"wk42\", \"wk43\", \"wk44\", \"wk45\", \"wk46\", \"wk47\", \"wk48\", \"wk49\", \"wk50\", \"wk51\", \"wk52\", \"wk53\", \"wk54\", \"wk55\", \"wk56\", \"wk57\", \"wk58\", \"wk59\", \"wk60\", \"wk61\", \"wk62\", \"wk63\", \"wk64\", \"wk65\", \"wk66\", \"wk67\", \"wk68\", \"wk69\", \"wk70\", \"wk71\", \"wk72\", \"wk73\", \"wk74\", \"wk75\", \"wk76\")\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n artist = \"character\",\n track = \"character\",\n date.entered = \"Date\",\n wk1 = \"numeric\",\n wk2 = \"numeric\",\n wk3 = \"numeric\",\n wk4 = \"numeric\",\n wk5 = \"numeric\",\n wk6 = \"numeric\",\n wk7 = \"numeric\",\n wk8 = \"numeric\",\n wk9 = \"numeric\",\n wk10 = \"numeric\",\n wk11 = \"numeric\",\n wk12 = \"numeric\",\n wk13 = \"numeric\",\n wk14 = \"numeric\",\n wk15 = \"numeric\",\n wk16 = \"numeric\",\n wk17 = \"numeric\",\n wk18 = \"numeric\",\n wk19 = \"numeric\",\n wk20 = \"numeric\",\n wk21 = \"numeric\",\n wk22 = \"numeric\",\n wk23 = \"numeric\",\n wk24 = \"numeric\",\n wk25 = \"numeric\",\n wk26 = \"numeric\",\n wk27 = \"numeric\",\n wk28 = \"numeric\",\n wk29 = \"numeric\",\n wk30 = \"numeric\",\n wk31 = \"numeric\",\n wk32 = \"numeric\",\n wk33 = \"numeric\",\n wk34 = \"numeric\",\n wk35 = \"numeric\",\n wk36 = \"numeric\",\n wk37 = \"numeric\",\n wk38 = \"numeric\",\n wk39 = \"numeric\",\n wk40 = \"numeric\",\n wk41 = \"numeric\",\n wk42 = \"numeric\",\n wk43 = \"numeric\",\n wk44 = \"numeric\",\n wk45 = \"numeric\",\n wk46 = \"numeric\",\n wk47 = \"numeric\",\n wk48 = \"numeric\",\n wk49 = \"numeric\",\n wk50 = \"numeric\",\n wk51 = \"numeric\",\n wk52 = \"numeric\",\n wk53 = \"numeric\",\n wk54 = \"numeric\",\n wk55 = \"numeric\",\n wk56 = \"numeric\",\n wk57 = \"numeric\",\n wk58 = \"numeric\",\n wk59 = \"numeric\",\n wk60 = \"numeric\",\n wk61 = \"numeric\",\n wk62 = \"numeric\",\n wk63 = \"numeric\",\n wk64 = \"numeric\",\n wk65 = \"numeric\",\n wk66 = \"logical\",\n wk67 = \"logical\",\n wk68 = \"logical\",\n wk69 = \"logical\",\n wk70 = \"logical\",\n wk71 = \"logical\",\n wk72 = \"logical\",\n wk73 = \"logical\",\n wk74 = \"logical\",\n wk75 = \"logical\",\n wk76 = \"logical\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `artist` is of type: character\n col_is_character(\n columns = vars(artist)\n ) %>%\n # Expect that column `track` is of type: character\n col_is_character(\n columns = vars(track)\n ) %>%\n # Expect that column `wk1` is of type: numeric\n col_is_numeric(\n columns = vars(wk1)\n ) %>%\n # Expect that values in `wk1` should be between `15` and `100`\n col_vals_between(\n columns = vars(wk1),\n left = 15,\n right = 100\n ) %>%\n # Expect that column `wk2` is of type: numeric\n col_is_numeric(\n columns = vars(wk2)\n ) %>%\n # Expect that values in `wk2` should be between `8` and `100`\n col_vals_between(\n columns = vars(wk2),\n left = 8,\n right = 100,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk3` is of type: numeric\n col_is_numeric(\n columns = vars(wk3)\n ) %>%\n # Expect that values in `wk3` should be between `6` and `100`\n col_vals_between(\n columns = vars(wk3),\n left = 6,\n right = 100,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk4` is of type: numeric\n col_is_numeric(\n columns = vars(wk4)\n ) %>%\n # Expect that values in `wk4` should be between `5` and `100`\n col_vals_between(\n columns = vars(wk4),\n left = 5,\n right = 100,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk5` is of type: numeric\n col_is_numeric(\n columns = vars(wk5)\n ) %>%\n # Expect that values in `wk5` should be between `2` and `100`\n col_vals_between(\n columns = vars(wk5),\n left = 2,\n right = 100,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk6` is of type: numeric\n col_is_numeric(\n columns = vars(wk6)\n ) %>%\n # Expect that values in `wk6` should be between `1` and `99`\n col_vals_between(\n columns = vars(wk6),\n left = 1,\n right = 99,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk7` is of type: numeric\n col_is_numeric(\n columns = vars(wk7)\n ) %>%\n # Expect that values in `wk7` should be between `1` and `100`\n col_vals_between(\n columns = vars(wk7),\n left = 1,\n right = 100,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk8` is of type: numeric\n col_is_numeric(\n columns = vars(wk8)\n ) %>%\n # Expect that values in `wk8` should be between `1` and `99`\n col_vals_between(\n columns = vars(wk8),\n left = 1,\n right = 99,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk9` is of type: numeric\n col_is_numeric(\n columns = vars(wk9)\n ) %>%\n # Expect that values in `wk9` should be between `1` and `100`\n col_vals_between(\n columns = vars(wk9),\n left = 1,\n right = 100,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk10` is of type: numeric\n col_is_numeric(\n columns = vars(wk10)\n ) %>%\n # Expect that values in `wk10` should be between `1` and `100`\n col_vals_between(\n columns = vars(wk10),\n left = 1,\n right = 100,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk11` is of type: numeric\n col_is_numeric(\n columns = vars(wk11)\n ) %>%\n # Expect that values in `wk11` should be between `1` and `100`\n col_vals_between(\n columns = vars(wk11),\n left = 1,\n right = 100,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk12` is of type: numeric\n col_is_numeric(\n columns = vars(wk12)\n ) %>%\n # Expect that values in `wk12` should be between `1` and `100`\n col_vals_between(\n columns = vars(wk12),\n left = 1,\n right = 100,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk13` is of type: numeric\n col_is_numeric(\n columns = vars(wk13)\n ) %>%\n # Expect that values in `wk13` should be between `1` and `100`\n col_vals_between(\n columns = vars(wk13),\n left = 1,\n right = 100,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk14` is of type: numeric\n col_is_numeric(\n columns = vars(wk14)\n ) %>%\n # Expect that values in `wk14` should be between `1` and `100`\n col_vals_between(\n columns = vars(wk14),\n left = 1,\n right = 100,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk15` is of type: numeric\n col_is_numeric(\n columns = vars(wk15)\n ) %>%\n # Expect that values in `wk15` should be between `1` and `100`\n col_vals_between(\n columns = vars(wk15),\n left = 1,\n right = 100,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk16` is of type: numeric\n col_is_numeric(\n columns = vars(wk16)\n ) %>%\n # Expect that values in `wk16` should be between `1` and `100`\n col_vals_between(\n columns = vars(wk16),\n left = 1,\n right = 100,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk17` is of type: numeric\n col_is_numeric(\n columns = vars(wk17)\n ) %>%\n # Expect that values in `wk17` should be between `1` and `100`\n col_vals_between(\n columns = vars(wk17),\n left = 1,\n right = 100,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk18` is of type: numeric\n col_is_numeric(\n columns = vars(wk18)\n ) %>%\n # Expect that values in `wk18` should be between `1` and `100`\n col_vals_between(\n columns = vars(wk18),\n left = 1,\n right = 100,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk19` is of type: numeric\n col_is_numeric(\n columns = vars(wk19)\n ) %>%\n # Expect that values in `wk19` should be between `1` and `99`\n col_vals_between(\n columns = vars(wk19),\n left = 1,\n right = 99,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk20` is of type: numeric\n col_is_numeric(\n columns = vars(wk20)\n ) %>%\n # Expect that values in `wk20` should be between `2` and `100`\n col_vals_between(\n columns = vars(wk20),\n left = 2,\n right = 100,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk21` is of type: numeric\n col_is_numeric(\n columns = vars(wk21)\n ) %>%\n # Expect that values in `wk21` should be between `3` and `97`\n col_vals_between(\n columns = vars(wk21),\n left = 3,\n right = 97,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk22` is of type: numeric\n col_is_numeric(\n columns = vars(wk22)\n ) %>%\n # Expect that values in `wk22` should be between `3` and `100`\n col_vals_between(\n columns = vars(wk22),\n left = 3,\n right = 100,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk23` is of type: numeric\n col_is_numeric(\n columns = vars(wk23)\n ) %>%\n # Expect that values in `wk23` should be between `3` and `91`\n col_vals_between(\n columns = vars(wk23),\n left = 3,\n right = 91,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk24` is of type: numeric\n col_is_numeric(\n columns = vars(wk24)\n ) %>%\n # Expect that values in `wk24` should be between `3` and `91`\n col_vals_between(\n columns = vars(wk24),\n left = 3,\n right = 91,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk25` is of type: numeric\n col_is_numeric(\n columns = vars(wk25)\n ) %>%\n # Expect that values in `wk25` should be between `2` and `90`\n col_vals_between(\n columns = vars(wk25),\n left = 2,\n right = 90,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk26` is of type: numeric\n col_is_numeric(\n columns = vars(wk26)\n ) %>%\n # Expect that values in `wk26` should be between `1` and `89`\n col_vals_between(\n columns = vars(wk26),\n left = 1,\n right = 89,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk27` is of type: numeric\n col_is_numeric(\n columns = vars(wk27)\n ) %>%\n # Expect that values in `wk27` should be between `1` and `86`\n col_vals_between(\n columns = vars(wk27),\n left = 1,\n right = 86,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk28` is of type: numeric\n col_is_numeric(\n columns = vars(wk28)\n ) %>%\n # Expect that values in `wk28` should be between `2` and `58`\n col_vals_between(\n columns = vars(wk28),\n left = 2,\n right = 58,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk29` is of type: numeric\n col_is_numeric(\n columns = vars(wk29)\n ) %>%\n # Expect that values in `wk29` should be between `2` and `49`\n col_vals_between(\n columns = vars(wk29),\n left = 2,\n right = 49,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk30` is of type: numeric\n col_is_numeric(\n columns = vars(wk30)\n ) %>%\n # Expect that values in `wk30` should be between `2` and `45`\n col_vals_between(\n columns = vars(wk30),\n left = 2,\n right = 45,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk31` is of type: numeric\n col_is_numeric(\n columns = vars(wk31)\n ) %>%\n # Expect that values in `wk31` should be between `3` and `49`\n col_vals_between(\n columns = vars(wk31),\n left = 3,\n right = 49,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk32` is of type: numeric\n col_is_numeric(\n columns = vars(wk32)\n ) %>%\n # Expect that values in `wk32` should be between `3` and `47`\n col_vals_between(\n columns = vars(wk32),\n left = 3,\n right = 47,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk33` is of type: numeric\n col_is_numeric(\n columns = vars(wk33)\n ) %>%\n # Expect that values in `wk33` should be between `2` and `50`\n col_vals_between(\n columns = vars(wk33),\n left = 2,\n right = 50,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk34` is of type: numeric\n col_is_numeric(\n columns = vars(wk34)\n ) %>%\n # Expect that values in `wk34` should be between `3` and `49`\n col_vals_between(\n columns = vars(wk34),\n left = 3,\n right = 49,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk35` is of type: numeric\n col_is_numeric(\n columns = vars(wk35)\n ) %>%\n # Expect that values in `wk35` should be between `4` and `34`\n col_vals_between(\n columns = vars(wk35),\n left = 4,\n right = 34,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk36` is of type: numeric\n col_is_numeric(\n columns = vars(wk36)\n ) %>%\n # Expect that values in `wk36` should be between `5` and `41`\n col_vals_between(\n columns = vars(wk36),\n left = 5,\n right = 41,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk37` is of type: numeric\n col_is_numeric(\n columns = vars(wk37)\n ) %>%\n # Expect that values in `wk37` should be between `5` and `48`\n col_vals_between(\n columns = vars(wk37),\n left = 5,\n right = 48,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk38` is of type: numeric\n col_is_numeric(\n columns = vars(wk38)\n ) %>%\n # Expect that values in `wk38` should be between `9` and `40`\n col_vals_between(\n columns = vars(wk38),\n left = 9,\n right = 40,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk39` is of type: numeric\n col_is_numeric(\n columns = vars(wk39)\n ) %>%\n # Expect that values in `wk39` should be between `3` and `50`\n col_vals_between(\n columns = vars(wk39),\n left = 3,\n right = 50,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk40` is of type: numeric\n col_is_numeric(\n columns = vars(wk40)\n ) %>%\n # Expect that values in `wk40` should be between `1` and `47`\n col_vals_between(\n columns = vars(wk40),\n left = 1,\n right = 47,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk41` is of type: numeric\n col_is_numeric(\n columns = vars(wk41)\n ) %>%\n # Expect that values in `wk41` should be between `1` and `50`\n col_vals_between(\n columns = vars(wk41),\n left = 1,\n right = 50,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk42` is of type: numeric\n col_is_numeric(\n columns = vars(wk42)\n ) %>%\n # Expect that values in `wk42` should be between `2` and `22`\n col_vals_between(\n columns = vars(wk42),\n left = 2,\n right = 22,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk43` is of type: numeric\n col_is_numeric(\n columns = vars(wk43)\n ) %>%\n # Expect that values in `wk43` should be between `3` and `32`\n col_vals_between(\n columns = vars(wk43),\n left = 3,\n right = 32,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk44` is of type: numeric\n col_is_numeric(\n columns = vars(wk44)\n ) %>%\n # Expect that values in `wk44` should be between `4` and `45`\n col_vals_between(\n columns = vars(wk44),\n left = 4,\n right = 45,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk45` is of type: numeric\n col_is_numeric(\n columns = vars(wk45)\n ) %>%\n # Expect that values in `wk45` should be between `4` and `31`\n col_vals_between(\n columns = vars(wk45),\n left = 4,\n right = 31,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk46` is of type: numeric\n col_is_numeric(\n columns = vars(wk46)\n ) %>%\n # Expect that values in `wk46` should be between `5` and `37`\n col_vals_between(\n columns = vars(wk46),\n left = 5,\n right = 37,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk47` is of type: numeric\n col_is_numeric(\n columns = vars(wk47)\n ) %>%\n # Expect that values in `wk47` should be between `6` and `41`\n col_vals_between(\n columns = vars(wk47),\n left = 6,\n right = 41,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk48` is of type: numeric\n col_is_numeric(\n columns = vars(wk48)\n ) %>%\n # Expect that values in `wk48` should be between `8` and `39`\n col_vals_between(\n columns = vars(wk48),\n left = 8,\n right = 39,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk49` is of type: numeric\n col_is_numeric(\n columns = vars(wk49)\n ) %>%\n # Expect that values in `wk49` should be between `9` and `42`\n col_vals_between(\n columns = vars(wk49),\n left = 9,\n right = 42,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk50` is of type: numeric\n col_is_numeric(\n columns = vars(wk50)\n ) %>%\n # Expect that values in `wk50` should be between `10` and `49`\n col_vals_between(\n columns = vars(wk50),\n left = 10,\n right = 49,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk51` is of type: numeric\n col_is_numeric(\n columns = vars(wk51)\n ) %>%\n # Expect that values in `wk51` should be between `12` and `49`\n col_vals_between(\n columns = vars(wk51),\n left = 12,\n right = 49,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk52` is of type: numeric\n col_is_numeric(\n columns = vars(wk52)\n ) %>%\n # Expect that values in `wk52` should be between `15` and `48`\n col_vals_between(\n columns = vars(wk52),\n left = 15,\n right = 48,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk53` is of type: numeric\n col_is_numeric(\n columns = vars(wk53)\n ) %>%\n # Expect that values in `wk53` should be between `17` and `49`\n col_vals_between(\n columns = vars(wk53),\n left = 17,\n right = 49,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk54` is of type: numeric\n col_is_numeric(\n columns = vars(wk54)\n ) %>%\n # Expect that values in `wk54` should be between `17` and `22`\n col_vals_between(\n columns = vars(wk54),\n left = 17,\n right = 22,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk55` is of type: numeric\n col_is_numeric(\n columns = vars(wk55)\n ) %>%\n # Expect that values in `wk55` should be between `21` and `22`\n col_vals_between(\n columns = vars(wk55),\n left = 21,\n right = 22,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk56` is of type: numeric\n col_is_numeric(\n columns = vars(wk56)\n ) %>%\n # Expect that values in `wk56` should be between `25` and `26`\n col_vals_between(\n columns = vars(wk56),\n left = 25,\n right = 26,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk57` is of type: numeric\n col_is_numeric(\n columns = vars(wk57)\n ) %>%\n # Expect that values in `wk57` should be between `26` and `29`\n col_vals_between(\n columns = vars(wk57),\n left = 26,\n right = 29,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk58` is of type: numeric\n col_is_numeric(\n columns = vars(wk58)\n ) %>%\n # Expect that values in `wk58` should be between `31` and `32`\n col_vals_between(\n columns = vars(wk58),\n left = 31,\n right = 32,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk59` is of type: numeric\n col_is_numeric(\n columns = vars(wk59)\n ) %>%\n # Expect that values in `wk59` should be between `32` and `39`\n col_vals_between(\n columns = vars(wk59),\n left = 32,\n right = 39,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk60` is of type: numeric\n col_is_numeric(\n columns = vars(wk60)\n ) %>%\n # Expect that values in `wk60` should be between `37` and `39`\n col_vals_between(\n columns = vars(wk60),\n left = 37,\n right = 39,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk61` is of type: numeric\n col_is_numeric(\n columns = vars(wk61)\n ) %>%\n # Expect that values in `wk61` should be between `42` and `43`\n col_vals_between(\n columns = vars(wk61),\n left = 42,\n right = 43,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk62` is of type: numeric\n col_is_numeric(\n columns = vars(wk62)\n ) %>%\n # Expect that values in `wk62` should be between `42` and `47`\n col_vals_between(\n columns = vars(wk62),\n left = 42,\n right = 47,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk63` is of type: numeric\n col_is_numeric(\n columns = vars(wk63)\n ) %>%\n # Expect that values in `wk63` should be between `45` and `50`\n col_vals_between(\n columns = vars(wk63),\n left = 45,\n right = 50,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk64` is of type: numeric\n col_is_numeric(\n columns = vars(wk64)\n ) %>%\n # Expect that values in `wk64` should be between `50` and `50`\n col_vals_between(\n columns = vars(wk64),\n left = 50,\n right = 50,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk65` is of type: numeric\n col_is_numeric(\n columns = vars(wk65)\n ) %>%\n # Expect that values in `wk65` should be between `49` and `49`\n col_vals_between(\n columns = vars(wk65),\n left = 49,\n right = 49,\n na_pass = TRUE\n ) %>%\n # Expect that column `wk66` is of type: logical\n col_is_logical(\n columns = vars(wk66)\n ) %>%\n # Expect that column `wk67` is of type: logical\n col_is_logical(\n columns = vars(wk67)\n ) %>%\n # Expect that column `wk68` is of type: logical\n col_is_logical(\n columns = vars(wk68)\n ) %>%\n # Expect that column `wk69` is of type: logical\n col_is_logical(\n columns = vars(wk69)\n ) %>%\n # Expect that column `wk70` is of type: logical\n col_is_logical(\n columns = vars(wk70)\n ) %>%\n # Expect that column `wk71` is of type: logical\n col_is_logical(\n columns = vars(wk71)\n ) %>%\n # Expect that column `wk72` is of type: logical\n col_is_logical(\n columns = vars(wk72)\n ) %>%\n # Expect that column `wk73` is of type: logical\n col_is_logical(\n columns = vars(wk73)\n ) %>%\n # Expect that column `wk74` is of type: logical\n col_is_logical(\n columns = vars(wk74)\n ) %>%\n # Expect that column `wk75` is of type: logical\n col_is_logical(\n columns = vars(wk75)\n ) %>%\n # Expect that column `wk76` is of type: logical\n col_is_logical(\n columns = vars(wk76)\n ) %>%\n # Expect entirely distinct rows across all columns\n rows_distinct() %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n artist = \"character\",\n track = \"character\",\n date.entered = \"Date\",\n wk1 = \"numeric\",\n wk2 = \"numeric\",\n wk3 = \"numeric\",\n wk4 = \"numeric\",\n wk5 = \"numeric\",\n wk6 = \"numeric\",\n wk7 = \"numeric\",\n wk8 = \"numeric\",\n wk9 = \"numeric\",\n wk10 = \"numeric\",\n wk11 = \"numeric\",\n wk12 = \"numeric\",\n wk13 = \"numeric\",\n wk14 = \"numeric\",\n wk15 = \"numeric\",\n wk16 = \"numeric\",\n wk17 = \"numeric\",\n wk18 = \"numeric\",\n wk19 = \"numeric\",\n wk20 = \"numeric\",\n wk21 = \"numeric\",\n wk22 = \"numeric\",\n wk23 = \"numeric\",\n wk24 = \"numeric\",\n wk25 = \"numeric\",\n wk26 = \"numeric\",\n wk27 = \"numeric\",\n wk28 = \"numeric\",\n wk29 = \"numeric\",\n wk30 = \"numeric\",\n wk31 = \"numeric\",\n wk32 = \"numeric\",\n wk33 = \"numeric\",\n wk34 = \"numeric\",\n wk35 = \"numeric\",\n wk36 = \"numeric\",\n wk37 = \"numeric\",\n wk38 = \"numeric\",\n wk39 = \"numeric\",\n wk40 = \"numeric\",\n wk41 = \"numeric\",\n wk42 = \"numeric\",\n wk43 = \"numeric\",\n wk44 = \"numeric\",\n wk45 = \"numeric\",\n wk46 = \"numeric\",\n wk47 = \"numeric\",\n wk48 = \"numeric\",\n wk49 = \"numeric\",\n wk50 = \"numeric\",\n wk51 = \"numeric\",\n wk52 = \"numeric\",\n wk53 = \"numeric\",\n wk54 = \"numeric\",\n wk55 = \"numeric\",\n wk56 = \"numeric\",\n wk57 = \"numeric\",\n wk58 = \"numeric\",\n wk59 = \"numeric\",\n wk60 = \"numeric\",\n wk61 = \"numeric\",\n wk62 = \"numeric\",\n wk63 = \"numeric\",\n wk64 = \"numeric\",\n wk65 = \"numeric\",\n wk66 = \"logical\",\n wk67 = \"logical\",\n wk68 = \"logical\",\n wk69 = \"logical\",\n wk70 = \"logical\",\n wk71 = \"logical\",\n wk72 = \"logical\",\n wk73 = \"logical\",\n wk74 = \"logical\",\n wk75 = \"logical\",\n wk76 = \"logical\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `Year` is of type: numeric\n col_is_numeric(\n columns = c(\"Year\")\n ) %>%\n # Expect that values in `Year` should be between `2018` and `2018`\n col_vals_between(\n columns = c(\"Year\"),\n left = 2018,\n right = 2018\n ) %>%\n # Expect that column `Month` is of type: character\n col_is_character(\n columns = c(\"Month\")\n ) %>%\n # Expect that column `1 unit` is of type: numeric\n col_is_numeric(\n columns = c(\"1 unit\")\n ) %>%\n # Expect that values in `1 unit` should be between `797` and `939`\n col_vals_between(\n columns = c(\"1 unit\"),\n left = 797,\n right = 939\n ) %>%\n # Expect that column `2 to 4 units` is of type: logical\n col_is_logical(\n columns = c(\"2 to 4 units\")\n ) %>%\n # Expect that column `5 units or more` is of type: numeric\n col_is_numeric(\n columns = c(\"5 units or more\")\n ) %>%\n # Expect that values in `5 units or more` should be between `286` and `447`\n col_vals_between(\n columns = c(\"5 units or more\"),\n left = 286,\n right = 447\n ) %>%\n # Expect that column `Northeast` is of type: numeric\n col_is_numeric(\n columns = c(\"Northeast\")\n ) %>%\n # Expect that values in `Northeast` should be between `76` and `150`\n col_vals_between(\n columns = c(\"Northeast\"),\n left = 76,\n right = 150\n ) %>%\n # Expect that column `Midwest` is of type: numeric\n col_is_numeric(\n columns = c(\"Midwest\")\n ) %>%\n # Expect that values in `Midwest` should be between `154` and `205`\n col_vals_between(\n columns = c(\"Midwest\"),\n left = 154,\n right = 205\n ) %>%\n # Expect that column `South` is of type: numeric\n col_is_numeric(\n columns = c(\"South\")\n ) %>%\n # Expect that values in `South` should be between `560` and `673`\n col_vals_between(\n columns = c(\"South\"),\n left = 560,\n right = 673\n ) %>%\n # Expect that column `West` is of type: numeric\n col_is_numeric(\n columns = c(\"West\")\n ) %>%\n # Expect that values in `West` should be between `286` and `360`\n col_vals_between(\n columns = c(\"West\"),\n left = 286,\n right = 360\n ) %>%\n # Expect entirely distinct rows across `Year, Month, 1 unit, 2 to 4 units, 5 units or more, Northeast, Midwest, South, West`\n rows_distinct(\n columns = c(\"Year\", \"Month\", \"1 unit\", \"2 to 4 units\", \"5 units or more\", \"Northeast\", \"Midwest\", \"South\", \"West\")\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n Year = \"numeric\",\n Month = \"character\",\n 1 unit = \"numeric\",\n 2 to 4 units = \"logical\",\n 5 units or more = \"numeric\",\n Northeast = \"numeric\",\n Midwest = \"numeric\",\n South = \"numeric\",\n West = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `Year` is of type: numeric\n col_is_numeric(\n columns = vars(Year)\n ) %>%\n # Expect that values in `Year` should be between `2018` and `2018`\n col_vals_between(\n columns = vars(Year),\n left = 2018,\n right = 2018\n ) %>%\n # Expect that column `Month` is of type: character\n col_is_character(\n columns = vars(Month)\n ) %>%\n # Expect that column `1 unit` is of type: numeric\n col_is_numeric(\n columns = vars(1 unit)\n ) %>%\n # Expect that values in `1 unit` should be between `797` and `939`\n col_vals_between(\n columns = vars(1 unit),\n left = 797,\n right = 939\n ) %>%\n # Expect that column `2 to 4 units` is of type: logical\n col_is_logical(\n columns = vars(2 to 4 units)\n ) %>%\n # Expect that column `5 units or more` is of type: numeric\n col_is_numeric(\n columns = vars(5 units or more)\n ) %>%\n # Expect that values in `5 units or more` should be between `286` and `447`\n col_vals_between(\n columns = vars(5 units or more),\n left = 286,\n right = 447\n ) %>%\n # Expect that column `Northeast` is of type: numeric\n col_is_numeric(\n columns = vars(Northeast)\n ) %>%\n # Expect that values in `Northeast` should be between `76` and `150`\n col_vals_between(\n columns = vars(Northeast),\n left = 76,\n right = 150\n ) %>%\n # Expect that column `Midwest` is of type: numeric\n col_is_numeric(\n columns = vars(Midwest)\n ) %>%\n # Expect that values in `Midwest` should be between `154` and `205`\n col_vals_between(\n columns = vars(Midwest),\n left = 154,\n right = 205\n ) %>%\n # Expect that column `South` is of type: numeric\n col_is_numeric(\n columns = vars(South)\n ) %>%\n # Expect that values in `South` should be between `560` and `673`\n col_vals_between(\n columns = vars(South),\n left = 560,\n right = 673\n ) %>%\n # Expect that column `West` is of type: numeric\n col_is_numeric(\n columns = vars(West)\n ) %>%\n # Expect that values in `West` should be between `286` and `360`\n col_vals_between(\n columns = vars(West),\n left = 286,\n right = 360\n ) %>%\n # Expect entirely distinct rows across all columns\n rows_distinct() %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n Year = \"numeric\",\n Month = \"character\",\n 1 unit = \"numeric\",\n 2 to 4 units = \"logical\",\n 5 units or more = \"numeric\",\n Northeast = \"numeric\",\n Midwest = \"numeric\",\n South = \"numeric\",\n West = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `fish` is of type: factor\n col_is_factor(\n columns = c(\"fish\")\n ) %>%\n # Expect that column `station` is of type: factor\n col_is_factor(\n columns = c(\"station\")\n ) %>%\n # Expect that column `seen` is of type: integer\n col_is_integer(\n columns = c(\"seen\")\n ) %>%\n # Expect that values in `seen` should be between `1` and `1`\n col_vals_between(\n columns = c(\"seen\"),\n left = 1,\n right = 1\n ) %>%\n # Expect entirely distinct rows across `fish, station, seen`\n rows_distinct(\n columns = c(\"fish\", \"station\", \"seen\")\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n fish = \"factor\",\n station = \"factor\",\n seen = \"integer\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `fish` is of type: factor\n col_is_factor(\n columns = vars(fish)\n ) %>%\n # Expect that column `station` is of type: factor\n col_is_factor(\n columns = vars(station)\n ) %>%\n # Expect that column `seen` is of type: integer\n col_is_integer(\n columns = vars(seen)\n ) %>%\n # Expect that values in `seen` should be between `1` and `1`\n col_vals_between(\n columns = vars(seen),\n left = 1,\n right = 1\n ) %>%\n # Expect entirely distinct rows across all columns\n rows_distinct() %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n fish = \"factor\",\n station = \"factor\",\n seen = \"integer\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `religion` is of type: character\n col_is_character(\n columns = c(\"religion\")\n ) %>%\n # Expect that column `<$10k` is of type: numeric\n col_is_numeric(\n columns = c(\"<$10k\")\n ) %>%\n # Expect that values in `<$10k` should be between `1` and `575`\n col_vals_between(\n columns = c(\"<$10k\"),\n left = 1,\n right = 575\n ) %>%\n # Expect that column `$10-20k` is of type: numeric\n col_is_numeric(\n columns = c(\"$10-20k\")\n ) %>%\n # Expect that values in `$10-20k` should be between `2` and `869`\n col_vals_between(\n columns = c(\"$10-20k\"),\n left = 2,\n right = 869\n ) %>%\n # Expect that column `$20-30k` is of type: numeric\n col_is_numeric(\n columns = c(\"$20-30k\")\n ) %>%\n # Expect that values in `$20-30k` should be between `3` and `1064`\n col_vals_between(\n columns = c(\"$20-30k\"),\n left = 3,\n right = 1064\n ) %>%\n # Expect that column `$30-40k` is of type: numeric\n col_is_numeric(\n columns = c(\"$30-40k\")\n ) %>%\n # Expect that values in `$30-40k` should be between `4` and `982`\n col_vals_between(\n columns = c(\"$30-40k\"),\n left = 4,\n right = 982\n ) %>%\n # Expect that column `$40-50k` is of type: numeric\n col_is_numeric(\n columns = c(\"$40-50k\")\n ) %>%\n # Expect that values in `$40-50k` should be between `2` and `881`\n col_vals_between(\n columns = c(\"$40-50k\"),\n left = 2,\n right = 881\n ) %>%\n # Expect that column `$50-75k` is of type: numeric\n col_is_numeric(\n columns = c(\"$50-75k\")\n ) %>%\n # Expect that values in `$50-75k` should be between `7` and `1486`\n col_vals_between(\n columns = c(\"$50-75k\"),\n left = 7,\n right = 1486\n ) %>%\n # Expect that column `$75-100k` is of type: numeric\n col_is_numeric(\n columns = c(\"$75-100k\")\n ) %>%\n # Expect that values in `$75-100k` should be between `3` and `949`\n col_vals_between(\n columns = c(\"$75-100k\"),\n left = 3,\n right = 949\n ) %>%\n # Expect that column `$100-150k` is of type: numeric\n col_is_numeric(\n columns = c(\"$100-150k\")\n ) %>%\n # Expect that values in `$100-150k` should be between `4` and `792`\n col_vals_between(\n columns = c(\"$100-150k\"),\n left = 4,\n right = 792\n ) %>%\n # Expect that column `>150k` is of type: numeric\n col_is_numeric(\n columns = c(\">150k\")\n ) %>%\n # Expect that values in `>150k` should be between `4` and `634`\n col_vals_between(\n columns = c(\">150k\"),\n left = 4,\n right = 634\n ) %>%\n # Expect that column `Don't know/refused` is of type: numeric\n col_is_numeric(\n columns = c(\"Don't know/refused\")\n ) %>%\n # Expect that values in `Don't know/refused` should be between `8` and `1529`\n col_vals_between(\n columns = c(\"Don't know/refused\"),\n left = 8,\n right = 1529\n ) %>%\n # Expect entirely distinct rows across `religion, <$10k, $10-20k, $20-30k, $30-40k, $40-50k, $50-75k, $75-100k, $100-150k, >150k, Don't know/refused`\n rows_distinct(\n columns = c(\"religion\", \"<$10k\", \"$10-20k\", \"$20-30k\", \"$30-40k\", \"$40-50k\", \"$50-75k\", \"$75-100k\", \"$100-150k\", \">150k\", \"Don't know/refused\")\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n religion = \"character\",\n <$10k = \"numeric\",\n $10-20k = \"numeric\",\n $20-30k = \"numeric\",\n $30-40k = \"numeric\",\n $40-50k = \"numeric\",\n $50-75k = \"numeric\",\n $75-100k = \"numeric\",\n $100-150k = \"numeric\",\n >150k = \"numeric\",\n Don't know/refused = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `religion` is of type: character\n col_is_character(\n columns = vars(religion)\n ) %>%\n # Expect that column `<$10k` is of type: numeric\n col_is_numeric(\n columns = vars(<$10k)\n ) %>%\n # Expect that values in `<$10k` should be between `1` and `575`\n col_vals_between(\n columns = vars(<$10k),\n left = 1,\n right = 575\n ) %>%\n # Expect that column `$10-20k` is of type: numeric\n col_is_numeric(\n columns = vars($10-20k)\n ) %>%\n # Expect that values in `$10-20k` should be between `2` and `869`\n col_vals_between(\n columns = vars($10-20k),\n left = 2,\n right = 869\n ) %>%\n # Expect that column `$20-30k` is of type: numeric\n col_is_numeric(\n columns = vars($20-30k)\n ) %>%\n # Expect that values in `$20-30k` should be between `3` and `1064`\n col_vals_between(\n columns = vars($20-30k),\n left = 3,\n right = 1064\n ) %>%\n # Expect that column `$30-40k` is of type: numeric\n col_is_numeric(\n columns = vars($30-40k)\n ) %>%\n # Expect that values in `$30-40k` should be between `4` and `982`\n col_vals_between(\n columns = vars($30-40k),\n left = 4,\n right = 982\n ) %>%\n # Expect that column `$40-50k` is of type: numeric\n col_is_numeric(\n columns = vars($40-50k)\n ) %>%\n # Expect that values in `$40-50k` should be between `2` and `881`\n col_vals_between(\n columns = vars($40-50k),\n left = 2,\n right = 881\n ) %>%\n # Expect that column `$50-75k` is of type: numeric\n col_is_numeric(\n columns = vars($50-75k)\n ) %>%\n # Expect that values in `$50-75k` should be between `7` and `1486`\n col_vals_between(\n columns = vars($50-75k),\n left = 7,\n right = 1486\n ) %>%\n # Expect that column `$75-100k` is of type: numeric\n col_is_numeric(\n columns = vars($75-100k)\n ) %>%\n # Expect that values in `$75-100k` should be between `3` and `949`\n col_vals_between(\n columns = vars($75-100k),\n left = 3,\n right = 949\n ) %>%\n # Expect that column `$100-150k` is of type: numeric\n col_is_numeric(\n columns = vars($100-150k)\n ) %>%\n # Expect that values in `$100-150k` should be between `4` and `792`\n col_vals_between(\n columns = vars($100-150k),\n left = 4,\n right = 792\n ) %>%\n # Expect that column `>150k` is of type: numeric\n col_is_numeric(\n columns = vars(>150k)\n ) %>%\n # Expect that values in `>150k` should be between `4` and `634`\n col_vals_between(\n columns = vars(>150k),\n left = 4,\n right = 634\n ) %>%\n # Expect that column `Don't know/refused` is of type: numeric\n col_is_numeric(\n columns = vars(Don't know/refused)\n ) %>%\n # Expect that values in `Don't know/refused` should be between `8` and `1529`\n col_vals_between(\n columns = vars(Don't know/refused),\n left = 8,\n right = 1529\n ) %>%\n # Expect entirely distinct rows across all columns\n rows_distinct() %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n religion = \"character\",\n <$10k = \"numeric\",\n $10-20k = \"numeric\",\n $20-30k = \"numeric\",\n $30-40k = \"numeric\",\n $40-50k = \"numeric\",\n $50-75k = \"numeric\",\n $75-100k = \"numeric\",\n $100-150k = \"numeric\",\n >150k = \"numeric\",\n Don't know/refused = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `subject` is of type: character\n col_is_character(\n columns = c(\"subject\")\n ) %>%\n # Expect that column `time` is of type: numeric\n col_is_numeric(\n columns = c(\"time\")\n ) %>%\n # Expect that values in `time` should be between `1` and `1`\n col_vals_between(\n columns = c(\"time\"),\n left = 1,\n right = 1\n ) %>%\n # Expect that column `age` is of type: numeric\n col_is_numeric(\n columns = c(\"age\")\n ) %>%\n # Expect that values in `age` should be between `33` and `33`\n col_vals_between(\n columns = c(\"age\"),\n left = 33,\n right = 33,\n na_pass = TRUE\n ) %>%\n # Expect that column `weight` is of type: numeric\n col_is_numeric(\n columns = c(\"weight\")\n ) %>%\n # Expect that values in `weight` should be between `90` and `90`\n col_vals_between(\n columns = c(\"weight\"),\n left = 90,\n right = 90,\n na_pass = TRUE\n ) %>%\n # Expect that column `height` is of type: numeric\n col_is_numeric(\n columns = c(\"height\")\n ) %>%\n # Expect that values in `height` should be between `1.54` and `1.87`\n col_vals_between(\n columns = c(\"height\"),\n left = 1.54,\n right = 1.87\n ) %>%\n # Expect entirely distinct rows across `subject, time, age, weight, height`\n rows_distinct(\n columns = c(\"subject\", \"time\", \"age\", \"weight\", \"height\")\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n subject = \"character\",\n time = \"numeric\",\n age = \"numeric\",\n weight = \"numeric\",\n height = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `subject` is of type: character\n col_is_character(\n columns = vars(subject)\n ) %>%\n # Expect that column `time` is of type: numeric\n col_is_numeric(\n columns = vars(time)\n ) %>%\n # Expect that values in `time` should be between `1` and `1`\n col_vals_between(\n columns = vars(time),\n left = 1,\n right = 1\n ) %>%\n # Expect that column `age` is of type: numeric\n col_is_numeric(\n columns = vars(age)\n ) %>%\n # Expect that values in `age` should be between `33` and `33`\n col_vals_between(\n columns = vars(age),\n left = 33,\n right = 33,\n na_pass = TRUE\n ) %>%\n # Expect that column `weight` is of type: numeric\n col_is_numeric(\n columns = vars(weight)\n ) %>%\n # Expect that values in `weight` should be between `90` and `90`\n col_vals_between(\n columns = vars(weight),\n left = 90,\n right = 90,\n na_pass = TRUE\n ) %>%\n # Expect that column `height` is of type: numeric\n col_is_numeric(\n columns = vars(height)\n ) %>%\n # Expect that values in `height` should be between `1.54` and `1.87`\n col_vals_between(\n columns = vars(height),\n left = 1.54,\n right = 1.87\n ) %>%\n # Expect entirely distinct rows across all columns\n rows_distinct() %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n subject = \"character\",\n time = \"numeric\",\n age = \"numeric\",\n weight = \"numeric\",\n height = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `GEOID` is of type: character\n col_is_character(\n columns = c(\"GEOID\")\n ) %>%\n # Expect that column `NAME` is of type: character\n col_is_character(\n columns = c(\"NAME\")\n ) %>%\n # Expect that column `variable` is of type: character\n col_is_character(\n columns = c(\"variable\")\n ) %>%\n # Expect that column `estimate` is of type: numeric\n col_is_numeric(\n columns = c(\"estimate\")\n ) %>%\n # Expect that values in `estimate` should be between `464` and `43198`\n col_vals_between(\n columns = c(\"estimate\"),\n left = 464,\n right = 43198,\n na_pass = TRUE\n ) %>%\n # Expect that column `moe` is of type: numeric\n col_is_numeric(\n columns = c(\"moe\")\n ) %>%\n # Expect that values in `moe` should be between `2` and `681`\n col_vals_between(\n columns = c(\"moe\"),\n left = 2,\n right = 681,\n na_pass = TRUE\n ) %>%\n # Expect entirely distinct rows across `GEOID, NAME, variable, estimate, moe`\n rows_distinct(\n columns = c(\"GEOID\", \"NAME\", \"variable\", \"estimate\", \"moe\")\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n GEOID = \"character\",\n NAME = \"character\",\n variable = \"character\",\n estimate = \"numeric\",\n moe = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `GEOID` is of type: character\n col_is_character(\n columns = vars(GEOID)\n ) %>%\n # Expect that column `NAME` is of type: character\n col_is_character(\n columns = vars(NAME)\n ) %>%\n # Expect that column `variable` is of type: character\n col_is_character(\n columns = vars(variable)\n ) %>%\n # Expect that column `estimate` is of type: numeric\n col_is_numeric(\n columns = vars(estimate)\n ) %>%\n # Expect that values in `estimate` should be between `464` and `43198`\n col_vals_between(\n columns = vars(estimate),\n left = 464,\n right = 43198,\n na_pass = TRUE\n ) %>%\n # Expect that column `moe` is of type: numeric\n col_is_numeric(\n columns = vars(moe)\n ) %>%\n # Expect that values in `moe` should be between `2` and `681`\n col_vals_between(\n columns = vars(moe),\n left = 2,\n right = 681,\n na_pass = TRUE\n ) %>%\n # Expect entirely distinct rows across all columns\n rows_distinct() %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n GEOID = \"character\",\n NAME = \"character\",\n variable = \"character\",\n estimate = \"numeric\",\n moe = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `country` is of type: character\n col_is_character(\n columns = c(\"country\")\n ) %>%\n # Expect that column `indicator` is of type: character\n col_is_character(\n columns = c(\"indicator\")\n ) %>%\n # Expect that column `2000` is of type: numeric\n col_is_numeric(\n columns = c(\"2000\")\n ) %>%\n # Expect that values in `2000` should be between `-4.07538613162288` and `6144322697`\n col_vals_between(\n columns = c(\"2000\"),\n left = -4.0753861,\n right = 6144322700,\n na_pass = TRUE\n ) %>%\n # Expect that column `2001` is of type: numeric\n col_is_numeric(\n columns = c(\"2001\")\n ) %>%\n # Expect that values in `2001` should be between `-3.8476707266781` and `6226339538`\n col_vals_between(\n columns = c(\"2001\"),\n left = -3.8476707,\n right = 6226339500,\n na_pass = TRUE\n ) %>%\n # Expect that column `2002` is of type: numeric\n col_is_numeric(\n columns = c(\"2002\")\n ) %>%\n # Expect that values in `2002` should be between `-3.5058941109977` and `6308092739`\n col_vals_between(\n columns = c(\"2002\"),\n left = -3.5058941,\n right = 6308092700,\n na_pass = TRUE\n ) %>%\n # Expect that column `2003` is of type: numeric\n col_is_numeric(\n columns = c(\"2003\")\n ) %>%\n # Expect that values in `2003` should be between `-3.55055571718435` and `6389383352`\n col_vals_between(\n columns = c(\"2003\"),\n left = -3.5505557,\n right = 6389383400,\n na_pass = TRUE\n ) %>%\n # Expect that column `2004` is of type: numeric\n col_is_numeric(\n columns = c(\"2004\")\n ) %>%\n # Expect that values in `2004` should be between `-3.72003227551706` and `6470821068`\n col_vals_between(\n columns = c(\"2004\"),\n left = -3.7200323,\n right = 6470821100,\n na_pass = TRUE\n ) %>%\n # Expect that column `2005` is of type: numeric\n col_is_numeric(\n columns = c(\"2005\")\n ) %>%\n # Expect that values in `2005` should be between `-4.07796901122163` and `6552571570`\n col_vals_between(\n columns = c(\"2005\"),\n left = -4.077969,\n right = 6552571600,\n na_pass = TRUE\n ) %>%\n # Expect that column `2006` is of type: numeric\n col_is_numeric(\n columns = c(\"2006\")\n ) %>%\n # Expect that values in `2006` should be between `-4.39053378535746` and `6634935638`\n col_vals_between(\n columns = c(\"2006\"),\n left = -4.3905338,\n right = 6634935600,\n na_pass = TRUE\n ) %>%\n # Expect that column `2007` is of type: numeric\n col_is_numeric(\n columns = c(\"2007\")\n ) %>%\n # Expect that values in `2007` should be between `-4.66353575517151` and `6717641730`\n col_vals_between(\n columns = c(\"2007\"),\n left = -4.6635358,\n right = 6717641700,\n na_pass = TRUE\n ) %>%\n # Expect that column `2008` is of type: numeric\n col_is_numeric(\n columns = c(\"2008\")\n ) %>%\n # Expect that values in `2008` should be between `-4.90503090271691` and `6801408360`\n col_vals_between(\n columns = c(\"2008\"),\n left = -4.9050309,\n right = 6801408400,\n na_pass = TRUE\n ) %>%\n # Expect that column `2009` is of type: numeric\n col_is_numeric(\n columns = c(\"2009\")\n ) %>%\n # Expect that values in `2009` should be between `-5.08445117030295` and `6885490816`\n col_vals_between(\n columns = c(\"2009\"),\n left = -5.0844512,\n right = 6885490800,\n na_pass = TRUE\n ) %>%\n # Expect that column `2010` is of type: numeric\n col_is_numeric(\n columns = c(\"2010\")\n ) %>%\n # Expect that values in `2010` should be between `-5.34393804525569` and `6969631901`\n col_vals_between(\n columns = c(\"2010\"),\n left = -5.343938,\n right = 6969631900,\n na_pass = TRUE\n ) %>%\n # Expect that column `2011` is of type: numeric\n col_is_numeric(\n columns = c(\"2011\")\n ) %>%\n # Expect that values in `2011` should be between `-4.79355371289299` and `7053533350`\n col_vals_between(\n columns = c(\"2011\"),\n left = -4.7935537,\n right = 7053533400,\n na_pass = TRUE\n ) %>%\n # Expect that column `2012` is of type: numeric\n col_is_numeric(\n columns = c(\"2012\")\n ) %>%\n # Expect that values in `2012` should be between `-5.28007770057696` and `7140895722`\n col_vals_between(\n columns = c(\"2012\"),\n left = -5.2800777,\n right = 7140895700,\n na_pass = TRUE\n ) %>%\n # Expect that column `2013` is of type: numeric\n col_is_numeric(\n columns = c(\"2013\")\n ) %>%\n # Expect that values in `2013` should be between `-6.96818698489862` and `7229184551`\n col_vals_between(\n columns = c(\"2013\"),\n left = -6.968187,\n right = 7229184600,\n na_pass = TRUE\n ) %>%\n # Expect that column `2014` is of type: numeric\n col_is_numeric(\n columns = c(\"2014\")\n ) %>%\n # Expect that values in `2014` should be between `-8.83048301221807` and `7317508753`\n col_vals_between(\n columns = c(\"2014\"),\n left = -8.830483,\n right = 7317508800,\n na_pass = TRUE\n ) %>%\n # Expect that column `2015` is of type: numeric\n col_is_numeric(\n columns = c(\"2015\")\n ) %>%\n # Expect that values in `2015` should be between `-4.41574372125213` and `7404910892`\n col_vals_between(\n columns = c(\"2015\"),\n left = -4.4157437,\n right = 7404910900,\n na_pass = TRUE\n ) %>%\n # Expect that column `2016` is of type: numeric\n col_is_numeric(\n columns = c(\"2016\")\n ) %>%\n # Expect that values in `2016` should be between `-2.2172797902348` and `7491934113`\n col_vals_between(\n columns = c(\"2016\"),\n left = -2.2172798,\n right = 7491934100,\n na_pass = TRUE\n ) %>%\n # Expect that column `2017` is of type: numeric\n col_is_numeric(\n columns = c(\"2017\")\n ) %>%\n # Expect that values in `2017` should be between `-3.75548445756917` and `7578157615`\n col_vals_between(\n columns = c(\"2017\"),\n left = -3.7554845,\n right = 7578157600,\n na_pass = TRUE\n ) %>%\n # Expect entirely distinct rows across `country, indicator, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017`\n rows_distinct(\n columns = c(\"country\", \"indicator\", \"2000\", \"2001\", \"2002\", \"2003\", \"2004\", \"2005\", \"2006\", \"2007\", \"2008\", \"2009\", \"2010\", \"2011\", \"2012\", \"2013\", \"2014\", \"2015\", \"2016\", \"2017\")\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n country = \"character\",\n indicator = \"character\",\n 2000 = \"numeric\",\n 2001 = \"numeric\",\n 2002 = \"numeric\",\n 2003 = \"numeric\",\n 2004 = \"numeric\",\n 2005 = \"numeric\",\n 2006 = \"numeric\",\n 2007 = \"numeric\",\n 2008 = \"numeric\",\n 2009 = \"numeric\",\n 2010 = \"numeric\",\n 2011 = \"numeric\",\n 2012 = \"numeric\",\n 2013 = \"numeric\",\n 2014 = \"numeric\",\n 2015 = \"numeric\",\n 2016 = \"numeric\",\n 2017 = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `country` is of type: character\n col_is_character(\n columns = vars(country)\n ) %>%\n # Expect that column `indicator` is of type: character\n col_is_character(\n columns = vars(indicator)\n ) %>%\n # Expect that column `2000` is of type: numeric\n col_is_numeric(\n columns = vars(2000)\n ) %>%\n # Expect that values in `2000` should be between `-4.07538613162288` and `6144322697`\n col_vals_between(\n columns = vars(2000),\n left = -4.0753861,\n right = 6144322700,\n na_pass = TRUE\n ) %>%\n # Expect that column `2001` is of type: numeric\n col_is_numeric(\n columns = vars(2001)\n ) %>%\n # Expect that values in `2001` should be between `-3.8476707266781` and `6226339538`\n col_vals_between(\n columns = vars(2001),\n left = -3.8476707,\n right = 6226339500,\n na_pass = TRUE\n ) %>%\n # Expect that column `2002` is of type: numeric\n col_is_numeric(\n columns = vars(2002)\n ) %>%\n # Expect that values in `2002` should be between `-3.5058941109977` and `6308092739`\n col_vals_between(\n columns = vars(2002),\n left = -3.5058941,\n right = 6308092700,\n na_pass = TRUE\n ) %>%\n # Expect that column `2003` is of type: numeric\n col_is_numeric(\n columns = vars(2003)\n ) %>%\n # Expect that values in `2003` should be between `-3.55055571718435` and `6389383352`\n col_vals_between(\n columns = vars(2003),\n left = -3.5505557,\n right = 6389383400,\n na_pass = TRUE\n ) %>%\n # Expect that column `2004` is of type: numeric\n col_is_numeric(\n columns = vars(2004)\n ) %>%\n # Expect that values in `2004` should be between `-3.72003227551706` and `6470821068`\n col_vals_between(\n columns = vars(2004),\n left = -3.7200323,\n right = 6470821100,\n na_pass = TRUE\n ) %>%\n # Expect that column `2005` is of type: numeric\n col_is_numeric(\n columns = vars(2005)\n ) %>%\n # Expect that values in `2005` should be between `-4.07796901122163` and `6552571570`\n col_vals_between(\n columns = vars(2005),\n left = -4.077969,\n right = 6552571600,\n na_pass = TRUE\n ) %>%\n # Expect that column `2006` is of type: numeric\n col_is_numeric(\n columns = vars(2006)\n ) %>%\n # Expect that values in `2006` should be between `-4.39053378535746` and `6634935638`\n col_vals_between(\n columns = vars(2006),\n left = -4.3905338,\n right = 6634935600,\n na_pass = TRUE\n ) %>%\n # Expect that column `2007` is of type: numeric\n col_is_numeric(\n columns = vars(2007)\n ) %>%\n # Expect that values in `2007` should be between `-4.66353575517151` and `6717641730`\n col_vals_between(\n columns = vars(2007),\n left = -4.6635358,\n right = 6717641700,\n na_pass = TRUE\n ) %>%\n # Expect that column `2008` is of type: numeric\n col_is_numeric(\n columns = vars(2008)\n ) %>%\n # Expect that values in `2008` should be between `-4.90503090271691` and `6801408360`\n col_vals_between(\n columns = vars(2008),\n left = -4.9050309,\n right = 6801408400,\n na_pass = TRUE\n ) %>%\n # Expect that column `2009` is of type: numeric\n col_is_numeric(\n columns = vars(2009)\n ) %>%\n # Expect that values in `2009` should be between `-5.08445117030295` and `6885490816`\n col_vals_between(\n columns = vars(2009),\n left = -5.0844512,\n right = 6885490800,\n na_pass = TRUE\n ) %>%\n # Expect that column `2010` is of type: numeric\n col_is_numeric(\n columns = vars(2010)\n ) %>%\n # Expect that values in `2010` should be between `-5.34393804525569` and `6969631901`\n col_vals_between(\n columns = vars(2010),\n left = -5.343938,\n right = 6969631900,\n na_pass = TRUE\n ) %>%\n # Expect that column `2011` is of type: numeric\n col_is_numeric(\n columns = vars(2011)\n ) %>%\n # Expect that values in `2011` should be between `-4.79355371289299` and `7053533350`\n col_vals_between(\n columns = vars(2011),\n left = -4.7935537,\n right = 7053533400,\n na_pass = TRUE\n ) %>%\n # Expect that column `2012` is of type: numeric\n col_is_numeric(\n columns = vars(2012)\n ) %>%\n # Expect that values in `2012` should be between `-5.28007770057696` and `7140895722`\n col_vals_between(\n columns = vars(2012),\n left = -5.2800777,\n right = 7140895700,\n na_pass = TRUE\n ) %>%\n # Expect that column `2013` is of type: numeric\n col_is_numeric(\n columns = vars(2013)\n ) %>%\n # Expect that values in `2013` should be between `-6.96818698489862` and `7229184551`\n col_vals_between(\n columns = vars(2013),\n left = -6.968187,\n right = 7229184600,\n na_pass = TRUE\n ) %>%\n # Expect that column `2014` is of type: numeric\n col_is_numeric(\n columns = vars(2014)\n ) %>%\n # Expect that values in `2014` should be between `-8.83048301221807` and `7317508753`\n col_vals_between(\n columns = vars(2014),\n left = -8.830483,\n right = 7317508800,\n na_pass = TRUE\n ) %>%\n # Expect that column `2015` is of type: numeric\n col_is_numeric(\n columns = vars(2015)\n ) %>%\n # Expect that values in `2015` should be between `-4.41574372125213` and `7404910892`\n col_vals_between(\n columns = vars(2015),\n left = -4.4157437,\n right = 7404910900,\n na_pass = TRUE\n ) %>%\n # Expect that column `2016` is of type: numeric\n col_is_numeric(\n columns = vars(2016)\n ) %>%\n # Expect that values in `2016` should be between `-2.2172797902348` and `7491934113`\n col_vals_between(\n columns = vars(2016),\n left = -2.2172798,\n right = 7491934100,\n na_pass = TRUE\n ) %>%\n # Expect that column `2017` is of type: numeric\n col_is_numeric(\n columns = vars(2017)\n ) %>%\n # Expect that values in `2017` should be between `-3.75548445756917` and `7578157615`\n col_vals_between(\n columns = vars(2017),\n left = -3.7554845,\n right = 7578157600,\n na_pass = TRUE\n ) %>%\n # Expect entirely distinct rows across all columns\n rows_distinct() %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n country = \"character\",\n indicator = \"character\",\n 2000 = \"numeric\",\n 2001 = \"numeric\",\n 2002 = \"numeric\",\n 2003 = \"numeric\",\n 2004 = \"numeric\",\n 2005 = \"numeric\",\n 2006 = \"numeric\",\n 2007 = \"numeric\",\n 2008 = \"numeric\",\n 2009 = \"numeric\",\n 2010 = \"numeric\",\n 2011 = \"numeric\",\n 2012 = \"numeric\",\n 2013 = \"numeric\",\n 2014 = \"numeric\",\n 2015 = \"numeric\",\n 2016 = \"numeric\",\n 2017 = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `date` is of type: integer\n col_is_integer(\n columns = c(\"date\")\n ) %>%\n # Expect that values in `date` should be between `20081028` and `20090414`\n col_vals_between(\n columns = c(\"date\"),\n left = 20081028,\n right = 20090414\n ) %>%\n # Expect that column `opponent` is of type: character\n col_is_character(\n columns = c(\"opponent\")\n ) %>%\n # Expect that column `game_type` is of type: character\n col_is_character(\n columns = c(\"game_type\")\n ) %>%\n # Expect that column `time` is of type: character\n col_is_character(\n columns = c(\"time\")\n ) %>%\n # Expect that column `period` is of type: integer\n col_is_integer(\n columns = c(\"period\")\n ) %>%\n # Expect that values in `period` should be between `1` and `5`\n col_vals_between(\n columns = c(\"period\"),\n left = 1,\n right = 5\n ) %>%\n # Expect that column `etype` is of type: character\n col_is_character(\n columns = c(\"etype\")\n ) %>%\n # Expect that column `team` is of type: character\n col_is_character(\n columns = c(\"team\")\n ) %>%\n # Expect that column `player` is of type: character\n col_is_character(\n columns = c(\"player\")\n ) %>%\n # Expect that column `result` is of type: character\n col_is_character(\n columns = c(\"result\")\n ) %>%\n # Expect that column `points` is of type: integer\n col_is_integer(\n columns = c(\"points\")\n ) %>%\n # Expect that values in `points` should be between `0` and `3`\n col_vals_between(\n columns = c(\"points\"),\n left = 0,\n right = 3\n ) %>%\n # Expect that column `type` is of type: character\n col_is_character(\n columns = c(\"type\")\n ) %>%\n # Expect that column `x` is of type: integer\n col_is_integer(\n columns = c(\"x\")\n ) %>%\n # Expect that values in `x` should be between `0` and `51`\n col_vals_between(\n columns = c(\"x\"),\n left = 0,\n right = 51,\n na_pass = TRUE\n ) %>%\n # Expect that column `y` is of type: integer\n col_is_integer(\n columns = c(\"y\")\n ) %>%\n # Expect that values in `y` should be between `3` and `90`\n col_vals_between(\n columns = c(\"y\"),\n left = 3,\n right = 90,\n na_pass = TRUE\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n date = \"integer\",\n opponent = \"character\",\n game_type = \"character\",\n time = \"character\",\n period = \"integer\",\n etype = \"character\",\n team = \"character\",\n player = \"character\",\n result = \"character\",\n points = \"integer\",\n type = \"character\",\n x = \"integer\",\n y = \"integer\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `date` is of type: integer\n col_is_integer(\n columns = vars(date)\n ) %>%\n # Expect that values in `date` should be between `20081028` and `20090414`\n col_vals_between(\n columns = vars(date),\n left = 20081028,\n right = 20090414\n ) %>%\n # Expect that column `opponent` is of type: character\n col_is_character(\n columns = vars(opponent)\n ) %>%\n # Expect that column `game_type` is of type: character\n col_is_character(\n columns = vars(game_type)\n ) %>%\n # Expect that column `time` is of type: character\n col_is_character(\n columns = vars(time)\n ) %>%\n # Expect that column `period` is of type: integer\n col_is_integer(\n columns = vars(period)\n ) %>%\n # Expect that values in `period` should be between `1` and `5`\n col_vals_between(\n columns = vars(period),\n left = 1,\n right = 5\n ) %>%\n # Expect that column `etype` is of type: character\n col_is_character(\n columns = vars(etype)\n ) %>%\n # Expect that column `team` is of type: character\n col_is_character(\n columns = vars(team)\n ) %>%\n # Expect that column `player` is of type: character\n col_is_character(\n columns = vars(player)\n ) %>%\n # Expect that column `result` is of type: character\n col_is_character(\n columns = vars(result)\n ) %>%\n # Expect that column `points` is of type: integer\n col_is_integer(\n columns = vars(points)\n ) %>%\n # Expect that values in `points` should be between `0` and `3`\n col_vals_between(\n columns = vars(points),\n left = 0,\n right = 3\n ) %>%\n # Expect that column `type` is of type: character\n col_is_character(\n columns = vars(type)\n ) %>%\n # Expect that column `x` is of type: integer\n col_is_integer(\n columns = vars(x)\n ) %>%\n # Expect that values in `x` should be between `0` and `51`\n col_vals_between(\n columns = vars(x),\n left = 0,\n right = 51,\n na_pass = TRUE\n ) %>%\n # Expect that column `y` is of type: integer\n col_is_integer(\n columns = vars(y)\n ) %>%\n # Expect that values in `y` should be between `3` and `90`\n col_vals_between(\n columns = vars(y),\n left = 3,\n right = 90,\n na_pass = TRUE\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n date = \"integer\",\n opponent = \"character\",\n game_type = \"character\",\n time = \"character\",\n period = \"integer\",\n etype = \"character\",\n team = \"character\",\n player = \"character\",\n result = \"character\",\n points = \"integer\",\n type = \"character\",\n x = \"integer\",\n y = \"integer\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `Ozone` is of type: integer\n col_is_integer(\n columns = c(\"Ozone\")\n ) %>%\n # Expect that values in `Ozone` should be between `1` and `168`\n col_vals_between(\n columns = c(\"Ozone\"),\n left = 1,\n right = 168,\n na_pass = TRUE\n ) %>%\n # Expect that column `Solar.R` is of type: integer\n col_is_integer(\n columns = c(\"Solar.R\")\n ) %>%\n # Expect that values in `Solar.R` should be between `7` and `334`\n col_vals_between(\n columns = c(\"Solar.R\"),\n left = 7,\n right = 334,\n na_pass = TRUE\n ) %>%\n # Expect that column `Wind` is of type: numeric\n col_is_numeric(\n columns = c(\"Wind\")\n ) %>%\n # Expect that values in `Wind` should be between `1.7` and `20.7`\n col_vals_between(\n columns = c(\"Wind\"),\n left = 1.7,\n right = 20.7\n ) %>%\n # Expect that column `Temp` is of type: integer\n col_is_integer(\n columns = c(\"Temp\")\n ) %>%\n # Expect that values in `Temp` should be between `56` and `97`\n col_vals_between(\n columns = c(\"Temp\"),\n left = 56,\n right = 97\n ) %>%\n # Expect that column `Month` is of type: integer\n col_is_integer(\n columns = c(\"Month\")\n ) %>%\n # Expect that values in `Month` should be between `5` and `9`\n col_vals_between(\n columns = c(\"Month\"),\n left = 5,\n right = 9\n ) %>%\n # Expect that column `Day` is of type: integer\n col_is_integer(\n columns = c(\"Day\")\n ) %>%\n # Expect that values in `Day` should be between `1` and `31`\n col_vals_between(\n columns = c(\"Day\"),\n left = 1,\n right = 31\n ) %>%\n # Expect entirely distinct rows across `Ozone, Solar.R, Wind, Temp, Month, Day`\n rows_distinct(\n columns = c(\"Ozone\", \"Solar.R\", \"Wind\", \"Temp\", \"Month\", \"Day\")\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n Ozone = \"integer\",\n Solar.R = \"integer\",\n Wind = \"numeric\",\n Temp = \"integer\",\n Month = \"integer\",\n Day = \"integer\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `Ozone` is of type: integer\n col_is_integer(\n columns = vars(Ozone)\n ) %>%\n # Expect that values in `Ozone` should be between `1` and `168`\n col_vals_between(\n columns = vars(Ozone),\n left = 1,\n right = 168,\n na_pass = TRUE\n ) %>%\n # Expect that column `Solar.R` is of type: integer\n col_is_integer(\n columns = vars(Solar.R)\n ) %>%\n # Expect that values in `Solar.R` should be between `7` and `334`\n col_vals_between(\n columns = vars(Solar.R),\n left = 7,\n right = 334,\n na_pass = TRUE\n ) %>%\n # Expect that column `Wind` is of type: numeric\n col_is_numeric(\n columns = vars(Wind)\n ) %>%\n # Expect that values in `Wind` should be between `1.7` and `20.7`\n col_vals_between(\n columns = vars(Wind),\n left = 1.7,\n right = 20.7\n ) %>%\n # Expect that column `Temp` is of type: integer\n col_is_integer(\n columns = vars(Temp)\n ) %>%\n # Expect that values in `Temp` should be between `56` and `97`\n col_vals_between(\n columns = vars(Temp),\n left = 56,\n right = 97\n ) %>%\n # Expect that column `Month` is of type: integer\n col_is_integer(\n columns = vars(Month)\n ) %>%\n # Expect that values in `Month` should be between `5` and `9`\n col_vals_between(\n columns = vars(Month),\n left = 5,\n right = 9\n ) %>%\n # Expect that column `Day` is of type: integer\n col_is_integer(\n columns = vars(Day)\n ) %>%\n # Expect that values in `Day` should be between `1` and `31`\n col_vals_between(\n columns = vars(Day),\n left = 1,\n right = 31\n ) %>%\n # Expect entirely distinct rows across all columns\n rows_distinct() %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n Ozone = \"integer\",\n Solar.R = \"integer\",\n Wind = \"numeric\",\n Temp = \"integer\",\n Month = \"integer\",\n Day = \"integer\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `weight` is of type: numeric\n col_is_numeric(\n columns = c(\"weight\")\n ) %>%\n # Expect that values in `weight` should be between `108` and `423`\n col_vals_between(\n columns = c(\"weight\"),\n left = 108,\n right = 423\n ) %>%\n # Expect that column `feed` is of type: factor\n col_is_factor(\n columns = c(\"feed\")\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n weight = \"numeric\",\n feed = \"factor\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `weight` is of type: numeric\n col_is_numeric(\n columns = vars(weight)\n ) %>%\n # Expect that values in `weight` should be between `108` and `423`\n col_vals_between(\n columns = vars(weight),\n left = 108,\n right = 423\n ) %>%\n # Expect that column `feed` is of type: factor\n col_is_factor(\n columns = vars(feed)\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n weight = \"numeric\",\n feed = \"factor\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `Sepal.Length` is of type: numeric\n col_is_numeric(\n columns = c(\"Sepal.Length\")\n ) %>%\n # Expect that values in `Sepal.Length` should be between `4.3` and `7.9`\n col_vals_between(\n columns = c(\"Sepal.Length\"),\n left = 4.3,\n right = 7.9\n ) %>%\n # Expect that column `Sepal.Width` is of type: numeric\n col_is_numeric(\n columns = c(\"Sepal.Width\")\n ) %>%\n # Expect that values in `Sepal.Width` should be between `2` and `4.4`\n col_vals_between(\n columns = c(\"Sepal.Width\"),\n left = 2,\n right = 4.4\n ) %>%\n # Expect that column `Petal.Length` is of type: numeric\n col_is_numeric(\n columns = c(\"Petal.Length\")\n ) %>%\n # Expect that values in `Petal.Length` should be between `1` and `6.9`\n col_vals_between(\n columns = c(\"Petal.Length\"),\n left = 1,\n right = 6.9\n ) %>%\n # Expect that column `Petal.Width` is of type: numeric\n col_is_numeric(\n columns = c(\"Petal.Width\")\n ) %>%\n # Expect that values in `Petal.Width` should be between `0.1` and `2.5`\n col_vals_between(\n columns = c(\"Petal.Width\"),\n left = 0.1,\n right = 2.5\n ) %>%\n # Expect that column `Species` is of type: factor\n col_is_factor(\n columns = c(\"Species\")\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n Sepal.Length = \"numeric\",\n Sepal.Width = \"numeric\",\n Petal.Length = \"numeric\",\n Petal.Width = \"numeric\",\n Species = \"factor\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `Sepal.Length` is of type: numeric\n col_is_numeric(\n columns = vars(Sepal.Length)\n ) %>%\n # Expect that values in `Sepal.Length` should be between `4.3` and `7.9`\n col_vals_between(\n columns = vars(Sepal.Length),\n left = 4.3,\n right = 7.9\n ) %>%\n # Expect that column `Sepal.Width` is of type: numeric\n col_is_numeric(\n columns = vars(Sepal.Width)\n ) %>%\n # Expect that values in `Sepal.Width` should be between `2` and `4.4`\n col_vals_between(\n columns = vars(Sepal.Width),\n left = 2,\n right = 4.4\n ) %>%\n # Expect that column `Petal.Length` is of type: numeric\n col_is_numeric(\n columns = vars(Petal.Length)\n ) %>%\n # Expect that values in `Petal.Length` should be between `1` and `6.9`\n col_vals_between(\n columns = vars(Petal.Length),\n left = 1,\n right = 6.9\n ) %>%\n # Expect that column `Petal.Width` is of type: numeric\n col_is_numeric(\n columns = vars(Petal.Width)\n ) %>%\n # Expect that values in `Petal.Width` should be between `0.1` and `2.5`\n col_vals_between(\n columns = vars(Petal.Width),\n left = 0.1,\n right = 2.5\n ) %>%\n # Expect that column `Species` is of type: factor\n col_is_factor(\n columns = vars(Species)\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n Sepal.Length = \"numeric\",\n Sepal.Width = \"numeric\",\n Petal.Length = \"numeric\",\n Petal.Width = \"numeric\",\n Species = \"factor\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `sr` is of type: numeric\n col_is_numeric(\n columns = c(\"sr\")\n ) %>%\n # Expect that values in `sr` should be between `0.6` and `21.1`\n col_vals_between(\n columns = c(\"sr\"),\n left = 0.6,\n right = 21.1\n ) %>%\n # Expect that column `pop15` is of type: numeric\n col_is_numeric(\n columns = c(\"pop15\")\n ) %>%\n # Expect that values in `pop15` should be between `21.44` and `47.64`\n col_vals_between(\n columns = c(\"pop15\"),\n left = 21.44,\n right = 47.64\n ) %>%\n # Expect that column `pop75` is of type: numeric\n col_is_numeric(\n columns = c(\"pop75\")\n ) %>%\n # Expect that values in `pop75` should be between `0.56` and `4.7`\n col_vals_between(\n columns = c(\"pop75\"),\n left = 0.56,\n right = 4.7\n ) %>%\n # Expect that column `dpi` is of type: numeric\n col_is_numeric(\n columns = c(\"dpi\")\n ) %>%\n # Expect that values in `dpi` should be between `88.94` and `4001.89`\n col_vals_between(\n columns = c(\"dpi\"),\n left = 88.94,\n right = 4001.89\n ) %>%\n # Expect that column `ddpi` is of type: numeric\n col_is_numeric(\n columns = c(\"ddpi\")\n ) %>%\n # Expect that values in `ddpi` should be between `0.22` and `16.71`\n col_vals_between(\n columns = c(\"ddpi\"),\n left = 0.22,\n right = 16.71\n ) %>%\n # Expect entirely distinct rows across `sr, pop15, pop75, dpi, ddpi`\n rows_distinct(\n columns = c(\"sr\", \"pop15\", \"pop75\", \"dpi\", \"ddpi\")\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n sr = \"numeric\",\n pop15 = \"numeric\",\n pop75 = \"numeric\",\n dpi = \"numeric\",\n ddpi = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `sr` is of type: numeric\n col_is_numeric(\n columns = vars(sr)\n ) %>%\n # Expect that values in `sr` should be between `0.6` and `21.1`\n col_vals_between(\n columns = vars(sr),\n left = 0.6,\n right = 21.1\n ) %>%\n # Expect that column `pop15` is of type: numeric\n col_is_numeric(\n columns = vars(pop15)\n ) %>%\n # Expect that values in `pop15` should be between `21.44` and `47.64`\n col_vals_between(\n columns = vars(pop15),\n left = 21.44,\n right = 47.64\n ) %>%\n # Expect that column `pop75` is of type: numeric\n col_is_numeric(\n columns = vars(pop75)\n ) %>%\n # Expect that values in `pop75` should be between `0.56` and `4.7`\n col_vals_between(\n columns = vars(pop75),\n left = 0.56,\n right = 4.7\n ) %>%\n # Expect that column `dpi` is of type: numeric\n col_is_numeric(\n columns = vars(dpi)\n ) %>%\n # Expect that values in `dpi` should be between `88.94` and `4001.89`\n col_vals_between(\n columns = vars(dpi),\n left = 88.94,\n right = 4001.89\n ) %>%\n # Expect that column `ddpi` is of type: numeric\n col_is_numeric(\n columns = vars(ddpi)\n ) %>%\n # Expect that values in `ddpi` should be between `0.22` and `16.71`\n col_vals_between(\n columns = vars(ddpi),\n left = 0.22,\n right = 16.71\n ) %>%\n # Expect entirely distinct rows across all columns\n rows_distinct() %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n sr = \"numeric\",\n pop15 = \"numeric\",\n pop75 = \"numeric\",\n dpi = \"numeric\",\n ddpi = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `GNP.deflator` is of type: numeric\n col_is_numeric(\n columns = c(\"GNP.deflator\")\n ) %>%\n # Expect that values in `GNP.deflator` should be between `83` and `116.9`\n col_vals_between(\n columns = c(\"GNP.deflator\"),\n left = 83,\n right = 116.9\n ) %>%\n # Expect that column `GNP` is of type: numeric\n col_is_numeric(\n columns = c(\"GNP\")\n ) %>%\n # Expect that values in `GNP` should be between `234.289` and `554.894`\n col_vals_between(\n columns = c(\"GNP\"),\n left = 234.289,\n right = 554.894\n ) %>%\n # Expect that column `Unemployed` is of type: numeric\n col_is_numeric(\n columns = c(\"Unemployed\")\n ) %>%\n # Expect that values in `Unemployed` should be between `187` and `480.6`\n col_vals_between(\n columns = c(\"Unemployed\"),\n left = 187,\n right = 480.6\n ) %>%\n # Expect that column `Armed.Forces` is of type: numeric\n col_is_numeric(\n columns = c(\"Armed.Forces\")\n ) %>%\n # Expect that values in `Armed.Forces` should be between `145.6` and `359.4`\n col_vals_between(\n columns = c(\"Armed.Forces\"),\n left = 145.6,\n right = 359.4\n ) %>%\n # Expect that column `Population` is of type: numeric\n col_is_numeric(\n columns = c(\"Population\")\n ) %>%\n # Expect that values in `Population` should be between `107.608` and `130.081`\n col_vals_between(\n columns = c(\"Population\"),\n left = 107.608,\n right = 130.081\n ) %>%\n # Expect that column `Year` is of type: integer\n col_is_integer(\n columns = c(\"Year\")\n ) %>%\n # Expect that values in `Year` should be between `1947` and `1962`\n col_vals_between(\n columns = c(\"Year\"),\n left = 1947,\n right = 1962\n ) %>%\n # Expect that column `Employed` is of type: numeric\n col_is_numeric(\n columns = c(\"Employed\")\n ) %>%\n # Expect that values in `Employed` should be between `60.171` and `70.551`\n col_vals_between(\n columns = c(\"Employed\"),\n left = 60.171,\n right = 70.551\n ) %>%\n # Expect entirely distinct rows across `GNP.deflator, GNP, Unemployed, Armed.Forces, Population, Year, Employed`\n rows_distinct(\n columns = c(\"GNP.deflator\", \"GNP\", \"Unemployed\", \"Armed.Forces\", \"Population\", \"Year\", \"Employed\")\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n GNP.deflator = \"numeric\",\n GNP = \"numeric\",\n Unemployed = \"numeric\",\n Armed.Forces = \"numeric\",\n Population = \"numeric\",\n Year = \"integer\",\n Employed = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `GNP.deflator` is of type: numeric\n col_is_numeric(\n columns = vars(GNP.deflator)\n ) %>%\n # Expect that values in `GNP.deflator` should be between `83` and `116.9`\n col_vals_between(\n columns = vars(GNP.deflator),\n left = 83,\n right = 116.9\n ) %>%\n # Expect that column `GNP` is of type: numeric\n col_is_numeric(\n columns = vars(GNP)\n ) %>%\n # Expect that values in `GNP` should be between `234.289` and `554.894`\n col_vals_between(\n columns = vars(GNP),\n left = 234.289,\n right = 554.894\n ) %>%\n # Expect that column `Unemployed` is of type: numeric\n col_is_numeric(\n columns = vars(Unemployed)\n ) %>%\n # Expect that values in `Unemployed` should be between `187` and `480.6`\n col_vals_between(\n columns = vars(Unemployed),\n left = 187,\n right = 480.6\n ) %>%\n # Expect that column `Armed.Forces` is of type: numeric\n col_is_numeric(\n columns = vars(Armed.Forces)\n ) %>%\n # Expect that values in `Armed.Forces` should be between `145.6` and `359.4`\n col_vals_between(\n columns = vars(Armed.Forces),\n left = 145.6,\n right = 359.4\n ) %>%\n # Expect that column `Population` is of type: numeric\n col_is_numeric(\n columns = vars(Population)\n ) %>%\n # Expect that values in `Population` should be between `107.608` and `130.081`\n col_vals_between(\n columns = vars(Population),\n left = 107.608,\n right = 130.081\n ) %>%\n # Expect that column `Year` is of type: integer\n col_is_integer(\n columns = vars(Year)\n ) %>%\n # Expect that values in `Year` should be between `1947` and `1962`\n col_vals_between(\n columns = vars(Year),\n left = 1947,\n right = 1962\n ) %>%\n # Expect that column `Employed` is of type: numeric\n col_is_numeric(\n columns = vars(Employed)\n ) %>%\n # Expect that values in `Employed` should be between `60.171` and `70.551`\n col_vals_between(\n columns = vars(Employed),\n left = 60.171,\n right = 70.551\n ) %>%\n # Expect entirely distinct rows across all columns\n rows_distinct() %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n GNP.deflator = \"numeric\",\n GNP = \"numeric\",\n Unemployed = \"numeric\",\n Armed.Forces = \"numeric\",\n Population = \"numeric\",\n Year = \"integer\",\n Employed = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `Expt` is of type: integer\n col_is_integer(\n columns = c(\"Expt\")\n ) %>%\n # Expect that values in `Expt` should be between `1` and `5`\n col_vals_between(\n columns = c(\"Expt\"),\n left = 1,\n right = 5\n ) %>%\n # Expect that column `Run` is of type: integer\n col_is_integer(\n columns = c(\"Run\")\n ) %>%\n # Expect that values in `Run` should be between `1` and `20`\n col_vals_between(\n columns = c(\"Run\"),\n left = 1,\n right = 20\n ) %>%\n # Expect that column `Speed` is of type: integer\n col_is_integer(\n columns = c(\"Speed\")\n ) %>%\n # Expect that values in `Speed` should be between `620` and `1070`\n col_vals_between(\n columns = c(\"Speed\"),\n left = 620,\n right = 1070\n ) %>%\n # Expect entirely distinct rows across `Expt, Run, Speed`\n rows_distinct(\n columns = c(\"Expt\", \"Run\", \"Speed\")\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n Expt = \"integer\",\n Run = \"integer\",\n Speed = \"integer\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `Expt` is of type: integer\n col_is_integer(\n columns = vars(Expt)\n ) %>%\n # Expect that values in `Expt` should be between `1` and `5`\n col_vals_between(\n columns = vars(Expt),\n left = 1,\n right = 5\n ) %>%\n # Expect that column `Run` is of type: integer\n col_is_integer(\n columns = vars(Run)\n ) %>%\n # Expect that values in `Run` should be between `1` and `20`\n col_vals_between(\n columns = vars(Run),\n left = 1,\n right = 20\n ) %>%\n # Expect that column `Speed` is of type: integer\n col_is_integer(\n columns = vars(Speed)\n ) %>%\n # Expect that values in `Speed` should be between `620` and `1070`\n col_vals_between(\n columns = vars(Speed),\n left = 620,\n right = 1070\n ) %>%\n # Expect entirely distinct rows across all columns\n rows_distinct() %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n Expt = \"integer\",\n Run = \"integer\",\n Speed = \"integer\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `mpg` is of type: numeric\n col_is_numeric(\n columns = c(\"mpg\")\n ) %>%\n # Expect that values in `mpg` should be between `10.4` and `33.9`\n col_vals_between(\n columns = c(\"mpg\"),\n left = 10.4,\n right = 33.9\n ) %>%\n # Expect that column `cyl` is of type: numeric\n col_is_numeric(\n columns = c(\"cyl\")\n ) %>%\n # Expect that values in `cyl` should be between `4` and `8`\n col_vals_between(\n columns = c(\"cyl\"),\n left = 4,\n right = 8\n ) %>%\n # Expect that column `disp` is of type: numeric\n col_is_numeric(\n columns = c(\"disp\")\n ) %>%\n # Expect that values in `disp` should be between `71.1` and `472`\n col_vals_between(\n columns = c(\"disp\"),\n left = 71.1,\n right = 472\n ) %>%\n # Expect that column `hp` is of type: numeric\n col_is_numeric(\n columns = c(\"hp\")\n ) %>%\n # Expect that values in `hp` should be between `52` and `335`\n col_vals_between(\n columns = c(\"hp\"),\n left = 52,\n right = 335\n ) %>%\n # Expect that column `drat` is of type: numeric\n col_is_numeric(\n columns = c(\"drat\")\n ) %>%\n # Expect that values in `drat` should be between `2.76` and `4.93`\n col_vals_between(\n columns = c(\"drat\"),\n left = 2.76,\n right = 4.93\n ) %>%\n # Expect that column `wt` is of type: numeric\n col_is_numeric(\n columns = c(\"wt\")\n ) %>%\n # Expect that values in `wt` should be between `1.513` and `5.424`\n col_vals_between(\n columns = c(\"wt\"),\n left = 1.513,\n right = 5.424\n ) %>%\n # Expect that column `qsec` is of type: numeric\n col_is_numeric(\n columns = c(\"qsec\")\n ) %>%\n # Expect that values in `qsec` should be between `14.5` and `22.9`\n col_vals_between(\n columns = c(\"qsec\"),\n left = 14.5,\n right = 22.9\n ) %>%\n # Expect that column `vs` is of type: numeric\n col_is_numeric(\n columns = c(\"vs\")\n ) %>%\n # Expect that values in `vs` should be between `0` and `1`\n col_vals_between(\n columns = c(\"vs\"),\n left = 0,\n right = 1\n ) %>%\n # Expect that column `am` is of type: numeric\n col_is_numeric(\n columns = c(\"am\")\n ) %>%\n # Expect that values in `am` should be between `0` and `1`\n col_vals_between(\n columns = c(\"am\"),\n left = 0,\n right = 1\n ) %>%\n # Expect that column `gear` is of type: numeric\n col_is_numeric(\n columns = c(\"gear\")\n ) %>%\n # Expect that values in `gear` should be between `3` and `5`\n col_vals_between(\n columns = c(\"gear\"),\n left = 3,\n right = 5\n ) %>%\n # Expect that column `carb` is of type: numeric\n col_is_numeric(\n columns = c(\"carb\")\n ) %>%\n # Expect that values in `carb` should be between `1` and `8`\n col_vals_between(\n columns = c(\"carb\"),\n left = 1,\n right = 8\n ) %>%\n # Expect entirely distinct rows across `mpg, cyl, disp, hp, drat, wt, qsec, vs, am, gear, carb`\n rows_distinct(\n columns = c(\"mpg\", \"cyl\", \"disp\", \"hp\", \"drat\", \"wt\", \"qsec\", \"vs\", \"am\", \"gear\", \"carb\")\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n mpg = \"numeric\",\n cyl = \"numeric\",\n disp = \"numeric\",\n hp = \"numeric\",\n drat = \"numeric\",\n wt = \"numeric\",\n qsec = \"numeric\",\n vs = \"numeric\",\n am = \"numeric\",\n gear = \"numeric\",\n carb = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `mpg` is of type: numeric\n col_is_numeric(\n columns = vars(mpg)\n ) %>%\n # Expect that values in `mpg` should be between `10.4` and `33.9`\n col_vals_between(\n columns = vars(mpg),\n left = 10.4,\n right = 33.9\n ) %>%\n # Expect that column `cyl` is of type: numeric\n col_is_numeric(\n columns = vars(cyl)\n ) %>%\n # Expect that values in `cyl` should be between `4` and `8`\n col_vals_between(\n columns = vars(cyl),\n left = 4,\n right = 8\n ) %>%\n # Expect that column `disp` is of type: numeric\n col_is_numeric(\n columns = vars(disp)\n ) %>%\n # Expect that values in `disp` should be between `71.1` and `472`\n col_vals_between(\n columns = vars(disp),\n left = 71.1,\n right = 472\n ) %>%\n # Expect that column `hp` is of type: numeric\n col_is_numeric(\n columns = vars(hp)\n ) %>%\n # Expect that values in `hp` should be between `52` and `335`\n col_vals_between(\n columns = vars(hp),\n left = 52,\n right = 335\n ) %>%\n # Expect that column `drat` is of type: numeric\n col_is_numeric(\n columns = vars(drat)\n ) %>%\n # Expect that values in `drat` should be between `2.76` and `4.93`\n col_vals_between(\n columns = vars(drat),\n left = 2.76,\n right = 4.93\n ) %>%\n # Expect that column `wt` is of type: numeric\n col_is_numeric(\n columns = vars(wt)\n ) %>%\n # Expect that values in `wt` should be between `1.513` and `5.424`\n col_vals_between(\n columns = vars(wt),\n left = 1.513,\n right = 5.424\n ) %>%\n # Expect that column `qsec` is of type: numeric\n col_is_numeric(\n columns = vars(qsec)\n ) %>%\n # Expect that values in `qsec` should be between `14.5` and `22.9`\n col_vals_between(\n columns = vars(qsec),\n left = 14.5,\n right = 22.9\n ) %>%\n # Expect that column `vs` is of type: numeric\n col_is_numeric(\n columns = vars(vs)\n ) %>%\n # Expect that values in `vs` should be between `0` and `1`\n col_vals_between(\n columns = vars(vs),\n left = 0,\n right = 1\n ) %>%\n # Expect that column `am` is of type: numeric\n col_is_numeric(\n columns = vars(am)\n ) %>%\n # Expect that values in `am` should be between `0` and `1`\n col_vals_between(\n columns = vars(am),\n left = 0,\n right = 1\n ) %>%\n # Expect that column `gear` is of type: numeric\n col_is_numeric(\n columns = vars(gear)\n ) %>%\n # Expect that values in `gear` should be between `3` and `5`\n col_vals_between(\n columns = vars(gear),\n left = 3,\n right = 5\n ) %>%\n # Expect that column `carb` is of type: numeric\n col_is_numeric(\n columns = vars(carb)\n ) %>%\n # Expect that values in `carb` should be between `1` and `8`\n col_vals_between(\n columns = vars(carb),\n left = 1,\n right = 8\n ) %>%\n # Expect entirely distinct rows across all columns\n rows_distinct() %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n mpg = \"numeric\",\n cyl = \"numeric\",\n disp = \"numeric\",\n hp = \"numeric\",\n drat = \"numeric\",\n wt = \"numeric\",\n qsec = \"numeric\",\n vs = \"numeric\",\n am = \"numeric\",\n gear = \"numeric\",\n carb = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `Tree` is of type: factor\n col_is_factor(\n columns = c(\"Tree\")\n ) %>%\n # Expect that column `age` is of type: numeric\n col_is_numeric(\n columns = c(\"age\")\n ) %>%\n # Expect that values in `age` should be between `118` and `1582`\n col_vals_between(\n columns = c(\"age\"),\n left = 118,\n right = 1582\n ) %>%\n # Expect that column `circumference` is of type: numeric\n col_is_numeric(\n columns = c(\"circumference\")\n ) %>%\n # Expect that values in `circumference` should be between `30` and `214`\n col_vals_between(\n columns = c(\"circumference\"),\n left = 30,\n right = 214\n ) %>%\n # Expect entirely distinct rows across `Tree, age, circumference`\n rows_distinct(\n columns = c(\"Tree\", \"age\", \"circumference\")\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n Tree = c(\"ordered\", \"factor\"),\n age = \"numeric\",\n circumference = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `Tree` is of type: factor\n col_is_factor(\n columns = vars(Tree)\n ) %>%\n # Expect that column `age` is of type: numeric\n col_is_numeric(\n columns = vars(age)\n ) %>%\n # Expect that values in `age` should be between `118` and `1582`\n col_vals_between(\n columns = vars(age),\n left = 118,\n right = 1582\n ) %>%\n # Expect that column `circumference` is of type: numeric\n col_is_numeric(\n columns = vars(circumference)\n ) %>%\n # Expect that values in `circumference` should be between `30` and `214`\n col_vals_between(\n columns = vars(circumference),\n left = 30,\n right = 214\n ) %>%\n # Expect entirely distinct rows across all columns\n rows_distinct() %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n Tree = c(\"ordered\", \"factor\"),\n age = \"numeric\",\n circumference = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `temperature` is of type: numeric\n col_is_numeric(\n columns = c(\"temperature\")\n ) %>%\n # Expect that values in `temperature` should be between `0` and `360`\n col_vals_between(\n columns = c(\"temperature\"),\n left = 0,\n right = 360\n ) %>%\n # Expect that column `pressure` is of type: numeric\n col_is_numeric(\n columns = c(\"pressure\")\n ) %>%\n # Expect that values in `pressure` should be between `2e-04` and `806`\n col_vals_between(\n columns = c(\"pressure\"),\n left = 2e-04,\n right = 806\n ) %>%\n # Expect entirely distinct rows across `temperature, pressure`\n rows_distinct(\n columns = c(\"temperature\", \"pressure\")\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n temperature = \"numeric\",\n pressure = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `temperature` is of type: numeric\n col_is_numeric(\n columns = vars(temperature)\n ) %>%\n # Expect that values in `temperature` should be between `0` and `360`\n col_vals_between(\n columns = vars(temperature),\n left = 0,\n right = 360\n ) %>%\n # Expect that column `pressure` is of type: numeric\n col_is_numeric(\n columns = vars(pressure)\n ) %>%\n # Expect that values in `pressure` should be between `2e-04` and `806`\n col_vals_between(\n columns = vars(pressure),\n left = 2e-04,\n right = 806\n ) %>%\n # Expect entirely distinct rows across all columns\n rows_distinct() %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n temperature = \"numeric\",\n pressure = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `lat` is of type: numeric\n col_is_numeric(\n columns = c(\"lat\")\n ) %>%\n # Expect that values in `lat` should be between `-90` and `90`\n col_vals_between(\n columns = c(\"lat\"),\n left = -90,\n right = 90\n ) %>%\n # Expect that column `long` is of type: numeric\n col_is_numeric(\n columns = c(\"long\")\n ) %>%\n # Expect that values in `long` should be between `-180` and `180`\n col_vals_between(\n columns = c(\"long\"),\n left = -180,\n right = 180\n ) %>%\n # Expect that column `depth` is of type: integer\n col_is_integer(\n columns = c(\"depth\")\n ) %>%\n # Expect that values in `depth` should be between `40` and `680`\n col_vals_between(\n columns = c(\"depth\"),\n left = 40,\n right = 680\n ) %>%\n # Expect that column `mag` is of type: numeric\n col_is_numeric(\n columns = c(\"mag\")\n ) %>%\n # Expect that values in `mag` should be between `4` and `6.4`\n col_vals_between(\n columns = c(\"mag\"),\n left = 4,\n right = 6.4\n ) %>%\n # Expect that column `stations` is of type: integer\n col_is_integer(\n columns = c(\"stations\")\n ) %>%\n # Expect that values in `stations` should be between `10` and `132`\n col_vals_between(\n columns = c(\"stations\"),\n left = 10,\n right = 132\n ) %>%\n # Expect entirely distinct rows across `lat, long, depth, mag, stations`\n rows_distinct(\n columns = c(\"lat\", \"long\", \"depth\", \"mag\", \"stations\")\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n lat = \"numeric\",\n long = \"numeric\",\n depth = \"integer\",\n mag = \"numeric\",\n stations = \"integer\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `lat` is of type: numeric\n col_is_numeric(\n columns = vars(lat)\n ) %>%\n # Expect that values in `lat` should be between `-90` and `90`\n col_vals_between(\n columns = vars(lat),\n left = -90,\n right = 90\n ) %>%\n # Expect that column `long` is of type: numeric\n col_is_numeric(\n columns = vars(long)\n ) %>%\n # Expect that values in `long` should be between `-180` and `180`\n col_vals_between(\n columns = vars(long),\n left = -180,\n right = 180\n ) %>%\n # Expect that column `depth` is of type: integer\n col_is_integer(\n columns = vars(depth)\n ) %>%\n # Expect that values in `depth` should be between `40` and `680`\n col_vals_between(\n columns = vars(depth),\n left = 40,\n right = 680\n ) %>%\n # Expect that column `mag` is of type: numeric\n col_is_numeric(\n columns = vars(mag)\n ) %>%\n # Expect that values in `mag` should be between `4` and `6.4`\n col_vals_between(\n columns = vars(mag),\n left = 4,\n right = 6.4\n ) %>%\n # Expect that column `stations` is of type: integer\n col_is_integer(\n columns = vars(stations)\n ) %>%\n # Expect that values in `stations` should be between `10` and `132`\n col_vals_between(\n columns = vars(stations),\n left = 10,\n right = 132\n ) %>%\n # Expect entirely distinct rows across all columns\n rows_distinct() %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n lat = \"numeric\",\n long = \"numeric\",\n depth = \"integer\",\n mag = \"numeric\",\n stations = \"integer\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `area` is of type: integer\n col_is_integer(\n columns = c(\"area\")\n ) %>%\n # Expect that values in `area` should be between `1016` and `12212`\n col_vals_between(\n columns = c(\"area\"),\n left = 1016,\n right = 12212\n ) %>%\n # Expect that column `peri` is of type: numeric\n col_is_numeric(\n columns = c(\"peri\")\n ) %>%\n # Expect that values in `peri` should be between `308.642` and `4864.22`\n col_vals_between(\n columns = c(\"peri\"),\n left = 308.642,\n right = 4864.22\n ) %>%\n # Expect that column `shape` is of type: numeric\n col_is_numeric(\n columns = c(\"shape\")\n ) %>%\n # Expect that values in `shape` should be between `0.0903296` and `0.464125`\n col_vals_between(\n columns = c(\"shape\"),\n left = 0.0903296,\n right = 0.464125\n ) %>%\n # Expect that column `perm` is of type: numeric\n col_is_numeric(\n columns = c(\"perm\")\n ) %>%\n # Expect that values in `perm` should be between `6.3` and `1300`\n col_vals_between(\n columns = c(\"perm\"),\n left = 6.3,\n right = 1300\n ) %>%\n # Expect entirely distinct rows across `area, peri, shape, perm`\n rows_distinct(\n columns = c(\"area\", \"peri\", \"shape\", \"perm\")\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n area = \"integer\",\n peri = \"numeric\",\n shape = \"numeric\",\n perm = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `area` is of type: integer\n col_is_integer(\n columns = vars(area)\n ) %>%\n # Expect that values in `area` should be between `1016` and `12212`\n col_vals_between(\n columns = vars(area),\n left = 1016,\n right = 12212\n ) %>%\n # Expect that column `peri` is of type: numeric\n col_is_numeric(\n columns = vars(peri)\n ) %>%\n # Expect that values in `peri` should be between `308.642` and `4864.22`\n col_vals_between(\n columns = vars(peri),\n left = 308.642,\n right = 4864.22\n ) %>%\n # Expect that column `shape` is of type: numeric\n col_is_numeric(\n columns = vars(shape)\n ) %>%\n # Expect that values in `shape` should be between `0.0903296` and `0.464125`\n col_vals_between(\n columns = vars(shape),\n left = 0.0903296,\n right = 0.464125\n ) %>%\n # Expect that column `perm` is of type: numeric\n col_is_numeric(\n columns = vars(perm)\n ) %>%\n # Expect that values in `perm` should be between `6.3` and `1300`\n col_vals_between(\n columns = vars(perm),\n left = 6.3,\n right = 1300\n ) %>%\n # Expect entirely distinct rows across all columns\n rows_distinct() %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n area = \"integer\",\n peri = \"numeric\",\n shape = \"numeric\",\n perm = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `Fertility` is of type: numeric\n col_is_numeric(\n columns = c(\"Fertility\")\n ) %>%\n # Expect that values in `Fertility` should be between `35` and `92.5`\n col_vals_between(\n columns = c(\"Fertility\"),\n left = 35,\n right = 92.5\n ) %>%\n # Expect that column `Agriculture` is of type: numeric\n col_is_numeric(\n columns = c(\"Agriculture\")\n ) %>%\n # Expect that values in `Agriculture` should be between `1.2` and `89.7`\n col_vals_between(\n columns = c(\"Agriculture\"),\n left = 1.2,\n right = 89.7\n ) %>%\n # Expect that column `Examination` is of type: integer\n col_is_integer(\n columns = c(\"Examination\")\n ) %>%\n # Expect that values in `Examination` should be between `3` and `37`\n col_vals_between(\n columns = c(\"Examination\"),\n left = 3,\n right = 37\n ) %>%\n # Expect that column `Education` is of type: integer\n col_is_integer(\n columns = c(\"Education\")\n ) %>%\n # Expect that values in `Education` should be between `1` and `53`\n col_vals_between(\n columns = c(\"Education\"),\n left = 1,\n right = 53\n ) %>%\n # Expect that column `Catholic` is of type: numeric\n col_is_numeric(\n columns = c(\"Catholic\")\n ) %>%\n # Expect that values in `Catholic` should be between `2.15` and `100`\n col_vals_between(\n columns = c(\"Catholic\"),\n left = 2.15,\n right = 100\n ) %>%\n # Expect that column `Infant.Mortality` is of type: numeric\n col_is_numeric(\n columns = c(\"Infant.Mortality\")\n ) %>%\n # Expect that values in `Infant.Mortality` should be between `10.8` and `26.6`\n col_vals_between(\n columns = c(\"Infant.Mortality\"),\n left = 10.8,\n right = 26.6\n ) %>%\n # Expect entirely distinct rows across `Fertility, Agriculture, Examination, Education, Catholic, Infant.Mortality`\n rows_distinct(\n columns = c(\"Fertility\", \"Agriculture\", \"Examination\", \"Education\", \"Catholic\", \"Infant.Mortality\")\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n Fertility = \"numeric\",\n Agriculture = \"numeric\",\n Examination = \"integer\",\n Education = \"integer\",\n Catholic = \"numeric\",\n Infant.Mortality = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `Fertility` is of type: numeric\n col_is_numeric(\n columns = vars(Fertility)\n ) %>%\n # Expect that values in `Fertility` should be between `35` and `92.5`\n col_vals_between(\n columns = vars(Fertility),\n left = 35,\n right = 92.5\n ) %>%\n # Expect that column `Agriculture` is of type: numeric\n col_is_numeric(\n columns = vars(Agriculture)\n ) %>%\n # Expect that values in `Agriculture` should be between `1.2` and `89.7`\n col_vals_between(\n columns = vars(Agriculture),\n left = 1.2,\n right = 89.7\n ) %>%\n # Expect that column `Examination` is of type: integer\n col_is_integer(\n columns = vars(Examination)\n ) %>%\n # Expect that values in `Examination` should be between `3` and `37`\n col_vals_between(\n columns = vars(Examination),\n left = 3,\n right = 37\n ) %>%\n # Expect that column `Education` is of type: integer\n col_is_integer(\n columns = vars(Education)\n ) %>%\n # Expect that values in `Education` should be between `1` and `53`\n col_vals_between(\n columns = vars(Education),\n left = 1,\n right = 53\n ) %>%\n # Expect that column `Catholic` is of type: numeric\n col_is_numeric(\n columns = vars(Catholic)\n ) %>%\n # Expect that values in `Catholic` should be between `2.15` and `100`\n col_vals_between(\n columns = vars(Catholic),\n left = 2.15,\n right = 100\n ) %>%\n # Expect that column `Infant.Mortality` is of type: numeric\n col_is_numeric(\n columns = vars(Infant.Mortality)\n ) %>%\n # Expect that values in `Infant.Mortality` should be between `10.8` and `26.6`\n col_vals_between(\n columns = vars(Infant.Mortality),\n left = 10.8,\n right = 26.6\n ) %>%\n # Expect entirely distinct rows across all columns\n rows_distinct() %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n Fertility = \"numeric\",\n Agriculture = \"numeric\",\n Examination = \"integer\",\n Education = \"integer\",\n Catholic = \"numeric\",\n Infant.Mortality = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" - ---- - - Code - readLines(con = path) %>% paste0(collapse = "\n") - Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `CONT` is of type: numeric\n col_is_numeric(\n columns = vars(CONT)\n ) %>%\n # Expect that values in `CONT` should be between `5.7` and `10.6`\n col_vals_between(\n columns = vars(CONT),\n left = 5.7,\n right = 10.6\n ) %>%\n # Expect that column `INTG` is of type: numeric\n col_is_numeric(\n columns = vars(INTG)\n ) %>%\n # Expect that values in `INTG` should be between `5.9` and `9.2`\n col_vals_between(\n columns = vars(INTG),\n left = 5.9,\n right = 9.2\n ) %>%\n # Expect that column `DMNR` is of type: numeric\n col_is_numeric(\n columns = vars(DMNR)\n ) %>%\n # Expect that values in `DMNR` should be between `4.3` and `9`\n col_vals_between(\n columns = vars(DMNR),\n left = 4.3,\n right = 9\n ) %>%\n # Expect that column `DILG` is of type: numeric\n col_is_numeric(\n columns = vars(DILG)\n ) %>%\n # Expect that values in `DILG` should be between `5.1` and `9`\n col_vals_between(\n columns = vars(DILG),\n left = 5.1,\n right = 9\n ) %>%\n # Expect that column `CFMG` is of type: numeric\n col_is_numeric(\n columns = vars(CFMG)\n ) %>%\n # Expect that values in `CFMG` should be between `5.4` and `8.7`\n col_vals_between(\n columns = vars(CFMG),\n left = 5.4,\n right = 8.7\n ) %>%\n # Expect that column `DECI` is of type: numeric\n col_is_numeric(\n columns = vars(DECI)\n ) %>%\n # Expect that values in `DECI` should be between `5.7` and `8.8`\n col_vals_between(\n columns = vars(DECI),\n left = 5.7,\n right = 8.8\n ) %>%\n # Expect that column `PREP` is of type: numeric\n col_is_numeric(\n columns = vars(PREP)\n ) %>%\n # Expect that values in `PREP` should be between `4.8` and `9.1`\n col_vals_between(\n columns = vars(PREP),\n left = 4.8,\n right = 9.1\n ) %>%\n # Expect that column `FAMI` is of type: numeric\n col_is_numeric(\n columns = vars(FAMI)\n ) %>%\n # Expect that values in `FAMI` should be between `5.1` and `9.1`\n col_vals_between(\n columns = vars(FAMI),\n left = 5.1,\n right = 9.1\n ) %>%\n # Expect that column `ORAL` is of type: numeric\n col_is_numeric(\n columns = vars(ORAL)\n ) %>%\n # Expect that values in `ORAL` should be between `4.7` and `8.9`\n col_vals_between(\n columns = vars(ORAL),\n left = 4.7,\n right = 8.9\n ) %>%\n # Expect that column `WRIT` is of type: numeric\n col_is_numeric(\n columns = vars(WRIT)\n ) %>%\n # Expect that values in `WRIT` should be between `4.9` and `9`\n col_vals_between(\n columns = vars(WRIT),\n left = 4.9,\n right = 9\n ) %>%\n # Expect that column `PHYS` is of type: numeric\n col_is_numeric(\n columns = vars(PHYS)\n ) %>%\n # Expect that values in `PHYS` should be between `4.7` and `9.1`\n col_vals_between(\n columns = vars(PHYS),\n left = 4.7,\n right = 9.1\n ) %>%\n # Expect that column `RTEN` is of type: numeric\n col_is_numeric(\n columns = vars(RTEN)\n ) %>%\n # Expect that values in `RTEN` should be between `4.8` and `9.2`\n col_vals_between(\n columns = vars(RTEN),\n left = 4.8,\n right = 9.2\n ) %>%\n # Expect entirely distinct rows across all columns\n rows_distinct() %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n CONT = \"numeric\",\n INTG = \"numeric\",\n DMNR = \"numeric\",\n DILG = \"numeric\",\n CFMG = \"numeric\",\n DECI = \"numeric\",\n PREP = \"numeric\",\n FAMI = \"numeric\",\n ORAL = \"numeric\",\n WRIT = \"numeric\",\n PHYS = \"numeric\",\n RTEN = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `CONT` is of type: numeric\n col_is_numeric(\n columns = c(\"CONT\")\n ) %>%\n # Expect that values in `CONT` should be between `5.7` and `10.6`\n col_vals_between(\n columns = c(\"CONT\"),\n left = 5.7,\n right = 10.6\n ) %>%\n # Expect that column `INTG` is of type: numeric\n col_is_numeric(\n columns = c(\"INTG\")\n ) %>%\n # Expect that values in `INTG` should be between `5.9` and `9.2`\n col_vals_between(\n columns = c(\"INTG\"),\n left = 5.9,\n right = 9.2\n ) %>%\n # Expect that column `DMNR` is of type: numeric\n col_is_numeric(\n columns = c(\"DMNR\")\n ) %>%\n # Expect that values in `DMNR` should be between `4.3` and `9`\n col_vals_between(\n columns = c(\"DMNR\"),\n left = 4.3,\n right = 9\n ) %>%\n # Expect that column `DILG` is of type: numeric\n col_is_numeric(\n columns = c(\"DILG\")\n ) %>%\n # Expect that values in `DILG` should be between `5.1` and `9`\n col_vals_between(\n columns = c(\"DILG\"),\n left = 5.1,\n right = 9\n ) %>%\n # Expect that column `CFMG` is of type: numeric\n col_is_numeric(\n columns = c(\"CFMG\")\n ) %>%\n # Expect that values in `CFMG` should be between `5.4` and `8.7`\n col_vals_between(\n columns = c(\"CFMG\"),\n left = 5.4,\n right = 8.7\n ) %>%\n # Expect that column `DECI` is of type: numeric\n col_is_numeric(\n columns = c(\"DECI\")\n ) %>%\n # Expect that values in `DECI` should be between `5.7` and `8.8`\n col_vals_between(\n columns = c(\"DECI\"),\n left = 5.7,\n right = 8.8\n ) %>%\n # Expect that column `PREP` is of type: numeric\n col_is_numeric(\n columns = c(\"PREP\")\n ) %>%\n # Expect that values in `PREP` should be between `4.8` and `9.1`\n col_vals_between(\n columns = c(\"PREP\"),\n left = 4.8,\n right = 9.1\n ) %>%\n # Expect that column `FAMI` is of type: numeric\n col_is_numeric(\n columns = c(\"FAMI\")\n ) %>%\n # Expect that values in `FAMI` should be between `5.1` and `9.1`\n col_vals_between(\n columns = c(\"FAMI\"),\n left = 5.1,\n right = 9.1\n ) %>%\n # Expect that column `ORAL` is of type: numeric\n col_is_numeric(\n columns = c(\"ORAL\")\n ) %>%\n # Expect that values in `ORAL` should be between `4.7` and `8.9`\n col_vals_between(\n columns = c(\"ORAL\"),\n left = 4.7,\n right = 8.9\n ) %>%\n # Expect that column `WRIT` is of type: numeric\n col_is_numeric(\n columns = c(\"WRIT\")\n ) %>%\n # Expect that values in `WRIT` should be between `4.9` and `9`\n col_vals_between(\n columns = c(\"WRIT\"),\n left = 4.9,\n right = 9\n ) %>%\n # Expect that column `PHYS` is of type: numeric\n col_is_numeric(\n columns = c(\"PHYS\")\n ) %>%\n # Expect that values in `PHYS` should be between `4.7` and `9.1`\n col_vals_between(\n columns = c(\"PHYS\"),\n left = 4.7,\n right = 9.1\n ) %>%\n # Expect that column `RTEN` is of type: numeric\n col_is_numeric(\n columns = c(\"RTEN\")\n ) %>%\n # Expect that values in `RTEN` should be between `4.8` and `9.2`\n col_vals_between(\n columns = c(\"RTEN\"),\n left = 4.8,\n right = 9.2\n ) %>%\n # Expect entirely distinct rows across `CONT, INTG, DMNR, DILG, CFMG, DECI, PREP, FAMI, ORAL, WRIT, PHYS, RTEN`\n rows_distinct(\n columns = c(\"CONT\", \"INTG\", \"DMNR\", \"DILG\", \"CFMG\", \"DECI\", \"PREP\", \"FAMI\", \"ORAL\", \"WRIT\", \"PHYS\", \"RTEN\")\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n CONT = \"numeric\",\n INTG = \"numeric\",\n DMNR = \"numeric\",\n DILG = \"numeric\",\n CFMG = \"numeric\",\n DECI = \"numeric\",\n PREP = \"numeric\",\n FAMI = \"numeric\",\n ORAL = \"numeric\",\n WRIT = \"numeric\",\n PHYS = \"numeric\",\n RTEN = \"numeric\"\n )\n ) %>%\n interrogate()\n\nagent" # draft validations for data tables can be generated in different languages Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `a` is of type: integer\n col_is_integer(\n columns = vars(a)\n ) %>%\n # Expect that values in `a` should be between `1` and `8`\n col_vals_between(\n columns = vars(a),\n left = 1,\n right = 8\n ) %>%\n # Expect that column `b` is of type: character\n col_is_character(\n columns = vars(b)\n ) %>%\n # Expect that column `c` is of type: numeric\n col_is_numeric(\n columns = vars(c)\n ) %>%\n # Expect that values in `c` should be between `2` and `9`\n col_vals_between(\n columns = vars(c),\n left = 2,\n right = 9,\n na_pass = TRUE\n ) %>%\n # Expect that column `d` is of type: numeric\n col_is_numeric(\n columns = vars(d)\n ) %>%\n # Expect that values in `d` should be between `108.34` and `9999.99`\n col_vals_between(\n columns = vars(d),\n left = 108.34,\n right = 9999.99\n ) %>%\n # Expect that column `e` is of type: logical\n col_is_logical(\n columns = vars(e)\n ) %>%\n # Expect that column `f` is of type: character\n col_is_character(\n columns = vars(f)\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n date_time = c(\"POSIXct\", \"POSIXt\"),\n date = \"Date\",\n a = \"integer\",\n b = \"character\",\n c = \"numeric\",\n d = \"numeric\",\n e = \"logical\",\n f = \"character\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `a` is of type: integer\n col_is_integer(\n columns = c(\"a\")\n ) %>%\n # Expect that values in `a` should be between `1` and `8`\n col_vals_between(\n columns = c(\"a\"),\n left = 1,\n right = 8\n ) %>%\n # Expect that column `b` is of type: character\n col_is_character(\n columns = c(\"b\")\n ) %>%\n # Expect that column `c` is of type: numeric\n col_is_numeric(\n columns = c(\"c\")\n ) %>%\n # Expect that values in `c` should be between `2` and `9`\n col_vals_between(\n columns = c(\"c\"),\n left = 2,\n right = 9,\n na_pass = TRUE\n ) %>%\n # Expect that column `d` is of type: numeric\n col_is_numeric(\n columns = c(\"d\")\n ) %>%\n # Expect that values in `d` should be between `108.34` and `9999.99`\n col_vals_between(\n columns = c(\"d\"),\n left = 108.34,\n right = 9999.99\n ) %>%\n # Expect that column `e` is of type: logical\n col_is_logical(\n columns = c(\"e\")\n ) %>%\n # Expect that column `f` is of type: character\n col_is_character(\n columns = c(\"f\")\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n date_time = c(\"POSIXct\", \"POSIXt\"),\n date = \"Date\",\n a = \"integer\",\n b = \"character\",\n c = \"numeric\",\n d = \"numeric\",\n e = \"logical\",\n f = \"character\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\",\n lang = \"fr\",\n locale = \"fr\"\n ) %>%\n # Attendez-vous à ce que la colonne `a` soit de type: integer\n col_is_integer(\n columns = vars(a)\n ) %>%\n # Attendez-vous à ce que les valeurs de `a` soient comprises entre `1` et `8`\n col_vals_between(\n columns = vars(a),\n left = 1,\n right = 8\n ) %>%\n # Attendez-vous à ce que la colonne `b` soit de type: character\n col_is_character(\n columns = vars(b)\n ) %>%\n # Attendez-vous à ce que la colonne `c` soit de type: numeric\n col_is_numeric(\n columns = vars(c)\n ) %>%\n # Attendez-vous à ce que les valeurs de `c` soient comprises entre `2` et `9`\n col_vals_between(\n columns = vars(c),\n left = 2,\n right = 9,\n na_pass = TRUE\n ) %>%\n # Attendez-vous à ce que la colonne `d` soit de type: numeric\n col_is_numeric(\n columns = vars(d)\n ) %>%\n # Attendez-vous à ce que les valeurs de `d` soient comprises entre `108.34` et `9999.99`\n col_vals_between(\n columns = vars(d),\n left = 108.34,\n right = 9999.99\n ) %>%\n # Attendez-vous à ce que la colonne `e` soit de type: logical\n col_is_logical(\n columns = vars(e)\n ) %>%\n # Attendez-vous à ce que la colonne `f` soit de type: character\n col_is_character(\n columns = vars(f)\n ) %>%\n # Attendez-vous à ce que les schémas de colonnes correspondent\n col_schema_match(\n schema = col_schema(\n date_time = c(\"POSIXct\", \"POSIXt\"),\n date = \"Date\",\n a = \"integer\",\n b = \"character\",\n c = \"numeric\",\n d = \"numeric\",\n e = \"logical\",\n f = \"character\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\",\n lang = \"fr\",\n locale = \"fr\"\n ) %>%\n # Attendez-vous à ce que la colonne `a` soit de type: integer\n col_is_integer(\n columns = c(\"a\")\n ) %>%\n # Attendez-vous à ce que les valeurs de `a` soient comprises entre `1` et `8`\n col_vals_between(\n columns = c(\"a\"),\n left = 1,\n right = 8\n ) %>%\n # Attendez-vous à ce que la colonne `b` soit de type: character\n col_is_character(\n columns = c(\"b\")\n ) %>%\n # Attendez-vous à ce que la colonne `c` soit de type: numeric\n col_is_numeric(\n columns = c(\"c\")\n ) %>%\n # Attendez-vous à ce que les valeurs de `c` soient comprises entre `2` et `9`\n col_vals_between(\n columns = c(\"c\"),\n left = 2,\n right = 9,\n na_pass = TRUE\n ) %>%\n # Attendez-vous à ce que la colonne `d` soit de type: numeric\n col_is_numeric(\n columns = c(\"d\")\n ) %>%\n # Attendez-vous à ce que les valeurs de `d` soient comprises entre `108.34` et `9999.99`\n col_vals_between(\n columns = c(\"d\"),\n left = 108.34,\n right = 9999.99\n ) %>%\n # Attendez-vous à ce que la colonne `e` soit de type: logical\n col_is_logical(\n columns = c(\"e\")\n ) %>%\n # Attendez-vous à ce que la colonne `f` soit de type: character\n col_is_character(\n columns = c(\"f\")\n ) %>%\n # Attendez-vous à ce que les schémas de colonnes correspondent\n col_schema_match(\n schema = col_schema(\n date_time = c(\"POSIXct\", \"POSIXt\"),\n date = \"Date\",\n a = \"integer\",\n b = \"character\",\n c = \"numeric\",\n d = \"numeric\",\n e = \"logical\",\n f = \"character\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\",\n lang = \"de\",\n locale = \"de\"\n ) %>%\n # Erwarten Sie, dass die Spalte `a` vom Typ integer ist\n col_is_integer(\n columns = vars(a)\n ) %>%\n # Erwarten Sie, dass die Werte in `a` zwischen `1` und `8` liegen sollten\n col_vals_between(\n columns = vars(a),\n left = 1,\n right = 8\n ) %>%\n # Erwarten Sie, dass die Spalte `b` vom Typ character ist\n col_is_character(\n columns = vars(b)\n ) %>%\n # Erwarten Sie, dass die Spalte `c` vom Typ numeric ist\n col_is_numeric(\n columns = vars(c)\n ) %>%\n # Erwarten Sie, dass die Werte in `c` zwischen `2` und `9` liegen sollten\n col_vals_between(\n columns = vars(c),\n left = 2,\n right = 9,\n na_pass = TRUE\n ) %>%\n # Erwarten Sie, dass die Spalte `d` vom Typ numeric ist\n col_is_numeric(\n columns = vars(d)\n ) %>%\n # Erwarten Sie, dass die Werte in `d` zwischen `108.34` und `9999.99` liegen sollten\n col_vals_between(\n columns = vars(d),\n left = 108.34,\n right = 9999.99\n ) %>%\n # Erwarten Sie, dass die Spalte `e` vom Typ logical ist\n col_is_logical(\n columns = vars(e)\n ) %>%\n # Erwarten Sie, dass die Spalte `f` vom Typ character ist\n col_is_character(\n columns = vars(f)\n ) %>%\n # Erwarten Sie, dass die Spaltenschemata übereinstimmen\n col_schema_match(\n schema = col_schema(\n date_time = c(\"POSIXct\", \"POSIXt\"),\n date = \"Date\",\n a = \"integer\",\n b = \"character\",\n c = \"numeric\",\n d = \"numeric\",\n e = \"logical\",\n f = \"character\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\",\n lang = \"de\",\n locale = \"de\"\n ) %>%\n # Erwarten Sie, dass die Spalte `a` vom Typ integer ist\n col_is_integer(\n columns = c(\"a\")\n ) %>%\n # Erwarten Sie, dass die Werte in `a` zwischen `1` und `8` liegen sollten\n col_vals_between(\n columns = c(\"a\"),\n left = 1,\n right = 8\n ) %>%\n # Erwarten Sie, dass die Spalte `b` vom Typ character ist\n col_is_character(\n columns = c(\"b\")\n ) %>%\n # Erwarten Sie, dass die Spalte `c` vom Typ numeric ist\n col_is_numeric(\n columns = c(\"c\")\n ) %>%\n # Erwarten Sie, dass die Werte in `c` zwischen `2` und `9` liegen sollten\n col_vals_between(\n columns = c(\"c\"),\n left = 2,\n right = 9,\n na_pass = TRUE\n ) %>%\n # Erwarten Sie, dass die Spalte `d` vom Typ numeric ist\n col_is_numeric(\n columns = c(\"d\")\n ) %>%\n # Erwarten Sie, dass die Werte in `d` zwischen `108.34` und `9999.99` liegen sollten\n col_vals_between(\n columns = c(\"d\"),\n left = 108.34,\n right = 9999.99\n ) %>%\n # Erwarten Sie, dass die Spalte `e` vom Typ logical ist\n col_is_logical(\n columns = c(\"e\")\n ) %>%\n # Erwarten Sie, dass die Spalte `f` vom Typ character ist\n col_is_character(\n columns = c(\"f\")\n ) %>%\n # Erwarten Sie, dass die Spaltenschemata übereinstimmen\n col_schema_match(\n schema = col_schema(\n date_time = c(\"POSIXct\", \"POSIXt\"),\n date = \"Date\",\n a = \"integer\",\n b = \"character\",\n c = \"numeric\",\n d = \"numeric\",\n e = \"logical\",\n f = \"character\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\",\n lang = \"it\",\n locale = \"it\"\n ) %>%\n # Aspettati che la colonna `a` sia di tipo: integer\n col_is_integer(\n columns = vars(a)\n ) %>%\n # Aspettati che i valori in `a` siano compresi tra `1` e `8`\n col_vals_between(\n columns = vars(a),\n left = 1,\n right = 8\n ) %>%\n # Aspettati che la colonna `b` sia di tipo: character\n col_is_character(\n columns = vars(b)\n ) %>%\n # Aspettati che la colonna `c` sia di tipo: numeric\n col_is_numeric(\n columns = vars(c)\n ) %>%\n # Aspettati che i valori in `c` siano compresi tra `2` e `9`\n col_vals_between(\n columns = vars(c),\n left = 2,\n right = 9,\n na_pass = TRUE\n ) %>%\n # Aspettati che la colonna `d` sia di tipo: numeric\n col_is_numeric(\n columns = vars(d)\n ) %>%\n # Aspettati che i valori in `d` siano compresi tra `108.34` e `9999.99`\n col_vals_between(\n columns = vars(d),\n left = 108.34,\n right = 9999.99\n ) %>%\n # Aspettati che la colonna `e` sia di tipo: logical\n col_is_logical(\n columns = vars(e)\n ) %>%\n # Aspettati che la colonna `f` sia di tipo: character\n col_is_character(\n columns = vars(f)\n ) %>%\n # Aspettati che gli schemi di colonna corrispondano\n col_schema_match(\n schema = col_schema(\n date_time = c(\"POSIXct\", \"POSIXt\"),\n date = \"Date\",\n a = \"integer\",\n b = \"character\",\n c = \"numeric\",\n d = \"numeric\",\n e = \"logical\",\n f = \"character\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\",\n lang = \"it\",\n locale = \"it\"\n ) %>%\n # Aspettati che la colonna `a` sia di tipo: integer\n col_is_integer(\n columns = c(\"a\")\n ) %>%\n # Aspettati che i valori in `a` siano compresi tra `1` e `8`\n col_vals_between(\n columns = c(\"a\"),\n left = 1,\n right = 8\n ) %>%\n # Aspettati che la colonna `b` sia di tipo: character\n col_is_character(\n columns = c(\"b\")\n ) %>%\n # Aspettati che la colonna `c` sia di tipo: numeric\n col_is_numeric(\n columns = c(\"c\")\n ) %>%\n # Aspettati che i valori in `c` siano compresi tra `2` e `9`\n col_vals_between(\n columns = c(\"c\"),\n left = 2,\n right = 9,\n na_pass = TRUE\n ) %>%\n # Aspettati che la colonna `d` sia di tipo: numeric\n col_is_numeric(\n columns = c(\"d\")\n ) %>%\n # Aspettati che i valori in `d` siano compresi tra `108.34` e `9999.99`\n col_vals_between(\n columns = c(\"d\"),\n left = 108.34,\n right = 9999.99\n ) %>%\n # Aspettati che la colonna `e` sia di tipo: logical\n col_is_logical(\n columns = c(\"e\")\n ) %>%\n # Aspettati che la colonna `f` sia di tipo: character\n col_is_character(\n columns = c(\"f\")\n ) %>%\n # Aspettati che gli schemi di colonna corrispondano\n col_schema_match(\n schema = col_schema(\n date_time = c(\"POSIXct\", \"POSIXt\"),\n date = \"Date\",\n a = \"integer\",\n b = \"character\",\n c = \"numeric\",\n d = \"numeric\",\n e = \"logical\",\n f = \"character\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\",\n lang = \"es\",\n locale = \"es\"\n ) %>%\n # Se espera que la columna `a` sea del tipo \n col_is_integer(\n columns = vars(a)\n ) %>%\n # Se espera que los valores en `a` estén entre `1` y `8`\n col_vals_between(\n columns = vars(a),\n left = 1,\n right = 8\n ) %>%\n # Se espera que la columna `b` sea del tipo \n col_is_character(\n columns = vars(b)\n ) %>%\n # Se espera que la columna `c` sea del tipo \n col_is_numeric(\n columns = vars(c)\n ) %>%\n # Se espera que los valores en `c` estén entre `2` y `9`\n col_vals_between(\n columns = vars(c),\n left = 2,\n right = 9,\n na_pass = TRUE\n ) %>%\n # Se espera que la columna `d` sea del tipo \n col_is_numeric(\n columns = vars(d)\n ) %>%\n # Se espera que los valores en `d` estén entre `108.34` y `9999.99`\n col_vals_between(\n columns = vars(d),\n left = 108.34,\n right = 9999.99\n ) %>%\n # Se espera que la columna `e` sea del tipo \n col_is_logical(\n columns = vars(e)\n ) %>%\n # Se espera que la columna `f` sea del tipo \n col_is_character(\n columns = vars(f)\n ) %>%\n # Se espera que los esquemas de columna coincidan\n col_schema_match(\n schema = col_schema(\n date_time = c(\"POSIXct\", \"POSIXt\"),\n date = \"Date\",\n a = \"integer\",\n b = \"character\",\n c = \"numeric\",\n d = \"numeric\",\n e = \"logical\",\n f = \"character\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\",\n lang = \"es\",\n locale = \"es\"\n ) %>%\n # Se espera que la columna `a` sea del tipo \n col_is_integer(\n columns = c(\"a\")\n ) %>%\n # Se espera que los valores en `a` estén entre `1` y `8`\n col_vals_between(\n columns = c(\"a\"),\n left = 1,\n right = 8\n ) %>%\n # Se espera que la columna `b` sea del tipo \n col_is_character(\n columns = c(\"b\")\n ) %>%\n # Se espera que la columna `c` sea del tipo \n col_is_numeric(\n columns = c(\"c\")\n ) %>%\n # Se espera que los valores en `c` estén entre `2` y `9`\n col_vals_between(\n columns = c(\"c\"),\n left = 2,\n right = 9,\n na_pass = TRUE\n ) %>%\n # Se espera que la columna `d` sea del tipo \n col_is_numeric(\n columns = c(\"d\")\n ) %>%\n # Se espera que los valores en `d` estén entre `108.34` y `9999.99`\n col_vals_between(\n columns = c(\"d\"),\n left = 108.34,\n right = 9999.99\n ) %>%\n # Se espera que la columna `e` sea del tipo \n col_is_logical(\n columns = c(\"e\")\n ) %>%\n # Se espera que la columna `f` sea del tipo \n col_is_character(\n columns = c(\"f\")\n ) %>%\n # Se espera que los esquemas de columna coincidan\n col_schema_match(\n schema = col_schema(\n date_time = c(\"POSIXct\", \"POSIXt\"),\n date = \"Date\",\n a = \"integer\",\n b = \"character\",\n c = \"numeric\",\n d = \"numeric\",\n e = \"logical\",\n f = \"character\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\",\n lang = \"pt\",\n locale = \"pt\"\n ) %>%\n # Espera-se que coluna `a` seja do tipo \n col_is_integer(\n columns = vars(a)\n ) %>%\n # Espera-se que os valores em `a` devem estar entre `1` e `8`\n col_vals_between(\n columns = vars(a),\n left = 1,\n right = 8\n ) %>%\n # Espera-se que coluna `b` seja do tipo \n col_is_character(\n columns = vars(b)\n ) %>%\n # Espera-se que coluna `c` seja do tipo \n col_is_numeric(\n columns = vars(c)\n ) %>%\n # Espera-se que os valores em `c` devem estar entre `2` e `9`\n col_vals_between(\n columns = vars(c),\n left = 2,\n right = 9,\n na_pass = TRUE\n ) %>%\n # Espera-se que coluna `d` seja do tipo \n col_is_numeric(\n columns = vars(d)\n ) %>%\n # Espera-se que os valores em `d` devem estar entre `108.34` e `9999.99`\n col_vals_between(\n columns = vars(d),\n left = 108.34,\n right = 9999.99\n ) %>%\n # Espera-se que coluna `e` seja do tipo \n col_is_logical(\n columns = vars(e)\n ) %>%\n # Espera-se que coluna `f` seja do tipo \n col_is_character(\n columns = vars(f)\n ) %>%\n # Espera-se que os esquemas de coluna concordem\n col_schema_match(\n schema = col_schema(\n date_time = c(\"POSIXct\", \"POSIXt\"),\n date = \"Date\",\n a = \"integer\",\n b = \"character\",\n c = \"numeric\",\n d = \"numeric\",\n e = \"logical\",\n f = \"character\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\",\n lang = \"pt\",\n locale = \"pt\"\n ) %>%\n # Espera-se que coluna `a` seja do tipo \n col_is_integer(\n columns = c(\"a\")\n ) %>%\n # Espera-se que os valores em `a` devem estar entre `1` e `8`\n col_vals_between(\n columns = c(\"a\"),\n left = 1,\n right = 8\n ) %>%\n # Espera-se que coluna `b` seja do tipo \n col_is_character(\n columns = c(\"b\")\n ) %>%\n # Espera-se que coluna `c` seja do tipo \n col_is_numeric(\n columns = c(\"c\")\n ) %>%\n # Espera-se que os valores em `c` devem estar entre `2` e `9`\n col_vals_between(\n columns = c(\"c\"),\n left = 2,\n right = 9,\n na_pass = TRUE\n ) %>%\n # Espera-se que coluna `d` seja do tipo \n col_is_numeric(\n columns = c(\"d\")\n ) %>%\n # Espera-se que os valores em `d` devem estar entre `108.34` e `9999.99`\n col_vals_between(\n columns = c(\"d\"),\n left = 108.34,\n right = 9999.99\n ) %>%\n # Espera-se que coluna `e` seja do tipo \n col_is_logical(\n columns = c(\"e\")\n ) %>%\n # Espera-se que coluna `f` seja do tipo \n col_is_character(\n columns = c(\"f\")\n ) %>%\n # Espera-se que os esquemas de coluna concordem\n col_schema_match(\n schema = col_schema(\n date_time = c(\"POSIXct\", \"POSIXt\"),\n date = \"Date\",\n a = \"integer\",\n b = \"character\",\n c = \"numeric\",\n d = \"numeric\",\n e = \"logical\",\n f = \"character\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\",\n lang = \"tr\",\n locale = \"tr\"\n ) %>%\n # `a` sütununun şu türde olmasını bekleyin: integer\n col_is_integer(\n columns = vars(a)\n ) %>%\n # Beklenti, `a` 'deki değerlerin `1` ile `8` arasında olması gerektiğidir\n col_vals_between(\n columns = vars(a),\n left = 1,\n right = 8\n ) %>%\n # `b` sütununun şu türde olmasını bekleyin: character\n col_is_character(\n columns = vars(b)\n ) %>%\n # `c` sütununun şu türde olmasını bekleyin: numeric\n col_is_numeric(\n columns = vars(c)\n ) %>%\n # Beklenti, `c` 'deki değerlerin `2` ile `9` arasında olması gerektiğidir\n col_vals_between(\n columns = vars(c),\n left = 2,\n right = 9,\n na_pass = TRUE\n ) %>%\n # `d` sütununun şu türde olmasını bekleyin: numeric\n col_is_numeric(\n columns = vars(d)\n ) %>%\n # Beklenti, `d` 'deki değerlerin `108.34` ile `9999.99` arasında olması gerektiğidir\n col_vals_between(\n columns = vars(d),\n left = 108.34,\n right = 9999.99\n ) %>%\n # `e` sütununun şu türde olmasını bekleyin: logical\n col_is_logical(\n columns = vars(e)\n ) %>%\n # `f` sütununun şu türde olmasını bekleyin: character\n col_is_character(\n columns = vars(f)\n ) %>%\n # Sütun şemalarının eşleşmesini bekleyin\n col_schema_match(\n schema = col_schema(\n date_time = c(\"POSIXct\", \"POSIXt\"),\n date = \"Date\",\n a = \"integer\",\n b = \"character\",\n c = \"numeric\",\n d = \"numeric\",\n e = \"logical\",\n f = \"character\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\",\n lang = \"tr\",\n locale = \"tr\"\n ) %>%\n # `a` sütununun şu türde olmasını bekleyin: integer\n col_is_integer(\n columns = c(\"a\")\n ) %>%\n # Beklenti, `a` 'deki değerlerin `1` ile `8` arasında olması gerektiğidir\n col_vals_between(\n columns = c(\"a\"),\n left = 1,\n right = 8\n ) %>%\n # `b` sütununun şu türde olmasını bekleyin: character\n col_is_character(\n columns = c(\"b\")\n ) %>%\n # `c` sütununun şu türde olmasını bekleyin: numeric\n col_is_numeric(\n columns = c(\"c\")\n ) %>%\n # Beklenti, `c` 'deki değerlerin `2` ile `9` arasında olması gerektiğidir\n col_vals_between(\n columns = c(\"c\"),\n left = 2,\n right = 9,\n na_pass = TRUE\n ) %>%\n # `d` sütununun şu türde olmasını bekleyin: numeric\n col_is_numeric(\n columns = c(\"d\")\n ) %>%\n # Beklenti, `d` 'deki değerlerin `108.34` ile `9999.99` arasında olması gerektiğidir\n col_vals_between(\n columns = c(\"d\"),\n left = 108.34,\n right = 9999.99\n ) %>%\n # `e` sütununun şu türde olmasını bekleyin: logical\n col_is_logical(\n columns = c(\"e\")\n ) %>%\n # `f` sütununun şu türde olmasını bekleyin: character\n col_is_character(\n columns = c(\"f\")\n ) %>%\n # Sütun şemalarının eşleşmesini bekleyin\n col_schema_match(\n schema = col_schema(\n date_time = c(\"POSIXct\", \"POSIXt\"),\n date = \"Date\",\n a = \"integer\",\n b = \"character\",\n c = \"numeric\",\n d = \"numeric\",\n e = \"logical\",\n f = \"character\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\",\n lang = \"zh\",\n locale = \"zh\"\n ) %>%\n # 预期列 `a`为类型 \n col_is_integer(\n columns = vars(a)\n ) %>%\n # 预期在`a` 的值应当在 `1`和 `8`之间。 \n col_vals_between(\n columns = vars(a),\n left = 1,\n right = 8\n ) %>%\n # 预期列 `b`为类型 \n col_is_character(\n columns = vars(b)\n ) %>%\n # 预期列 `c`为类型 \n col_is_numeric(\n columns = vars(c)\n ) %>%\n # 预期在`c` 的值应当在 `2`和 `9`之间。 \n col_vals_between(\n columns = vars(c),\n left = 2,\n right = 9,\n na_pass = TRUE\n ) %>%\n # 预期列 `d`为类型 \n col_is_numeric(\n columns = vars(d)\n ) %>%\n # 预期在`d` 的值应当在 `108.34`和 `9999.99`之间。 \n col_vals_between(\n columns = vars(d),\n left = 108.34,\n right = 9999.99\n ) %>%\n # 预期列 `e`为类型 \n col_is_logical(\n columns = vars(e)\n ) %>%\n # 预期列 `f`为类型 \n col_is_character(\n columns = vars(f)\n ) %>%\n # 预期列模式(column schemas)应当匹配。 \n col_schema_match(\n schema = col_schema(\n date_time = c(\"POSIXct\", \"POSIXt\"),\n date = \"Date\",\n a = \"integer\",\n b = \"character\",\n c = \"numeric\",\n d = \"numeric\",\n e = \"logical\",\n f = \"character\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\",\n lang = \"zh\",\n locale = \"zh\"\n ) %>%\n # 预期列 `a`为类型 \n col_is_integer(\n columns = c(\"a\")\n ) %>%\n # 预期在`a` 的值应当在 `1`和 `8`之间。 \n col_vals_between(\n columns = c(\"a\"),\n left = 1,\n right = 8\n ) %>%\n # 预期列 `b`为类型 \n col_is_character(\n columns = c(\"b\")\n ) %>%\n # 预期列 `c`为类型 \n col_is_numeric(\n columns = c(\"c\")\n ) %>%\n # 预期在`c` 的值应当在 `2`和 `9`之间。 \n col_vals_between(\n columns = c(\"c\"),\n left = 2,\n right = 9,\n na_pass = TRUE\n ) %>%\n # 预期列 `d`为类型 \n col_is_numeric(\n columns = c(\"d\")\n ) %>%\n # 预期在`d` 的值应当在 `108.34`和 `9999.99`之间。 \n col_vals_between(\n columns = c(\"d\"),\n left = 108.34,\n right = 9999.99\n ) %>%\n # 预期列 `e`为类型 \n col_is_logical(\n columns = c(\"e\")\n ) %>%\n # 预期列 `f`为类型 \n col_is_character(\n columns = c(\"f\")\n ) %>%\n # 预期列模式(column schemas)应当匹配。 \n col_schema_match(\n schema = col_schema(\n date_time = c(\"POSIXct\", \"POSIXt\"),\n date = \"Date\",\n a = \"integer\",\n b = \"character\",\n c = \"numeric\",\n d = \"numeric\",\n e = \"logical\",\n f = \"character\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\",\n lang = \"ru\",\n locale = \"ru\"\n ) %>%\n # Ожидайте, что столбец `a` имеет тип: integer\n col_is_integer(\n columns = vars(a)\n ) %>%\n # Ожидайте, что значения в `a` должны находиться между `1` и `8`\n col_vals_between(\n columns = vars(a),\n left = 1,\n right = 8\n ) %>%\n # Ожидайте, что столбец `b` имеет тип: character\n col_is_character(\n columns = vars(b)\n ) %>%\n # Ожидайте, что столбец `c` имеет тип: numeric\n col_is_numeric(\n columns = vars(c)\n ) %>%\n # Ожидайте, что значения в `c` должны находиться между `2` и `9`\n col_vals_between(\n columns = vars(c),\n left = 2,\n right = 9,\n na_pass = TRUE\n ) %>%\n # Ожидайте, что столбец `d` имеет тип: numeric\n col_is_numeric(\n columns = vars(d)\n ) %>%\n # Ожидайте, что значения в `d` должны находиться между `108.34` и `9999.99`\n col_vals_between(\n columns = vars(d),\n left = 108.34,\n right = 9999.99\n ) %>%\n # Ожидайте, что столбец `e` имеет тип: logical\n col_is_logical(\n columns = vars(e)\n ) %>%\n # Ожидайте, что столбец `f` имеет тип: character\n col_is_character(\n columns = vars(f)\n ) %>%\n # Ожидайте, что схемы столбцов совпадают\n col_schema_match(\n schema = col_schema(\n date_time = c(\"POSIXct\", \"POSIXt\"),\n date = \"Date\",\n a = \"integer\",\n b = \"character\",\n c = \"numeric\",\n d = \"numeric\",\n e = \"logical\",\n f = \"character\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\",\n lang = \"ru\",\n locale = \"ru\"\n ) %>%\n # Ожидайте, что столбец `a` имеет тип: integer\n col_is_integer(\n columns = c(\"a\")\n ) %>%\n # Ожидайте, что значения в `a` должны находиться между `1` и `8`\n col_vals_between(\n columns = c(\"a\"),\n left = 1,\n right = 8\n ) %>%\n # Ожидайте, что столбец `b` имеет тип: character\n col_is_character(\n columns = c(\"b\")\n ) %>%\n # Ожидайте, что столбец `c` имеет тип: numeric\n col_is_numeric(\n columns = c(\"c\")\n ) %>%\n # Ожидайте, что значения в `c` должны находиться между `2` и `9`\n col_vals_between(\n columns = c(\"c\"),\n left = 2,\n right = 9,\n na_pass = TRUE\n ) %>%\n # Ожидайте, что столбец `d` имеет тип: numeric\n col_is_numeric(\n columns = c(\"d\")\n ) %>%\n # Ожидайте, что значения в `d` должны находиться между `108.34` и `9999.99`\n col_vals_between(\n columns = c(\"d\"),\n left = 108.34,\n right = 9999.99\n ) %>%\n # Ожидайте, что столбец `e` имеет тип: logical\n col_is_logical(\n columns = c(\"e\")\n ) %>%\n # Ожидайте, что столбец `f` имеет тип: character\n col_is_character(\n columns = c(\"f\")\n ) %>%\n # Ожидайте, что схемы столбцов совпадают\n col_schema_match(\n schema = col_schema(\n date_time = c(\"POSIXct\", \"POSIXt\"),\n date = \"Date\",\n a = \"integer\",\n b = \"character\",\n c = \"numeric\",\n d = \"numeric\",\n e = \"logical\",\n f = \"character\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\",\n lang = \"pl\",\n locale = \"pl\"\n ) %>%\n # Spodziewaj się, że kolumna `a` jest typu: integer\n col_is_integer(\n columns = vars(a)\n ) %>%\n # Spodziewaj się, że wartości w `a` powinny zawierac się między `1` a `8`\n col_vals_between(\n columns = vars(a),\n left = 1,\n right = 8\n ) %>%\n # Spodziewaj się, że kolumna `b` jest typu: character\n col_is_character(\n columns = vars(b)\n ) %>%\n # Spodziewaj się, że kolumna `c` jest typu: numeric\n col_is_numeric(\n columns = vars(c)\n ) %>%\n # Spodziewaj się, że wartości w `c` powinny zawierac się między `2` a `9`\n col_vals_between(\n columns = vars(c),\n left = 2,\n right = 9,\n na_pass = TRUE\n ) %>%\n # Spodziewaj się, że kolumna `d` jest typu: numeric\n col_is_numeric(\n columns = vars(d)\n ) %>%\n # Spodziewaj się, że wartości w `d` powinny zawierac się między `108.34` a `9999.99`\n col_vals_between(\n columns = vars(d),\n left = 108.34,\n right = 9999.99\n ) %>%\n # Spodziewaj się, że kolumna `e` jest typu: logical\n col_is_logical(\n columns = vars(e)\n ) %>%\n # Spodziewaj się, że kolumna `f` jest typu: character\n col_is_character(\n columns = vars(f)\n ) %>%\n # Spodziewaj się, że schematy kolumn będa zgodne\n col_schema_match(\n schema = col_schema(\n date_time = c(\"POSIXct\", \"POSIXt\"),\n date = \"Date\",\n a = \"integer\",\n b = \"character\",\n c = \"numeric\",\n d = \"numeric\",\n e = \"logical\",\n f = \"character\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\",\n lang = \"pl\",\n locale = \"pl\"\n ) %>%\n # Spodziewaj się, że kolumna `a` jest typu: integer\n col_is_integer(\n columns = c(\"a\")\n ) %>%\n # Spodziewaj się, że wartości w `a` powinny zawierac się między `1` a `8`\n col_vals_between(\n columns = c(\"a\"),\n left = 1,\n right = 8\n ) %>%\n # Spodziewaj się, że kolumna `b` jest typu: character\n col_is_character(\n columns = c(\"b\")\n ) %>%\n # Spodziewaj się, że kolumna `c` jest typu: numeric\n col_is_numeric(\n columns = c(\"c\")\n ) %>%\n # Spodziewaj się, że wartości w `c` powinny zawierac się między `2` a `9`\n col_vals_between(\n columns = c(\"c\"),\n left = 2,\n right = 9,\n na_pass = TRUE\n ) %>%\n # Spodziewaj się, że kolumna `d` jest typu: numeric\n col_is_numeric(\n columns = c(\"d\")\n ) %>%\n # Spodziewaj się, że wartości w `d` powinny zawierac się między `108.34` a `9999.99`\n col_vals_between(\n columns = c(\"d\"),\n left = 108.34,\n right = 9999.99\n ) %>%\n # Spodziewaj się, że kolumna `e` jest typu: logical\n col_is_logical(\n columns = c(\"e\")\n ) %>%\n # Spodziewaj się, że kolumna `f` jest typu: character\n col_is_character(\n columns = c(\"f\")\n ) %>%\n # Spodziewaj się, że schematy kolumn będa zgodne\n col_schema_match(\n schema = col_schema(\n date_time = c(\"POSIXct\", \"POSIXt\"),\n date = \"Date\",\n a = \"integer\",\n b = \"character\",\n c = \"numeric\",\n d = \"numeric\",\n e = \"logical\",\n f = \"character\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\",\n lang = \"da\",\n locale = \"da\"\n ) %>%\n # Forvent at kolonne `a` er af typen: integer\n col_is_integer(\n columns = vars(a)\n ) %>%\n # Forvent at værdierne i `a` skal være imellem `1` og `8`\n col_vals_between(\n columns = vars(a),\n left = 1,\n right = 8\n ) %>%\n # Forvent at kolonne `b` er af typen: character\n col_is_character(\n columns = vars(b)\n ) %>%\n # Forvent at kolonne `c` er af typen: numeric\n col_is_numeric(\n columns = vars(c)\n ) %>%\n # Forvent at værdierne i `c` skal være imellem `2` og `9`\n col_vals_between(\n columns = vars(c),\n left = 2,\n right = 9,\n na_pass = TRUE\n ) %>%\n # Forvent at kolonne `d` er af typen: numeric\n col_is_numeric(\n columns = vars(d)\n ) %>%\n # Forvent at værdierne i `d` skal være imellem `108.34` og `9999.99`\n col_vals_between(\n columns = vars(d),\n left = 108.34,\n right = 9999.99\n ) %>%\n # Forvent at kolonne `e` er af typen: logical\n col_is_logical(\n columns = vars(e)\n ) %>%\n # Forvent at kolonne `f` er af typen: character\n col_is_character(\n columns = vars(f)\n ) %>%\n # Forvent overensstemmelse med kolonne schema\n col_schema_match(\n schema = col_schema(\n date_time = c(\"POSIXct\", \"POSIXt\"),\n date = \"Date\",\n a = \"integer\",\n b = \"character\",\n c = \"numeric\",\n d = \"numeric\",\n e = \"logical\",\n f = \"character\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\",\n lang = \"da\",\n locale = \"da\"\n ) %>%\n # Forvent at kolonne `a` er af typen: integer\n col_is_integer(\n columns = c(\"a\")\n ) %>%\n # Forvent at værdierne i `a` skal være imellem `1` og `8`\n col_vals_between(\n columns = c(\"a\"),\n left = 1,\n right = 8\n ) %>%\n # Forvent at kolonne `b` er af typen: character\n col_is_character(\n columns = c(\"b\")\n ) %>%\n # Forvent at kolonne `c` er af typen: numeric\n col_is_numeric(\n columns = c(\"c\")\n ) %>%\n # Forvent at værdierne i `c` skal være imellem `2` og `9`\n col_vals_between(\n columns = c(\"c\"),\n left = 2,\n right = 9,\n na_pass = TRUE\n ) %>%\n # Forvent at kolonne `d` er af typen: numeric\n col_is_numeric(\n columns = c(\"d\")\n ) %>%\n # Forvent at værdierne i `d` skal være imellem `108.34` og `9999.99`\n col_vals_between(\n columns = c(\"d\"),\n left = 108.34,\n right = 9999.99\n ) %>%\n # Forvent at kolonne `e` er af typen: logical\n col_is_logical(\n columns = c(\"e\")\n ) %>%\n # Forvent at kolonne `f` er af typen: character\n col_is_character(\n columns = c(\"f\")\n ) %>%\n # Forvent overensstemmelse med kolonne schema\n col_schema_match(\n schema = col_schema(\n date_time = c(\"POSIXct\", \"POSIXt\"),\n date = \"Date\",\n a = \"integer\",\n b = \"character\",\n c = \"numeric\",\n d = \"numeric\",\n e = \"logical\",\n f = \"character\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\",\n lang = \"sv\",\n locale = \"sv\"\n ) %>%\n # Förvänta dig att kolumn `a` är av typen: integer\n col_is_integer(\n columns = vars(a)\n ) %>%\n # Förvänta dig att värdena i `a` ligger mellan `1` och `8`\n col_vals_between(\n columns = vars(a),\n left = 1,\n right = 8\n ) %>%\n # Förvänta dig att kolumn `b` är av typen: character\n col_is_character(\n columns = vars(b)\n ) %>%\n # Förvänta dig att kolumn `c` är av typen: numeric\n col_is_numeric(\n columns = vars(c)\n ) %>%\n # Förvänta dig att värdena i `c` ligger mellan `2` och `9`\n col_vals_between(\n columns = vars(c),\n left = 2,\n right = 9,\n na_pass = TRUE\n ) %>%\n # Förvänta dig att kolumn `d` är av typen: numeric\n col_is_numeric(\n columns = vars(d)\n ) %>%\n # Förvänta dig att värdena i `d` ligger mellan `108.34` och `9999.99`\n col_vals_between(\n columns = vars(d),\n left = 108.34,\n right = 9999.99\n ) %>%\n # Förvänta dig att kolumn `e` är av typen: logical\n col_is_logical(\n columns = vars(e)\n ) %>%\n # Förvänta dig att kolumn `f` är av typen: character\n col_is_character(\n columns = vars(f)\n ) %>%\n # Förvänta överensstämmelse med kolumn schema\n col_schema_match(\n schema = col_schema(\n date_time = c(\"POSIXct\", \"POSIXt\"),\n date = \"Date\",\n a = \"integer\",\n b = \"character\",\n c = \"numeric\",\n d = \"numeric\",\n e = \"logical\",\n f = \"character\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\",\n lang = \"sv\",\n locale = \"sv\"\n ) %>%\n # Förvänta dig att kolumn `a` är av typen: integer\n col_is_integer(\n columns = c(\"a\")\n ) %>%\n # Förvänta dig att värdena i `a` ligger mellan `1` och `8`\n col_vals_between(\n columns = c(\"a\"),\n left = 1,\n right = 8\n ) %>%\n # Förvänta dig att kolumn `b` är av typen: character\n col_is_character(\n columns = c(\"b\")\n ) %>%\n # Förvänta dig att kolumn `c` är av typen: numeric\n col_is_numeric(\n columns = c(\"c\")\n ) %>%\n # Förvänta dig att värdena i `c` ligger mellan `2` och `9`\n col_vals_between(\n columns = c(\"c\"),\n left = 2,\n right = 9,\n na_pass = TRUE\n ) %>%\n # Förvänta dig att kolumn `d` är av typen: numeric\n col_is_numeric(\n columns = c(\"d\")\n ) %>%\n # Förvänta dig att värdena i `d` ligger mellan `108.34` och `9999.99`\n col_vals_between(\n columns = c(\"d\"),\n left = 108.34,\n right = 9999.99\n ) %>%\n # Förvänta dig att kolumn `e` är av typen: logical\n col_is_logical(\n columns = c(\"e\")\n ) %>%\n # Förvänta dig att kolumn `f` är av typen: character\n col_is_character(\n columns = c(\"f\")\n ) %>%\n # Förvänta överensstämmelse med kolumn schema\n col_schema_match(\n schema = col_schema(\n date_time = c(\"POSIXct\", \"POSIXt\"),\n date = \"Date\",\n a = \"integer\",\n b = \"character\",\n c = \"numeric\",\n d = \"numeric\",\n e = \"logical\",\n f = \"character\"\n )\n ) %>%\n interrogate()\n\nagent" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\",\n lang = \"nl\",\n locale = \"nl\"\n ) %>%\n # Verwacht dat de kolom `a` van het type integer is\n col_is_integer(\n columns = vars(a)\n ) %>%\n # Verwacht dat de waarden in `a` tussen `1` en `8` moeten liggen\n col_vals_between(\n columns = vars(a),\n left = 1,\n right = 8\n ) %>%\n # Verwacht dat de kolom `b` van het type character is\n col_is_character(\n columns = vars(b)\n ) %>%\n # Verwacht dat de kolom `c` van het type numeric is\n col_is_numeric(\n columns = vars(c)\n ) %>%\n # Verwacht dat de waarden in `c` tussen `2` en `9` moeten liggen\n col_vals_between(\n columns = vars(c),\n left = 2,\n right = 9,\n na_pass = TRUE\n ) %>%\n # Verwacht dat de kolom `d` van het type numeric is\n col_is_numeric(\n columns = vars(d)\n ) %>%\n # Verwacht dat de waarden in `d` tussen `108.34` en `9999.99` moeten liggen\n col_vals_between(\n columns = vars(d),\n left = 108.34,\n right = 9999.99\n ) %>%\n # Verwacht dat de kolom `e` van het type logical is\n col_is_logical(\n columns = vars(e)\n ) %>%\n # Verwacht dat de kolom `f` van het type character is\n col_is_character(\n columns = vars(f)\n ) %>%\n # Verwacht dat de kolomschema's overeenkomen\n col_schema_match(\n schema = col_schema(\n date_time = c(\"POSIXct\", \"POSIXt\"),\n date = \"Date\",\n a = \"integer\",\n b = \"character\",\n c = \"numeric\",\n d = \"numeric\",\n e = \"logical\",\n f = \"character\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\",\n lang = \"nl\",\n locale = \"nl\"\n ) %>%\n # Verwacht dat de kolom `a` van het type integer is\n col_is_integer(\n columns = c(\"a\")\n ) %>%\n # Verwacht dat de waarden in `a` tussen `1` en `8` moeten liggen\n col_vals_between(\n columns = c(\"a\"),\n left = 1,\n right = 8\n ) %>%\n # Verwacht dat de kolom `b` van het type character is\n col_is_character(\n columns = c(\"b\")\n ) %>%\n # Verwacht dat de kolom `c` van het type numeric is\n col_is_numeric(\n columns = c(\"c\")\n ) %>%\n # Verwacht dat de waarden in `c` tussen `2` en `9` moeten liggen\n col_vals_between(\n columns = c(\"c\"),\n left = 2,\n right = 9,\n na_pass = TRUE\n ) %>%\n # Verwacht dat de kolom `d` van het type numeric is\n col_is_numeric(\n columns = c(\"d\")\n ) %>%\n # Verwacht dat de waarden in `d` tussen `108.34` en `9999.99` moeten liggen\n col_vals_between(\n columns = c(\"d\"),\n left = 108.34,\n right = 9999.99\n ) %>%\n # Verwacht dat de kolom `e` van het type logical is\n col_is_logical(\n columns = c(\"e\")\n ) %>%\n # Verwacht dat de kolom `f` van het type character is\n col_is_character(\n columns = c(\"f\")\n ) %>%\n # Verwacht dat de kolomschema's overeenkomen\n col_schema_match(\n schema = col_schema(\n date_time = c(\"POSIXct\", \"POSIXt\"),\n date = \"Date\",\n a = \"integer\",\n b = \"character\",\n c = \"numeric\",\n d = \"numeric\",\n e = \"logical\",\n f = \"character\"\n )\n ) %>%\n interrogate()\n\nagent" # draft validations for data tables can be generated in .Rmd format Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "---\ntitle: \"tbl\"\noutput: html_document\n---\n\n```{r setup, include=FALSE}\nknitr::opts_chunk$set(echo = TRUE)\nlibrary(pointblank)\n```\n\n\n```{r create_agent, echo=TRUE}\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `country_name` is of type: character\n col_is_character(\n columns = vars(country_name)\n ) %>%\n # Expect that values in `country_name` should be in the set of `Aruba`, `Afghanistan`, `Angola` (and 212 more)\n col_vals_in_set(\n columns = vars(country_name),\n set = c(\"Aruba\", \"Afghanistan\", \"Angola\", \"Albania\", \"Andorra\", \"United Arab Emirates\", \"Argentina\", \"Armenia\", \"American Samoa\", \"Antigua and Barbuda\", \"Australia\", \"Austria\", \"Azerbaijan\", \"Burundi\", \"Belgium\", \"Benin\", \"Burkina Faso\", \"Bangladesh\", \"Bulgaria\", \"Bahrain\", \"Bahamas\", \"Bosnia and Herzegovina\", \"Belarus\", \"Belize\", \"Bermuda\", \"Bolivia\", \"Brazil\", \"Barbados\", \"Brunei Darussalam\", \"Bhutan\", \"Botswana\", \"Central African Republic\", \"Canada\", \"Switzerland\", \"Chile\", \"China\", \"Cote d'Ivoire\", \"Cameroon\", \"Congo (Democratic Republic)\", \"Congo\", \"Colombia\", \"Comoros\", \"Cabo Verde\", \"Costa Rica\", \"Cuba\", \"Curacao\", \"Cayman Islands\", \"Cyprus\", \"Czechia\", \"Germany\", \"Djibouti\", \"Dominica\", \"Denmark\", \"Dominican Republic\", \"Algeria\", \"Ecuador\", \"Egypt\", \"Eritrea\", \"Spain\", \"Estonia\", \"Ethiopia\", \"Finland\", \"Fiji\", \"France\", \"Faroe Islands\", \"Micronesia (Federated States)\", \"Gabon\", \"United Kingdom\", \"Georgia\", \"Ghana\", \"Gibraltar\", \"Guinea\", \"Gambia, The\", \"Guinea-Bissau\", \"Equatorial Guinea\", \"Greece\", \"Grenada\", \"Greenland\", \"Guatemala\", \"Guam\", \"Guyana\", \"Hong Kong\", \"Honduras\", \"Croatia\", \"Haiti\", \"Hungary\", \"Indonesia\", \"Isle of Man\", \"India\", \"Ireland\", \"Iran (Islamic Republic)\", \"Iraq\", \"Iceland\", \"Israel\", \"Italy\", \"Jamaica\", \"Jordan\", \"Japan\", \"Kazakhstan\", \"Kenya\", \"Kyrgyz Republic\", \"Cambodia\", \"Kiribati\", \"St. Kitts and Nevis\", \"Korea, Rep.\", \"Kuwait\", \"Lao PDR\", \"Lebanon\", \"Liberia\", \"Libya\", \"St. Lucia\", \"Liechtenstein\", \"Sri Lanka\", \"Lesotho\", \"Lithuania\", \"Luxembourg\", \"Latvia\", \"Macao\", \"St. Martin (French part)\", \"Morocco\", \"Monaco\", \"Moldova\", \"Madagascar\", \"Maldives\", \"Mexico\", \"Marshall Islands\", \"North Macedonia\", \"Mali\", \"Malta\", \"Myanmar\", \"Montenegro\", \"Mongolia\", \"Northern Mariana Islands\", \"Mozambique\", \"Mauritania\", \"Mauritius\", \"Malawi\", \"Malaysia\", \"Namibia\", \"New Caledonia\", \"Niger\", \"Nigeria\", \"Nicaragua\", \"Netherlands\", \"Norway\", \"Nepal\", \"Nauru\", \"New Zealand\", \"Oman\", \"Pakistan\", \"Panama\", \"Peru\", \"Philippines\", \"Palau\", \"Papua New Guinea\", \"Poland\", \"Puerto Rico\", \"Korea, Dem. People's Rep.\", \"Portugal\", \"Paraguay\", \"West Bank and Gaza\", \"French Polynesia\", \"Qatar\", \"Romania\", \"Russian Federation\", \"Rwanda\", \"Saudi Arabia\", \"Sudan\", \"Senegal\", \"Singapore\", \"Solomon Islands\", \"Sierra Leone\", \"El Salvador\", \"San Marino\", \"Somalia\", \"Serbia\", \"South Sudan\", \"Sao Tome and Principe\", \"Suriname\", \"Slovak Republic\", \"Slovenia\", \"Sweden\", \"Eswatini\", \"Sint Maarten (Dutch part)\", \"Seychelles\", \"Syrian Arab Republic\", \"Turks and Caicos Islands\", \"Chad\", \"Togo\", \"Thailand\", \"Tajikistan\", \"Turkmenistan\", \"Timor-Leste\", \"Tonga\", \"Trinidad and Tobago\", \"Tunisia\", \"Turkiye\", \"Tuvalu\", \"Tanzania\", \"Uganda\", \"Ukraine\", \"Uruguay\", \"United States\", \"Uzbekistan\", \"St. Vincent and the Grenadines\", \"Venezuela, RB\", \"British Virgin Islands\", \"Virgin Islands (U.S.)\", \"Vietnam\", \"Vanuatu\", \"Samoa\", \"Yemen\", \"South Africa\", \"Zambia\", \"Zimbabwe\")\n ) %>%\n # Expect that column `country_code_2` is of type: character\n col_is_character(\n columns = vars(country_code_2)\n ) %>%\n # Expect that values in `country_code_2` should be in the set of `AD`, `AE`, `AF` (and 246 more)\n col_vals_in_set(\n columns = vars(country_code_2),\n set = c(\"AD\", \"AE\", \"AF\", \"AG\", \"AI\", \"AL\", \"AM\", \"AO\", \"AQ\", \"AR\", \"AS\", \"AT\", \"AU\", \"AW\", \"AX\", \"AZ\", \"BA\", \"BB\", \"BD\", \"BE\", \"BF\", \"BG\", \"BH\", \"BI\", \"BJ\", \"BL\", \"BM\", \"BN\", \"BO\", \"BQ\", \"BR\", \"BS\", \"BT\", \"BV\", \"BW\", \"BY\", \"BZ\", \"CA\", \"CC\", \"CD\", \"CF\", \"CG\", \"CH\", \"CI\", \"CK\", \"CL\", \"CM\", \"CN\", \"CO\", \"CR\", \"CU\", \"CV\", \"CW\", \"CX\", \"CY\", \"CZ\", \"DE\", \"DJ\", \"DK\", \"DM\", \"DO\", \"DZ\", \"EC\", \"EE\", \"EG\", \"EH\", \"ER\", \"ES\", \"ET\", \"FI\", \"FJ\", \"FK\", \"FM\", \"FO\", \"FR\", \"GA\", \"GB\", \"GD\", \"GE\", \"GF\", \"GG\", \"GH\", \"GI\", \"GL\", \"GM\", \"GN\", \"GP\", \"GQ\", \"GR\", \"GS\", \"GT\", \"GU\", \"GW\", \"GY\", \"HK\", \"HM\", \"HN\", \"HR\", \"HT\", \"HU\", \"ID\", \"IE\", \"IL\", \"IM\", \"IN\", \"IO\", \"IQ\", \"IR\", \"IS\", \"IT\", \"JE\", \"JM\", \"JO\", \"JP\", \"KE\", \"KG\", \"KH\", \"KI\", \"KM\", \"KN\", \"KP\", \"KR\", \"KW\", \"KY\", \"KZ\", \"LA\", \"LB\", \"LC\", \"LI\", \"LK\", \"LR\", \"LS\", \"LT\", \"LU\", \"LV\", \"LY\", \"MA\", \"MC\", \"MD\", \"ME\", \"MF\", \"MG\", \"MH\", \"MK\", \"ML\", \"MM\", \"MN\", \"MO\", \"MP\", \"MQ\", \"MR\", \"MS\", \"MT\", \"MU\", \"MV\", \"MW\", \"MX\", \"MY\", \"MZ\", \"NA\", \"NC\", \"NE\", \"NF\", \"NG\", \"NI\", \"NL\", \"NO\", \"NP\", \"NR\", \"NU\", \"NZ\", \"OM\", \"PA\", \"PE\", \"PF\", \"PG\", \"PH\", \"PK\", \"PL\", \"PM\", \"PN\", \"PR\", \"PS\", \"PT\", \"PW\", \"PY\", \"QA\", \"RE\", \"RO\", \"RS\", \"RU\", \"RW\", \"SA\", \"SB\", \"SC\", \"SD\", \"SE\", \"SG\", \"SH\", \"SI\", \"SJ\", \"SK\", \"SL\", \"SM\", \"SN\", \"SO\", \"SR\", \"SS\", \"ST\", \"SV\", \"SX\", \"SY\", \"SZ\", \"TC\", \"TD\", \"TF\", \"TG\", \"TH\", \"TJ\", \"TK\", \"TL\", \"TM\", \"TN\", \"TO\", \"TR\", \"TT\", \"TV\", \"TW\", \"TZ\", \"UA\", \"UG\", \"UM\", \"US\", \"UY\", \"UZ\", \"VA\", \"VC\", \"VE\", \"VG\", \"VI\", \"VN\", \"VU\", \"WF\", \"WS\", \"YE\", \"YT\", \"ZA\", \"ZM\", \"ZW\")\n ) %>%\n # Expect that column `country_code_3` is of type: character\n col_is_character(\n columns = vars(country_code_3)\n ) %>%\n # Expect that values in `country_code_3` should be in the set of `AND`, `ARE`, `AFG` (and 246 more)\n col_vals_in_set(\n columns = vars(country_code_3),\n set = c(\"AND\", \"ARE\", \"AFG\", \"ATG\", \"AIA\", \"ALB\", \"ARM\", \"AGO\", \"ATA\", \"ARG\", \"ASM\", \"AUT\", \"AUS\", \"ABW\", \"ALA\", \"AZE\", \"BIH\", \"BRB\", \"BGD\", \"BEL\", \"BFA\", \"BGR\", \"BHR\", \"BDI\", \"BEN\", \"BLM\", \"BMU\", \"BRN\", \"BOL\", \"BES\", \"BRA\", \"BHS\", \"BTN\", \"BVT\", \"BWA\", \"BLR\", \"BLZ\", \"CAN\", \"CCK\", \"COD\", \"CAF\", \"COG\", \"CHE\", \"CIV\", \"COK\", \"CHL\", \"CMR\", \"CHN\", \"COL\", \"CRI\", \"CUB\", \"CPV\", \"CUW\", \"CXR\", \"CYP\", \"CZE\", \"DEU\", \"DJI\", \"DNK\", \"DMA\", \"DOM\", \"DZA\", \"ECU\", \"EST\", \"EGY\", \"ESH\", \"ERI\", \"ESP\", \"ETH\", \"FIN\", \"FJI\", \"FLK\", \"FSM\", \"FRO\", \"FRA\", \"GAB\", \"GBR\", \"GRD\", \"GEO\", \"GUF\", \"GGY\", \"GHA\", \"GIB\", \"GRL\", \"GMB\", \"GIN\", \"GLP\", \"GNQ\", \"GRC\", \"SGS\", \"GTM\", \"GUM\", \"GNB\", \"GUY\", \"HKG\", \"HMD\", \"HND\", \"HRV\", \"HTI\", \"HUN\", \"IDN\", \"IRL\", \"ISR\", \"IMN\", \"IND\", \"IOT\", \"IRQ\", \"IRN\", \"ISL\", \"ITA\", \"JEY\", \"JAM\", \"JOR\", \"JPN\", \"KEN\", \"KGZ\", \"KHM\", \"KIR\", \"COM\", \"KNA\", \"PRK\", \"KOR\", \"KWT\", \"CYM\", \"KAZ\", \"LAO\", \"LBN\", \"LCA\", \"LIE\", \"LKA\", \"LBR\", \"LSO\", \"LTU\", \"LUX\", \"LVA\", \"LBY\", \"MAR\", \"MCO\", \"MDA\", \"MNE\", \"MAF\", \"MDG\", \"MHL\", \"MKD\", \"MLI\", \"MMR\", \"MNG\", \"MAC\", \"MNP\", \"MTQ\", \"MRT\", \"MSR\", \"MLT\", \"MUS\", \"MDV\", \"MWI\", \"MEX\", \"MYS\", \"MOZ\", \"NAM\", \"NCL\", \"NER\", \"NFK\", \"NGA\", \"NIC\", \"NLD\", \"NOR\", \"NPL\", \"NRU\", \"NIU\", \"NZL\", \"OMN\", \"PAN\", \"PER\", \"PYF\", \"PNG\", \"PHL\", \"PAK\", \"POL\", \"SPM\", \"PCN\", \"PRI\", \"PSE\", \"PRT\", \"PLW\", \"PRY\", \"QAT\", \"REU\", \"ROU\", \"SRB\", \"RUS\", \"RWA\", \"SAU\", \"SLB\", \"SYC\", \"SDN\", \"SWE\", \"SGP\", \"SHN\", \"SVN\", \"SJM\", \"SVK\", \"SLE\", \"SMR\", \"SEN\", \"SOM\", \"SUR\", \"SSD\", \"STP\", \"SLV\", \"SXM\", \"SYR\", \"SWZ\", \"TCA\", \"TCD\", \"ATF\", \"TGO\", \"THA\", \"TJK\", \"TKL\", \"TLS\", \"TKM\", \"TUN\", \"TON\", \"TUR\", \"TTO\", \"TUV\", \"TWN\", \"TZA\", \"UKR\", \"UGA\", \"UMI\", \"USA\", \"URY\", \"UZB\", \"VAT\", \"VCT\", \"VEN\", \"VGB\", \"VIR\", \"VNM\", \"VUT\", \"WLF\", \"WSM\", \"YEM\", \"MYT\", \"ZAF\", \"ZMB\", \"ZWE\")\n ) %>%\n # Expect that column `year` is of type: integer\n col_is_integer(\n columns = vars(year)\n ) %>%\n # Expect that values in `year` should be between `1960` and `2021`\n col_vals_between(\n columns = vars(year),\n left = 1960,\n right = 2021\n ) %>%\n # Expect that column `population` is of type: integer\n col_is_integer(\n columns = vars(population)\n ) %>%\n # Expect that values in `population` should be between `2646` and `1412360000`\n col_vals_between(\n columns = vars(population),\n left = 2646,\n right = 1412360000,\n na_pass = TRUE\n ) %>%\n # Expect entirely distinct rows across all columns\n rows_distinct() %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n country_name = \"character\",\n country_code_2 = \"character\",\n country_code_3 = \"character\",\n year = \"integer\",\n population = \"integer\"\n )\n ) %>%\n interrogate()\n```\n\n\n```{r print_agent, echo=FALSE}\nagent\n```\n" + [1] "---\ntitle: \"tbl\"\noutput: html_document\n---\n\n```{r setup, include=FALSE}\nknitr::opts_chunk$set(echo = TRUE)\nlibrary(pointblank)\n```\n\n\n```{r create_agent, echo=TRUE}\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `country_name` is of type: character\n col_is_character(\n columns = c(\"country_name\")\n ) %>%\n # Expect that values in `country_name` should be in the set of `Aruba`, `Afghanistan`, `Angola` (and 212 more)\n col_vals_in_set(\n columns = c(\"country_name\"),\n set = c(\"Aruba\", \"Afghanistan\", \"Angola\", \"Albania\", \"Andorra\", \"United Arab Emirates\", \"Argentina\", \"Armenia\", \"American Samoa\", \"Antigua and Barbuda\", \"Australia\", \"Austria\", \"Azerbaijan\", \"Burundi\", \"Belgium\", \"Benin\", \"Burkina Faso\", \"Bangladesh\", \"Bulgaria\", \"Bahrain\", \"Bahamas\", \"Bosnia and Herzegovina\", \"Belarus\", \"Belize\", \"Bermuda\", \"Bolivia\", \"Brazil\", \"Barbados\", \"Brunei Darussalam\", \"Bhutan\", \"Botswana\", \"Central African Republic\", \"Canada\", \"Switzerland\", \"Chile\", \"China\", \"Cote d'Ivoire\", \"Cameroon\", \"Congo (Democratic Republic)\", \"Congo\", \"Colombia\", \"Comoros\", \"Cabo Verde\", \"Costa Rica\", \"Cuba\", \"Curacao\", \"Cayman Islands\", \"Cyprus\", \"Czechia\", \"Germany\", \"Djibouti\", \"Dominica\", \"Denmark\", \"Dominican Republic\", \"Algeria\", \"Ecuador\", \"Egypt\", \"Eritrea\", \"Spain\", \"Estonia\", \"Ethiopia\", \"Finland\", \"Fiji\", \"France\", \"Faroe Islands\", \"Micronesia (Federated States)\", \"Gabon\", \"United Kingdom\", \"Georgia\", \"Ghana\", \"Gibraltar\", \"Guinea\", \"Gambia, The\", \"Guinea-Bissau\", \"Equatorial Guinea\", \"Greece\", \"Grenada\", \"Greenland\", \"Guatemala\", \"Guam\", \"Guyana\", \"Hong Kong\", \"Honduras\", \"Croatia\", \"Haiti\", \"Hungary\", \"Indonesia\", \"Isle of Man\", \"India\", \"Ireland\", \"Iran (Islamic Republic)\", \"Iraq\", \"Iceland\", \"Israel\", \"Italy\", \"Jamaica\", \"Jordan\", \"Japan\", \"Kazakhstan\", \"Kenya\", \"Kyrgyz Republic\", \"Cambodia\", \"Kiribati\", \"St. Kitts and Nevis\", \"Korea, Rep.\", \"Kuwait\", \"Lao PDR\", \"Lebanon\", \"Liberia\", \"Libya\", \"St. Lucia\", \"Liechtenstein\", \"Sri Lanka\", \"Lesotho\", \"Lithuania\", \"Luxembourg\", \"Latvia\", \"Macao\", \"St. Martin (French part)\", \"Morocco\", \"Monaco\", \"Moldova\", \"Madagascar\", \"Maldives\", \"Mexico\", \"Marshall Islands\", \"North Macedonia\", \"Mali\", \"Malta\", \"Myanmar\", \"Montenegro\", \"Mongolia\", \"Northern Mariana Islands\", \"Mozambique\", \"Mauritania\", \"Mauritius\", \"Malawi\", \"Malaysia\", \"Namibia\", \"New Caledonia\", \"Niger\", \"Nigeria\", \"Nicaragua\", \"Netherlands\", \"Norway\", \"Nepal\", \"Nauru\", \"New Zealand\", \"Oman\", \"Pakistan\", \"Panama\", \"Peru\", \"Philippines\", \"Palau\", \"Papua New Guinea\", \"Poland\", \"Puerto Rico\", \"Korea, Dem. People's Rep.\", \"Portugal\", \"Paraguay\", \"West Bank and Gaza\", \"French Polynesia\", \"Qatar\", \"Romania\", \"Russian Federation\", \"Rwanda\", \"Saudi Arabia\", \"Sudan\", \"Senegal\", \"Singapore\", \"Solomon Islands\", \"Sierra Leone\", \"El Salvador\", \"San Marino\", \"Somalia\", \"Serbia\", \"South Sudan\", \"Sao Tome and Principe\", \"Suriname\", \"Slovak Republic\", \"Slovenia\", \"Sweden\", \"Eswatini\", \"Sint Maarten (Dutch part)\", \"Seychelles\", \"Syrian Arab Republic\", \"Turks and Caicos Islands\", \"Chad\", \"Togo\", \"Thailand\", \"Tajikistan\", \"Turkmenistan\", \"Timor-Leste\", \"Tonga\", \"Trinidad and Tobago\", \"Tunisia\", \"Turkiye\", \"Tuvalu\", \"Tanzania\", \"Uganda\", \"Ukraine\", \"Uruguay\", \"United States\", \"Uzbekistan\", \"St. Vincent and the Grenadines\", \"Venezuela, RB\", \"British Virgin Islands\", \"Virgin Islands (U.S.)\", \"Vietnam\", \"Vanuatu\", \"Samoa\", \"Yemen\", \"South Africa\", \"Zambia\", \"Zimbabwe\")\n ) %>%\n # Expect that column `country_code_2` is of type: character\n col_is_character(\n columns = c(\"country_code_2\")\n ) %>%\n # Expect that values in `country_code_2` should be in the set of `AD`, `AE`, `AF` (and 246 more)\n col_vals_in_set(\n columns = c(\"country_code_2\"),\n set = c(\"AD\", \"AE\", \"AF\", \"AG\", \"AI\", \"AL\", \"AM\", \"AO\", \"AQ\", \"AR\", \"AS\", \"AT\", \"AU\", \"AW\", \"AX\", \"AZ\", \"BA\", \"BB\", \"BD\", \"BE\", \"BF\", \"BG\", \"BH\", \"BI\", \"BJ\", \"BL\", \"BM\", \"BN\", \"BO\", \"BQ\", \"BR\", \"BS\", \"BT\", \"BV\", \"BW\", \"BY\", \"BZ\", \"CA\", \"CC\", \"CD\", \"CF\", \"CG\", \"CH\", \"CI\", \"CK\", \"CL\", \"CM\", \"CN\", \"CO\", \"CR\", \"CU\", \"CV\", \"CW\", \"CX\", \"CY\", \"CZ\", \"DE\", \"DJ\", \"DK\", \"DM\", \"DO\", \"DZ\", \"EC\", \"EE\", \"EG\", \"EH\", \"ER\", \"ES\", \"ET\", \"FI\", \"FJ\", \"FK\", \"FM\", \"FO\", \"FR\", \"GA\", \"GB\", \"GD\", \"GE\", \"GF\", \"GG\", \"GH\", \"GI\", \"GL\", \"GM\", \"GN\", \"GP\", \"GQ\", \"GR\", \"GS\", \"GT\", \"GU\", \"GW\", \"GY\", \"HK\", \"HM\", \"HN\", \"HR\", \"HT\", \"HU\", \"ID\", \"IE\", \"IL\", \"IM\", \"IN\", \"IO\", \"IQ\", \"IR\", \"IS\", \"IT\", \"JE\", \"JM\", \"JO\", \"JP\", \"KE\", \"KG\", \"KH\", \"KI\", \"KM\", \"KN\", \"KP\", \"KR\", \"KW\", \"KY\", \"KZ\", \"LA\", \"LB\", \"LC\", \"LI\", \"LK\", \"LR\", \"LS\", \"LT\", \"LU\", \"LV\", \"LY\", \"MA\", \"MC\", \"MD\", \"ME\", \"MF\", \"MG\", \"MH\", \"MK\", \"ML\", \"MM\", \"MN\", \"MO\", \"MP\", \"MQ\", \"MR\", \"MS\", \"MT\", \"MU\", \"MV\", \"MW\", \"MX\", \"MY\", \"MZ\", \"NA\", \"NC\", \"NE\", \"NF\", \"NG\", \"NI\", \"NL\", \"NO\", \"NP\", \"NR\", \"NU\", \"NZ\", \"OM\", \"PA\", \"PE\", \"PF\", \"PG\", \"PH\", \"PK\", \"PL\", \"PM\", \"PN\", \"PR\", \"PS\", \"PT\", \"PW\", \"PY\", \"QA\", \"RE\", \"RO\", \"RS\", \"RU\", \"RW\", \"SA\", \"SB\", \"SC\", \"SD\", \"SE\", \"SG\", \"SH\", \"SI\", \"SJ\", \"SK\", \"SL\", \"SM\", \"SN\", \"SO\", \"SR\", \"SS\", \"ST\", \"SV\", \"SX\", \"SY\", \"SZ\", \"TC\", \"TD\", \"TF\", \"TG\", \"TH\", \"TJ\", \"TK\", \"TL\", \"TM\", \"TN\", \"TO\", \"TR\", \"TT\", \"TV\", \"TW\", \"TZ\", \"UA\", \"UG\", \"UM\", \"US\", \"UY\", \"UZ\", \"VA\", \"VC\", \"VE\", \"VG\", \"VI\", \"VN\", \"VU\", \"WF\", \"WS\", \"YE\", \"YT\", \"ZA\", \"ZM\", \"ZW\")\n ) %>%\n # Expect that column `country_code_3` is of type: character\n col_is_character(\n columns = c(\"country_code_3\")\n ) %>%\n # Expect that values in `country_code_3` should be in the set of `AND`, `ARE`, `AFG` (and 246 more)\n col_vals_in_set(\n columns = c(\"country_code_3\"),\n set = c(\"AND\", \"ARE\", \"AFG\", \"ATG\", \"AIA\", \"ALB\", \"ARM\", \"AGO\", \"ATA\", \"ARG\", \"ASM\", \"AUT\", \"AUS\", \"ABW\", \"ALA\", \"AZE\", \"BIH\", \"BRB\", \"BGD\", \"BEL\", \"BFA\", \"BGR\", \"BHR\", \"BDI\", \"BEN\", \"BLM\", \"BMU\", \"BRN\", \"BOL\", \"BES\", \"BRA\", \"BHS\", \"BTN\", \"BVT\", \"BWA\", \"BLR\", \"BLZ\", \"CAN\", \"CCK\", \"COD\", \"CAF\", \"COG\", \"CHE\", \"CIV\", \"COK\", \"CHL\", \"CMR\", \"CHN\", \"COL\", \"CRI\", \"CUB\", \"CPV\", \"CUW\", \"CXR\", \"CYP\", \"CZE\", \"DEU\", \"DJI\", \"DNK\", \"DMA\", \"DOM\", \"DZA\", \"ECU\", \"EST\", \"EGY\", \"ESH\", \"ERI\", \"ESP\", \"ETH\", \"FIN\", \"FJI\", \"FLK\", \"FSM\", \"FRO\", \"FRA\", \"GAB\", \"GBR\", \"GRD\", \"GEO\", \"GUF\", \"GGY\", \"GHA\", \"GIB\", \"GRL\", \"GMB\", \"GIN\", \"GLP\", \"GNQ\", \"GRC\", \"SGS\", \"GTM\", \"GUM\", \"GNB\", \"GUY\", \"HKG\", \"HMD\", \"HND\", \"HRV\", \"HTI\", \"HUN\", \"IDN\", \"IRL\", \"ISR\", \"IMN\", \"IND\", \"IOT\", \"IRQ\", \"IRN\", \"ISL\", \"ITA\", \"JEY\", \"JAM\", \"JOR\", \"JPN\", \"KEN\", \"KGZ\", \"KHM\", \"KIR\", \"COM\", \"KNA\", \"PRK\", \"KOR\", \"KWT\", \"CYM\", \"KAZ\", \"LAO\", \"LBN\", \"LCA\", \"LIE\", \"LKA\", \"LBR\", \"LSO\", \"LTU\", \"LUX\", \"LVA\", \"LBY\", \"MAR\", \"MCO\", \"MDA\", \"MNE\", \"MAF\", \"MDG\", \"MHL\", \"MKD\", \"MLI\", \"MMR\", \"MNG\", \"MAC\", \"MNP\", \"MTQ\", \"MRT\", \"MSR\", \"MLT\", \"MUS\", \"MDV\", \"MWI\", \"MEX\", \"MYS\", \"MOZ\", \"NAM\", \"NCL\", \"NER\", \"NFK\", \"NGA\", \"NIC\", \"NLD\", \"NOR\", \"NPL\", \"NRU\", \"NIU\", \"NZL\", \"OMN\", \"PAN\", \"PER\", \"PYF\", \"PNG\", \"PHL\", \"PAK\", \"POL\", \"SPM\", \"PCN\", \"PRI\", \"PSE\", \"PRT\", \"PLW\", \"PRY\", \"QAT\", \"REU\", \"ROU\", \"SRB\", \"RUS\", \"RWA\", \"SAU\", \"SLB\", \"SYC\", \"SDN\", \"SWE\", \"SGP\", \"SHN\", \"SVN\", \"SJM\", \"SVK\", \"SLE\", \"SMR\", \"SEN\", \"SOM\", \"SUR\", \"SSD\", \"STP\", \"SLV\", \"SXM\", \"SYR\", \"SWZ\", \"TCA\", \"TCD\", \"ATF\", \"TGO\", \"THA\", \"TJK\", \"TKL\", \"TLS\", \"TKM\", \"TUN\", \"TON\", \"TUR\", \"TTO\", \"TUV\", \"TWN\", \"TZA\", \"UKR\", \"UGA\", \"UMI\", \"USA\", \"URY\", \"UZB\", \"VAT\", \"VCT\", \"VEN\", \"VGB\", \"VIR\", \"VNM\", \"VUT\", \"WLF\", \"WSM\", \"YEM\", \"MYT\", \"ZAF\", \"ZMB\", \"ZWE\")\n ) %>%\n # Expect that column `year` is of type: integer\n col_is_integer(\n columns = c(\"year\")\n ) %>%\n # Expect that values in `year` should be between `1960` and `2022`\n col_vals_between(\n columns = c(\"year\"),\n left = 1960,\n right = 2022\n ) %>%\n # Expect that column `population` is of type: integer\n col_is_integer(\n columns = c(\"population\")\n ) %>%\n # Expect that values in `population` should be between `2646` and `1417173173`\n col_vals_between(\n columns = c(\"population\"),\n left = 2646,\n right = 1417173200,\n na_pass = TRUE\n ) %>%\n # Expect entirely distinct rows across `country_name, country_code_2, country_code_3, year, population`\n rows_distinct(\n columns = c(\"country_name\", \"country_code_2\", \"country_code_3\", \"year\", \"population\")\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n country_name = \"character\",\n country_code_2 = \"character\",\n country_code_3 = \"character\",\n year = \"integer\",\n population = \"integer\"\n )\n ) %>%\n interrogate()\n```\n\n\n```{r print_agent, echo=FALSE}\nagent\n```\n" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "---\ntitle: \"tbl\"\noutput: html_document\n---\n\n```{r setup, include=FALSE}\nknitr::opts_chunk$set(echo = TRUE)\nlibrary(pointblank)\n```\n\n\n```{r create_agent, echo=TRUE}\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `latitude` is of type: numeric\n col_is_numeric(\n columns = vars(latitude)\n ) %>%\n # Expect that values in `latitude` should be between `-90` and `90`\n col_vals_between(\n columns = vars(latitude),\n left = -90,\n right = 90\n ) %>%\n # Expect that column `month` is of type: factor\n col_is_factor(\n columns = vars(month)\n ) %>%\n # Expect that column `tst` is of type: character\n col_is_character(\n columns = vars(tst)\n ) %>%\n # Expect that column `sza` is of type: numeric\n col_is_numeric(\n columns = vars(sza)\n ) %>%\n # Expect that values in `sza` should be between `1.9` and `89.7`\n col_vals_between(\n columns = vars(sza),\n left = 1.9,\n right = 89.7,\n na_pass = TRUE\n ) %>%\n # Expect entirely distinct rows across all columns\n rows_distinct() %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n latitude = \"numeric\",\n month = \"factor\",\n tst = \"character\",\n sza = \"numeric\"\n )\n ) %>%\n interrogate()\n```\n\n\n```{r print_agent, echo=FALSE}\nagent\n```\n" + [1] "---\ntitle: \"tbl\"\noutput: html_document\n---\n\n```{r setup, include=FALSE}\nknitr::opts_chunk$set(echo = TRUE)\nlibrary(pointblank)\n```\n\n\n```{r create_agent, echo=TRUE}\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `latitude` is of type: numeric\n col_is_numeric(\n columns = c(\"latitude\")\n ) %>%\n # Expect that values in `latitude` should be between `-90` and `90`\n col_vals_between(\n columns = c(\"latitude\"),\n left = -90,\n right = 90\n ) %>%\n # Expect that column `month` is of type: factor\n col_is_factor(\n columns = c(\"month\")\n ) %>%\n # Expect that column `tst` is of type: character\n col_is_character(\n columns = c(\"tst\")\n ) %>%\n # Expect that column `sza` is of type: numeric\n col_is_numeric(\n columns = c(\"sza\")\n ) %>%\n # Expect that values in `sza` should be between `1.9` and `89.7`\n col_vals_between(\n columns = c(\"sza\"),\n left = 1.9,\n right = 89.7,\n na_pass = TRUE\n ) %>%\n # Expect entirely distinct rows across `latitude, month, tst, sza`\n rows_distinct(\n columns = c(\"latitude\", \"month\", \"tst\", \"sza\")\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n latitude = \"numeric\",\n month = \"factor\",\n tst = \"character\",\n sza = \"numeric\"\n )\n ) %>%\n interrogate()\n```\n\n\n```{r print_agent, echo=FALSE}\nagent\n```\n" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "---\ntitle: \"tbl\"\noutput: html_document\n---\n\n```{r setup, include=FALSE}\nknitr::opts_chunk$set(echo = TRUE)\nlibrary(pointblank)\n```\n\n\n```{r create_agent, echo=TRUE}\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `mfr` is of type: character\n col_is_character(\n columns = vars(mfr)\n ) %>%\n # Expect that column `model` is of type: character\n col_is_character(\n columns = vars(model)\n ) %>%\n # Expect that column `year` is of type: numeric\n col_is_numeric(\n columns = vars(year)\n ) %>%\n # Expect that values in `year` should be between `2014` and `2017`\n col_vals_between(\n columns = vars(year),\n left = 2014,\n right = 2017\n ) %>%\n # Expect that column `trim` is of type: character\n col_is_character(\n columns = vars(trim)\n ) %>%\n # Expect that column `bdy_style` is of type: character\n col_is_character(\n columns = vars(bdy_style)\n ) %>%\n # Expect that column `hp` is of type: numeric\n col_is_numeric(\n columns = vars(hp)\n ) %>%\n # Expect that values in `hp` should be between `259` and `949`\n col_vals_between(\n columns = vars(hp),\n left = 259,\n right = 949\n ) %>%\n # Expect that column `hp_rpm` is of type: numeric\n col_is_numeric(\n columns = vars(hp_rpm)\n ) %>%\n # Expect that values in `hp_rpm` should be between `5000` and `9000`\n col_vals_between(\n columns = vars(hp_rpm),\n left = 5000,\n right = 9000\n ) %>%\n # Expect that column `trq` is of type: numeric\n col_is_numeric(\n columns = vars(trq)\n ) %>%\n # Expect that values in `trq` should be between `243` and `664`\n col_vals_between(\n columns = vars(trq),\n left = 243,\n right = 664\n ) %>%\n # Expect that column `trq_rpm` is of type: numeric\n col_is_numeric(\n columns = vars(trq_rpm)\n ) %>%\n # Expect that values in `trq_rpm` should be between `1400` and `6750`\n col_vals_between(\n columns = vars(trq_rpm),\n left = 1400,\n right = 6750,\n na_pass = TRUE\n ) %>%\n # Expect that column `mpg_c` is of type: numeric\n col_is_numeric(\n columns = vars(mpg_c)\n ) %>%\n # Expect that values in `mpg_c` should be between `11` and `28`\n col_vals_between(\n columns = vars(mpg_c),\n left = 11,\n right = 28,\n na_pass = TRUE\n ) %>%\n # Expect that column `mpg_h` is of type: numeric\n col_is_numeric(\n columns = vars(mpg_h)\n ) %>%\n # Expect that values in `mpg_h` should be between `16` and `30`\n col_vals_between(\n columns = vars(mpg_h),\n left = 16,\n right = 30,\n na_pass = TRUE\n ) %>%\n # Expect that column `drivetrain` is of type: character\n col_is_character(\n columns = vars(drivetrain)\n ) %>%\n # Expect that column `trsmn` is of type: character\n col_is_character(\n columns = vars(trsmn)\n ) %>%\n # Expect that column `ctry_origin` is of type: character\n col_is_character(\n columns = vars(ctry_origin)\n ) %>%\n # Expect that values in `ctry_origin` should be in the set of `United States`, `Italy`, `Japan` (and 2 more)\n col_vals_in_set(\n columns = vars(ctry_origin),\n set = c(\"United States\", \"Italy\", \"Japan\", \"United Kingdom\", \"Germany\")\n ) %>%\n # Expect that column `msrp` is of type: numeric\n col_is_numeric(\n columns = vars(msrp)\n ) %>%\n # Expect that values in `msrp` should be between `53900` and `1416362`\n col_vals_between(\n columns = vars(msrp),\n left = 53900,\n right = 1416362\n ) %>%\n # Expect entirely distinct rows across all columns\n rows_distinct() %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n mfr = \"character\",\n model = \"character\",\n year = \"numeric\",\n trim = \"character\",\n bdy_style = \"character\",\n hp = \"numeric\",\n hp_rpm = \"numeric\",\n trq = \"numeric\",\n trq_rpm = \"numeric\",\n mpg_c = \"numeric\",\n mpg_h = \"numeric\",\n drivetrain = \"character\",\n trsmn = \"character\",\n ctry_origin = \"character\",\n msrp = \"numeric\"\n )\n ) %>%\n interrogate()\n```\n\n\n```{r print_agent, echo=FALSE}\nagent\n```\n" + [1] "---\ntitle: \"tbl\"\noutput: html_document\n---\n\n```{r setup, include=FALSE}\nknitr::opts_chunk$set(echo = TRUE)\nlibrary(pointblank)\n```\n\n\n```{r create_agent, echo=TRUE}\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `mfr` is of type: character\n col_is_character(\n columns = c(\"mfr\")\n ) %>%\n # Expect that column `model` is of type: character\n col_is_character(\n columns = c(\"model\")\n ) %>%\n # Expect that column `year` is of type: numeric\n col_is_numeric(\n columns = c(\"year\")\n ) %>%\n # Expect that values in `year` should be between `2014` and `2017`\n col_vals_between(\n columns = c(\"year\"),\n left = 2014,\n right = 2017\n ) %>%\n # Expect that column `trim` is of type: character\n col_is_character(\n columns = c(\"trim\")\n ) %>%\n # Expect that column `bdy_style` is of type: character\n col_is_character(\n columns = c(\"bdy_style\")\n ) %>%\n # Expect that column `hp` is of type: numeric\n col_is_numeric(\n columns = c(\"hp\")\n ) %>%\n # Expect that values in `hp` should be between `259` and `949`\n col_vals_between(\n columns = c(\"hp\"),\n left = 259,\n right = 949\n ) %>%\n # Expect that column `hp_rpm` is of type: numeric\n col_is_numeric(\n columns = c(\"hp_rpm\")\n ) %>%\n # Expect that values in `hp_rpm` should be between `5000` and `9000`\n col_vals_between(\n columns = c(\"hp_rpm\"),\n left = 5000,\n right = 9000\n ) %>%\n # Expect that column `trq` is of type: numeric\n col_is_numeric(\n columns = c(\"trq\")\n ) %>%\n # Expect that values in `trq` should be between `243` and `664`\n col_vals_between(\n columns = c(\"trq\"),\n left = 243,\n right = 664\n ) %>%\n # Expect that column `trq_rpm` is of type: numeric\n col_is_numeric(\n columns = c(\"trq_rpm\")\n ) %>%\n # Expect that values in `trq_rpm` should be between `1400` and `6750`\n col_vals_between(\n columns = c(\"trq_rpm\"),\n left = 1400,\n right = 6750,\n na_pass = TRUE\n ) %>%\n # Expect that column `mpg_c` is of type: numeric\n col_is_numeric(\n columns = c(\"mpg_c\")\n ) %>%\n # Expect that values in `mpg_c` should be between `11` and `28`\n col_vals_between(\n columns = c(\"mpg_c\"),\n left = 11,\n right = 28,\n na_pass = TRUE\n ) %>%\n # Expect that column `mpg_h` is of type: numeric\n col_is_numeric(\n columns = c(\"mpg_h\")\n ) %>%\n # Expect that values in `mpg_h` should be between `16` and `30`\n col_vals_between(\n columns = c(\"mpg_h\"),\n left = 16,\n right = 30,\n na_pass = TRUE\n ) %>%\n # Expect that column `drivetrain` is of type: character\n col_is_character(\n columns = c(\"drivetrain\")\n ) %>%\n # Expect that column `trsmn` is of type: character\n col_is_character(\n columns = c(\"trsmn\")\n ) %>%\n # Expect that column `ctry_origin` is of type: character\n col_is_character(\n columns = c(\"ctry_origin\")\n ) %>%\n # Expect that values in `ctry_origin` should be in the set of `United States`, `Italy`, `Japan` (and 2 more)\n col_vals_in_set(\n columns = c(\"ctry_origin\"),\n set = c(\"United States\", \"Italy\", \"Japan\", \"United Kingdom\", \"Germany\")\n ) %>%\n # Expect that column `msrp` is of type: numeric\n col_is_numeric(\n columns = c(\"msrp\")\n ) %>%\n # Expect that values in `msrp` should be between `53900` and `1416362`\n col_vals_between(\n columns = c(\"msrp\"),\n left = 53900,\n right = 1416362\n ) %>%\n # Expect entirely distinct rows across `mfr, model, year, trim, bdy_style, hp, hp_rpm, trq, trq_rpm, mpg_c, mpg_h, drivetrain, trsmn, ctry_origin, msrp`\n rows_distinct(\n columns = c(\"mfr\", \"model\", \"year\", \"trim\", \"bdy_style\", \"hp\", \"hp_rpm\", \"trq\", \"trq_rpm\", \"mpg_c\", \"mpg_h\", \"drivetrain\", \"trsmn\", \"ctry_origin\", \"msrp\")\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n mfr = \"character\",\n model = \"character\",\n year = \"numeric\",\n trim = \"character\",\n bdy_style = \"character\",\n hp = \"numeric\",\n hp_rpm = \"numeric\",\n trq = \"numeric\",\n trq_rpm = \"numeric\",\n mpg_c = \"numeric\",\n mpg_h = \"numeric\",\n drivetrain = \"character\",\n trsmn = \"character\",\n ctry_origin = \"character\",\n msrp = \"numeric\"\n )\n ) %>%\n interrogate()\n```\n\n\n```{r print_agent, echo=FALSE}\nagent\n```\n" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "---\ntitle: \"tbl\"\noutput: html_document\n---\n\n```{r setup, include=FALSE}\nknitr::opts_chunk$set(echo = TRUE)\nlibrary(pointblank)\n```\n\n\n```{r create_agent, echo=TRUE}\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `open` is of type: numeric\n col_is_numeric(\n columns = vars(open)\n ) %>%\n # Expect that values in `open` should be between `16.66` and `2130.3601`\n col_vals_between(\n columns = vars(open),\n left = 16.66,\n right = 2130.3601\n ) %>%\n # Expect that column `high` is of type: numeric\n col_is_numeric(\n columns = vars(high)\n ) %>%\n # Expect that values in `high` should be between `16.66` and `2134.72`\n col_vals_between(\n columns = vars(high),\n left = 16.66,\n right = 2134.72\n ) %>%\n # Expect that column `low` is of type: numeric\n col_is_numeric(\n columns = vars(low)\n ) %>%\n # Expect that values in `low` should be between `16.66` and `2126.0601`\n col_vals_between(\n columns = vars(low),\n left = 16.66,\n right = 2126.0601\n ) %>%\n # Expect that column `close` is of type: numeric\n col_is_numeric(\n columns = vars(close)\n ) %>%\n # Expect that values in `close` should be between `16.66` and `2130.8201`\n col_vals_between(\n columns = vars(close),\n left = 16.66,\n right = 2130.8201\n ) %>%\n # Expect that column `volume` is of type: numeric\n col_is_numeric(\n columns = vars(volume)\n ) %>%\n # Expect that values in `volume` should be between `680000` and `11456230400`\n col_vals_between(\n columns = vars(volume),\n left = 680000,\n right = 11456230000\n ) %>%\n # Expect that column `adj_close` is of type: numeric\n col_is_numeric(\n columns = vars(adj_close)\n ) %>%\n # Expect that values in `adj_close` should be between `16.66` and `2130.8201`\n col_vals_between(\n columns = vars(adj_close),\n left = 16.66,\n right = 2130.8201\n ) %>%\n # Expect entirely distinct rows across all columns\n rows_distinct() %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n date = \"Date\",\n open = \"numeric\",\n high = \"numeric\",\n low = \"numeric\",\n close = \"numeric\",\n volume = \"numeric\",\n adj_close = \"numeric\"\n )\n ) %>%\n interrogate()\n```\n\n\n```{r print_agent, echo=FALSE}\nagent\n```\n" + [1] "---\ntitle: \"tbl\"\noutput: html_document\n---\n\n```{r setup, include=FALSE}\nknitr::opts_chunk$set(echo = TRUE)\nlibrary(pointblank)\n```\n\n\n```{r create_agent, echo=TRUE}\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `open` is of type: numeric\n col_is_numeric(\n columns = c(\"open\")\n ) %>%\n # Expect that values in `open` should be between `16.66` and `2130.3601`\n col_vals_between(\n columns = c(\"open\"),\n left = 16.66,\n right = 2130.3601\n ) %>%\n # Expect that column `high` is of type: numeric\n col_is_numeric(\n columns = c(\"high\")\n ) %>%\n # Expect that values in `high` should be between `16.66` and `2134.72`\n col_vals_between(\n columns = c(\"high\"),\n left = 16.66,\n right = 2134.72\n ) %>%\n # Expect that column `low` is of type: numeric\n col_is_numeric(\n columns = c(\"low\")\n ) %>%\n # Expect that values in `low` should be between `16.66` and `2126.0601`\n col_vals_between(\n columns = c(\"low\"),\n left = 16.66,\n right = 2126.0601\n ) %>%\n # Expect that column `close` is of type: numeric\n col_is_numeric(\n columns = c(\"close\")\n ) %>%\n # Expect that values in `close` should be between `16.66` and `2130.8201`\n col_vals_between(\n columns = c(\"close\"),\n left = 16.66,\n right = 2130.8201\n ) %>%\n # Expect that column `volume` is of type: numeric\n col_is_numeric(\n columns = c(\"volume\")\n ) %>%\n # Expect that values in `volume` should be between `680000` and `11456230400`\n col_vals_between(\n columns = c(\"volume\"),\n left = 680000,\n right = 11456230000\n ) %>%\n # Expect that column `adj_close` is of type: numeric\n col_is_numeric(\n columns = c(\"adj_close\")\n ) %>%\n # Expect that values in `adj_close` should be between `16.66` and `2130.8201`\n col_vals_between(\n columns = c(\"adj_close\"),\n left = 16.66,\n right = 2130.8201\n ) %>%\n # Expect entirely distinct rows across `date, open, high, low, close, volume, adj_close`\n rows_distinct(\n columns = c(\"date\", \"open\", \"high\", \"low\", \"close\", \"volume\", \"adj_close\")\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n date = \"Date\",\n open = \"numeric\",\n high = \"numeric\",\n low = \"numeric\",\n close = \"numeric\",\n volume = \"numeric\",\n adj_close = \"numeric\"\n )\n ) %>%\n interrogate()\n```\n\n\n```{r print_agent, echo=FALSE}\nagent\n```\n" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "---\ntitle: \"tbl\"\noutput: html_document\n---\n\n```{r setup, include=FALSE}\nknitr::opts_chunk$set(echo = TRUE)\nlibrary(pointblank)\n```\n\n\n```{r create_agent, echo=TRUE}\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `id` is of type: character\n col_is_character(\n columns = vars(id)\n ) %>%\n # Expect that column `date` is of type: character\n col_is_character(\n columns = vars(date)\n ) %>%\n # Expect that column `time` is of type: character\n col_is_character(\n columns = vars(time)\n ) %>%\n # Expect that column `name` is of type: character\n col_is_character(\n columns = vars(name)\n ) %>%\n # Expect that column `size` is of type: character\n col_is_character(\n columns = vars(size)\n ) %>%\n # Expect that column `type` is of type: character\n col_is_character(\n columns = vars(type)\n ) %>%\n # Expect that column `price` is of type: numeric\n col_is_numeric(\n columns = vars(price)\n ) %>%\n # Expect that values in `price` should be between `9.75` and `35.95`\n col_vals_between(\n columns = vars(price),\n left = 9.75,\n right = 35.95\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n id = \"character\",\n date = \"character\",\n time = \"character\",\n name = \"character\",\n size = \"character\",\n type = \"character\",\n price = \"numeric\"\n )\n ) %>%\n interrogate()\n```\n\n\n```{r print_agent, echo=FALSE}\nagent\n```\n" + [1] "---\ntitle: \"tbl\"\noutput: html_document\n---\n\n```{r setup, include=FALSE}\nknitr::opts_chunk$set(echo = TRUE)\nlibrary(pointblank)\n```\n\n\n```{r create_agent, echo=TRUE}\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `id` is of type: character\n col_is_character(\n columns = c(\"id\")\n ) %>%\n # Expect that column `date` is of type: character\n col_is_character(\n columns = c(\"date\")\n ) %>%\n # Expect that column `time` is of type: character\n col_is_character(\n columns = c(\"time\")\n ) %>%\n # Expect that column `name` is of type: character\n col_is_character(\n columns = c(\"name\")\n ) %>%\n # Expect that column `size` is of type: character\n col_is_character(\n columns = c(\"size\")\n ) %>%\n # Expect that column `type` is of type: character\n col_is_character(\n columns = c(\"type\")\n ) %>%\n # Expect that column `price` is of type: numeric\n col_is_numeric(\n columns = c(\"price\")\n ) %>%\n # Expect that values in `price` should be between `9.75` and `35.95`\n col_vals_between(\n columns = c(\"price\"),\n left = 9.75,\n right = 35.95\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n id = \"character\",\n date = \"character\",\n time = \"character\",\n name = \"character\",\n size = \"character\",\n type = \"character\",\n price = \"numeric\"\n )\n ) %>%\n interrogate()\n```\n\n\n```{r print_agent, echo=FALSE}\nagent\n```\n" --- Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "---\ntitle: \"tbl\"\noutput: html_document\n---\n\n```{r setup, include=FALSE}\nknitr::opts_chunk$set(echo = TRUE)\nlibrary(pointblank)\n```\n\n\n```{r create_agent, echo=TRUE}\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `num` is of type: numeric\n col_is_numeric(\n columns = vars(num)\n ) %>%\n # Expect that values in `num` should be between `0.1111` and `8880000`\n col_vals_between(\n columns = vars(num),\n left = 0.1111,\n right = 8880000,\n na_pass = TRUE\n ) %>%\n # Expect that column `char` is of type: character\n col_is_character(\n columns = vars(char)\n ) %>%\n # Expect that column `fctr` is of type: factor\n col_is_factor(\n columns = vars(fctr)\n ) %>%\n # Expect that column `date` is of type: character\n col_is_character(\n columns = vars(date)\n ) %>%\n # Expect that column `time` is of type: character\n col_is_character(\n columns = vars(time)\n ) %>%\n # Expect that column `datetime` is of type: character\n col_is_character(\n columns = vars(datetime)\n ) %>%\n # Expect that column `currency` is of type: numeric\n col_is_numeric(\n columns = vars(currency)\n ) %>%\n # Expect that values in `currency` should be between `0.44` and `65100`\n col_vals_between(\n columns = vars(currency),\n left = 0.44,\n right = 65100,\n na_pass = TRUE\n ) %>%\n # Expect that column `row` is of type: character\n col_is_character(\n columns = vars(row)\n ) %>%\n # Expect that column `group` is of type: character\n col_is_character(\n columns = vars(group)\n ) %>%\n # Expect entirely distinct rows across all columns\n rows_distinct() %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n num = \"numeric\",\n char = \"character\",\n fctr = \"factor\",\n date = \"character\",\n time = \"character\",\n datetime = \"character\",\n currency = \"numeric\",\n row = \"character\",\n group = \"character\"\n )\n ) %>%\n interrogate()\n```\n\n\n```{r print_agent, echo=FALSE}\nagent\n```\n" + [1] "---\ntitle: \"tbl\"\noutput: html_document\n---\n\n```{r setup, include=FALSE}\nknitr::opts_chunk$set(echo = TRUE)\nlibrary(pointblank)\n```\n\n\n```{r create_agent, echo=TRUE}\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n # Expect that column `num` is of type: numeric\n col_is_numeric(\n columns = c(\"num\")\n ) %>%\n # Expect that values in `num` should be between `0.1111` and `8880000`\n col_vals_between(\n columns = c(\"num\"),\n left = 0.1111,\n right = 8880000,\n na_pass = TRUE\n ) %>%\n # Expect that column `char` is of type: character\n col_is_character(\n columns = c(\"char\")\n ) %>%\n # Expect that column `fctr` is of type: factor\n col_is_factor(\n columns = c(\"fctr\")\n ) %>%\n # Expect that column `date` is of type: character\n col_is_character(\n columns = c(\"date\")\n ) %>%\n # Expect that column `time` is of type: character\n col_is_character(\n columns = c(\"time\")\n ) %>%\n # Expect that column `datetime` is of type: character\n col_is_character(\n columns = c(\"datetime\")\n ) %>%\n # Expect that column `currency` is of type: numeric\n col_is_numeric(\n columns = c(\"currency\")\n ) %>%\n # Expect that values in `currency` should be between `0.44` and `65100`\n col_vals_between(\n columns = c(\"currency\"),\n left = 0.44,\n right = 65100,\n na_pass = TRUE\n ) %>%\n # Expect that column `row` is of type: character\n col_is_character(\n columns = c(\"row\")\n ) %>%\n # Expect that column `group` is of type: character\n col_is_character(\n columns = c(\"group\")\n ) %>%\n # Expect entirely distinct rows across `num, char, fctr, date, time, datetime, currency, row, group`\n rows_distinct(\n columns = c(\"num\", \"char\", \"fctr\", \"date\", \"time\", \"datetime\", \"currency\", \"row\", \"group\")\n ) %>%\n # Expect that column schemas match\n col_schema_match(\n schema = col_schema(\n num = \"numeric\",\n char = \"character\",\n fctr = \"factor\",\n date = \"character\",\n time = \"character\",\n datetime = \"character\",\n currency = \"numeric\",\n row = \"character\",\n group = \"character\"\n )\n ) %>%\n interrogate()\n```\n\n\n```{r print_agent, echo=FALSE}\nagent\n```\n" # draft validations for data tables can be generated without comments Code readLines(con = path) %>% paste0(collapse = "\n") Output - [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n col_is_character(\n columns = vars(country_name)\n ) %>%\n col_vals_in_set(\n columns = vars(country_name),\n set = c(\"Aruba\", \"Afghanistan\", \"Angola\", \"Albania\", \"Andorra\", \"United Arab Emirates\", \"Argentina\", \"Armenia\", \"American Samoa\", \"Antigua and Barbuda\", \"Australia\", \"Austria\", \"Azerbaijan\", \"Burundi\", \"Belgium\", \"Benin\", \"Burkina Faso\", \"Bangladesh\", \"Bulgaria\", \"Bahrain\", \"Bahamas\", \"Bosnia and Herzegovina\", \"Belarus\", \"Belize\", \"Bermuda\", \"Bolivia\", \"Brazil\", \"Barbados\", \"Brunei Darussalam\", \"Bhutan\", \"Botswana\", \"Central African Republic\", \"Canada\", \"Switzerland\", \"Chile\", \"China\", \"Cote d'Ivoire\", \"Cameroon\", \"Congo (Democratic Republic)\", \"Congo\", \"Colombia\", \"Comoros\", \"Cabo Verde\", \"Costa Rica\", \"Cuba\", \"Curacao\", \"Cayman Islands\", \"Cyprus\", \"Czechia\", \"Germany\", \"Djibouti\", \"Dominica\", \"Denmark\", \"Dominican Republic\", \"Algeria\", \"Ecuador\", \"Egypt\", \"Eritrea\", \"Spain\", \"Estonia\", \"Ethiopia\", \"Finland\", \"Fiji\", \"France\", \"Faroe Islands\", \"Micronesia (Federated States)\", \"Gabon\", \"United Kingdom\", \"Georgia\", \"Ghana\", \"Gibraltar\", \"Guinea\", \"Gambia, The\", \"Guinea-Bissau\", \"Equatorial Guinea\", \"Greece\", \"Grenada\", \"Greenland\", \"Guatemala\", \"Guam\", \"Guyana\", \"Hong Kong\", \"Honduras\", \"Croatia\", \"Haiti\", \"Hungary\", \"Indonesia\", \"Isle of Man\", \"India\", \"Ireland\", \"Iran (Islamic Republic)\", \"Iraq\", \"Iceland\", \"Israel\", \"Italy\", \"Jamaica\", \"Jordan\", \"Japan\", \"Kazakhstan\", \"Kenya\", \"Kyrgyz Republic\", \"Cambodia\", \"Kiribati\", \"St. Kitts and Nevis\", \"Korea, Rep.\", \"Kuwait\", \"Lao PDR\", \"Lebanon\", \"Liberia\", \"Libya\", \"St. Lucia\", \"Liechtenstein\", \"Sri Lanka\", \"Lesotho\", \"Lithuania\", \"Luxembourg\", \"Latvia\", \"Macao\", \"St. Martin (French part)\", \"Morocco\", \"Monaco\", \"Moldova\", \"Madagascar\", \"Maldives\", \"Mexico\", \"Marshall Islands\", \"North Macedonia\", \"Mali\", \"Malta\", \"Myanmar\", \"Montenegro\", \"Mongolia\", \"Northern Mariana Islands\", \"Mozambique\", \"Mauritania\", \"Mauritius\", \"Malawi\", \"Malaysia\", \"Namibia\", \"New Caledonia\", \"Niger\", \"Nigeria\", \"Nicaragua\", \"Netherlands\", \"Norway\", \"Nepal\", \"Nauru\", \"New Zealand\", \"Oman\", \"Pakistan\", \"Panama\", \"Peru\", \"Philippines\", \"Palau\", \"Papua New Guinea\", \"Poland\", \"Puerto Rico\", \"Korea, Dem. People's Rep.\", \"Portugal\", \"Paraguay\", \"West Bank and Gaza\", \"French Polynesia\", \"Qatar\", \"Romania\", \"Russian Federation\", \"Rwanda\", \"Saudi Arabia\", \"Sudan\", \"Senegal\", \"Singapore\", \"Solomon Islands\", \"Sierra Leone\", \"El Salvador\", \"San Marino\", \"Somalia\", \"Serbia\", \"South Sudan\", \"Sao Tome and Principe\", \"Suriname\", \"Slovak Republic\", \"Slovenia\", \"Sweden\", \"Eswatini\", \"Sint Maarten (Dutch part)\", \"Seychelles\", \"Syrian Arab Republic\", \"Turks and Caicos Islands\", \"Chad\", \"Togo\", \"Thailand\", \"Tajikistan\", \"Turkmenistan\", \"Timor-Leste\", \"Tonga\", \"Trinidad and Tobago\", \"Tunisia\", \"Turkiye\", \"Tuvalu\", \"Tanzania\", \"Uganda\", \"Ukraine\", \"Uruguay\", \"United States\", \"Uzbekistan\", \"St. Vincent and the Grenadines\", \"Venezuela, RB\", \"British Virgin Islands\", \"Virgin Islands (U.S.)\", \"Vietnam\", \"Vanuatu\", \"Samoa\", \"Yemen\", \"South Africa\", \"Zambia\", \"Zimbabwe\")\n ) %>%\n col_is_character(\n columns = vars(country_code_2)\n ) %>%\n col_vals_in_set(\n columns = vars(country_code_2),\n set = c(\"AD\", \"AE\", \"AF\", \"AG\", \"AI\", \"AL\", \"AM\", \"AO\", \"AQ\", \"AR\", \"AS\", \"AT\", \"AU\", \"AW\", \"AX\", \"AZ\", \"BA\", \"BB\", \"BD\", \"BE\", \"BF\", \"BG\", \"BH\", \"BI\", \"BJ\", \"BL\", \"BM\", \"BN\", \"BO\", \"BQ\", \"BR\", \"BS\", \"BT\", \"BV\", \"BW\", \"BY\", \"BZ\", \"CA\", \"CC\", \"CD\", \"CF\", \"CG\", \"CH\", \"CI\", \"CK\", \"CL\", \"CM\", \"CN\", \"CO\", \"CR\", \"CU\", \"CV\", \"CW\", \"CX\", \"CY\", \"CZ\", \"DE\", \"DJ\", \"DK\", \"DM\", \"DO\", \"DZ\", \"EC\", \"EE\", \"EG\", \"EH\", \"ER\", \"ES\", \"ET\", \"FI\", \"FJ\", \"FK\", \"FM\", \"FO\", \"FR\", \"GA\", \"GB\", \"GD\", \"GE\", \"GF\", \"GG\", \"GH\", \"GI\", \"GL\", \"GM\", \"GN\", \"GP\", \"GQ\", \"GR\", \"GS\", \"GT\", \"GU\", \"GW\", \"GY\", \"HK\", \"HM\", \"HN\", \"HR\", \"HT\", \"HU\", \"ID\", \"IE\", \"IL\", \"IM\", \"IN\", \"IO\", \"IQ\", \"IR\", \"IS\", \"IT\", \"JE\", \"JM\", \"JO\", \"JP\", \"KE\", \"KG\", \"KH\", \"KI\", \"KM\", \"KN\", \"KP\", \"KR\", \"KW\", \"KY\", \"KZ\", \"LA\", \"LB\", \"LC\", \"LI\", \"LK\", \"LR\", \"LS\", \"LT\", \"LU\", \"LV\", \"LY\", \"MA\", \"MC\", \"MD\", \"ME\", \"MF\", \"MG\", \"MH\", \"MK\", \"ML\", \"MM\", \"MN\", \"MO\", \"MP\", \"MQ\", \"MR\", \"MS\", \"MT\", \"MU\", \"MV\", \"MW\", \"MX\", \"MY\", \"MZ\", \"NA\", \"NC\", \"NE\", \"NF\", \"NG\", \"NI\", \"NL\", \"NO\", \"NP\", \"NR\", \"NU\", \"NZ\", \"OM\", \"PA\", \"PE\", \"PF\", \"PG\", \"PH\", \"PK\", \"PL\", \"PM\", \"PN\", \"PR\", \"PS\", \"PT\", \"PW\", \"PY\", \"QA\", \"RE\", \"RO\", \"RS\", \"RU\", \"RW\", \"SA\", \"SB\", \"SC\", \"SD\", \"SE\", \"SG\", \"SH\", \"SI\", \"SJ\", \"SK\", \"SL\", \"SM\", \"SN\", \"SO\", \"SR\", \"SS\", \"ST\", \"SV\", \"SX\", \"SY\", \"SZ\", \"TC\", \"TD\", \"TF\", \"TG\", \"TH\", \"TJ\", \"TK\", \"TL\", \"TM\", \"TN\", \"TO\", \"TR\", \"TT\", \"TV\", \"TW\", \"TZ\", \"UA\", \"UG\", \"UM\", \"US\", \"UY\", \"UZ\", \"VA\", \"VC\", \"VE\", \"VG\", \"VI\", \"VN\", \"VU\", \"WF\", \"WS\", \"YE\", \"YT\", \"ZA\", \"ZM\", \"ZW\")\n ) %>%\n col_is_character(\n columns = vars(country_code_3)\n ) %>%\n col_vals_in_set(\n columns = vars(country_code_3),\n set = c(\"AND\", \"ARE\", \"AFG\", \"ATG\", \"AIA\", \"ALB\", \"ARM\", \"AGO\", \"ATA\", \"ARG\", \"ASM\", \"AUT\", \"AUS\", \"ABW\", \"ALA\", \"AZE\", \"BIH\", \"BRB\", \"BGD\", \"BEL\", \"BFA\", \"BGR\", \"BHR\", \"BDI\", \"BEN\", \"BLM\", \"BMU\", \"BRN\", \"BOL\", \"BES\", \"BRA\", \"BHS\", \"BTN\", \"BVT\", \"BWA\", \"BLR\", \"BLZ\", \"CAN\", \"CCK\", \"COD\", \"CAF\", \"COG\", \"CHE\", \"CIV\", \"COK\", \"CHL\", \"CMR\", \"CHN\", \"COL\", \"CRI\", \"CUB\", \"CPV\", \"CUW\", \"CXR\", \"CYP\", \"CZE\", \"DEU\", \"DJI\", \"DNK\", \"DMA\", \"DOM\", \"DZA\", \"ECU\", \"EST\", \"EGY\", \"ESH\", \"ERI\", \"ESP\", \"ETH\", \"FIN\", \"FJI\", \"FLK\", \"FSM\", \"FRO\", \"FRA\", \"GAB\", \"GBR\", \"GRD\", \"GEO\", \"GUF\", \"GGY\", \"GHA\", \"GIB\", \"GRL\", \"GMB\", \"GIN\", \"GLP\", \"GNQ\", \"GRC\", \"SGS\", \"GTM\", \"GUM\", \"GNB\", \"GUY\", \"HKG\", \"HMD\", \"HND\", \"HRV\", \"HTI\", \"HUN\", \"IDN\", \"IRL\", \"ISR\", \"IMN\", \"IND\", \"IOT\", \"IRQ\", \"IRN\", \"ISL\", \"ITA\", \"JEY\", \"JAM\", \"JOR\", \"JPN\", \"KEN\", \"KGZ\", \"KHM\", \"KIR\", \"COM\", \"KNA\", \"PRK\", \"KOR\", \"KWT\", \"CYM\", \"KAZ\", \"LAO\", \"LBN\", \"LCA\", \"LIE\", \"LKA\", \"LBR\", \"LSO\", \"LTU\", \"LUX\", \"LVA\", \"LBY\", \"MAR\", \"MCO\", \"MDA\", \"MNE\", \"MAF\", \"MDG\", \"MHL\", \"MKD\", \"MLI\", \"MMR\", \"MNG\", \"MAC\", \"MNP\", \"MTQ\", \"MRT\", \"MSR\", \"MLT\", \"MUS\", \"MDV\", \"MWI\", \"MEX\", \"MYS\", \"MOZ\", \"NAM\", \"NCL\", \"NER\", \"NFK\", \"NGA\", \"NIC\", \"NLD\", \"NOR\", \"NPL\", \"NRU\", \"NIU\", \"NZL\", \"OMN\", \"PAN\", \"PER\", \"PYF\", \"PNG\", \"PHL\", \"PAK\", \"POL\", \"SPM\", \"PCN\", \"PRI\", \"PSE\", \"PRT\", \"PLW\", \"PRY\", \"QAT\", \"REU\", \"ROU\", \"SRB\", \"RUS\", \"RWA\", \"SAU\", \"SLB\", \"SYC\", \"SDN\", \"SWE\", \"SGP\", \"SHN\", \"SVN\", \"SJM\", \"SVK\", \"SLE\", \"SMR\", \"SEN\", \"SOM\", \"SUR\", \"SSD\", \"STP\", \"SLV\", \"SXM\", \"SYR\", \"SWZ\", \"TCA\", \"TCD\", \"ATF\", \"TGO\", \"THA\", \"TJK\", \"TKL\", \"TLS\", \"TKM\", \"TUN\", \"TON\", \"TUR\", \"TTO\", \"TUV\", \"TWN\", \"TZA\", \"UKR\", \"UGA\", \"UMI\", \"USA\", \"URY\", \"UZB\", \"VAT\", \"VCT\", \"VEN\", \"VGB\", \"VIR\", \"VNM\", \"VUT\", \"WLF\", \"WSM\", \"YEM\", \"MYT\", \"ZAF\", \"ZMB\", \"ZWE\")\n ) %>%\n col_is_integer(\n columns = vars(year)\n ) %>%\n col_vals_between(\n columns = vars(year),\n left = 1960,\n right = 2021\n ) %>%\n col_is_integer(\n columns = vars(population)\n ) %>%\n col_vals_between(\n columns = vars(population),\n left = 2646,\n right = 1412360000,\n na_pass = TRUE\n ) %>%\n rows_distinct() %>%\n col_schema_match(\n schema = col_schema(\n country_name = \"character\",\n country_code_2 = \"character\",\n country_code_3 = \"character\",\n year = \"integer\",\n population = \"integer\"\n )\n ) %>%\n interrogate()\n\nagent" + [1] "library(pointblank)\n\nagent <-\n create_agent(\n tbl = ~ tbl,\n actions = action_levels(\n warn_at = 0.05,\n stop_at = 0.10\n ),\n tbl_name = \"tbl\",\n label = \"Validation plan generated by `draft_validation()`.\"\n ) %>%\n col_is_character(\n columns = c(\"country_name\")\n ) %>%\n col_vals_in_set(\n columns = c(\"country_name\"),\n set = c(\"Aruba\", \"Afghanistan\", \"Angola\", \"Albania\", \"Andorra\", \"United Arab Emirates\", \"Argentina\", \"Armenia\", \"American Samoa\", \"Antigua and Barbuda\", \"Australia\", \"Austria\", \"Azerbaijan\", \"Burundi\", \"Belgium\", \"Benin\", \"Burkina Faso\", \"Bangladesh\", \"Bulgaria\", \"Bahrain\", \"Bahamas\", \"Bosnia and Herzegovina\", \"Belarus\", \"Belize\", \"Bermuda\", \"Bolivia\", \"Brazil\", \"Barbados\", \"Brunei Darussalam\", \"Bhutan\", \"Botswana\", \"Central African Republic\", \"Canada\", \"Switzerland\", \"Chile\", \"China\", \"Cote d'Ivoire\", \"Cameroon\", \"Congo (Democratic Republic)\", \"Congo\", \"Colombia\", \"Comoros\", \"Cabo Verde\", \"Costa Rica\", \"Cuba\", \"Curacao\", \"Cayman Islands\", \"Cyprus\", \"Czechia\", \"Germany\", \"Djibouti\", \"Dominica\", \"Denmark\", \"Dominican Republic\", \"Algeria\", \"Ecuador\", \"Egypt\", \"Eritrea\", \"Spain\", \"Estonia\", \"Ethiopia\", \"Finland\", \"Fiji\", \"France\", \"Faroe Islands\", \"Micronesia (Federated States)\", \"Gabon\", \"United Kingdom\", \"Georgia\", \"Ghana\", \"Gibraltar\", \"Guinea\", \"Gambia, The\", \"Guinea-Bissau\", \"Equatorial Guinea\", \"Greece\", \"Grenada\", \"Greenland\", \"Guatemala\", \"Guam\", \"Guyana\", \"Hong Kong\", \"Honduras\", \"Croatia\", \"Haiti\", \"Hungary\", \"Indonesia\", \"Isle of Man\", \"India\", \"Ireland\", \"Iran (Islamic Republic)\", \"Iraq\", \"Iceland\", \"Israel\", \"Italy\", \"Jamaica\", \"Jordan\", \"Japan\", \"Kazakhstan\", \"Kenya\", \"Kyrgyz Republic\", \"Cambodia\", \"Kiribati\", \"St. Kitts and Nevis\", \"Korea, Rep.\", \"Kuwait\", \"Lao PDR\", \"Lebanon\", \"Liberia\", \"Libya\", \"St. Lucia\", \"Liechtenstein\", \"Sri Lanka\", \"Lesotho\", \"Lithuania\", \"Luxembourg\", \"Latvia\", \"Macao\", \"St. Martin (French part)\", \"Morocco\", \"Monaco\", \"Moldova\", \"Madagascar\", \"Maldives\", \"Mexico\", \"Marshall Islands\", \"North Macedonia\", \"Mali\", \"Malta\", \"Myanmar\", \"Montenegro\", \"Mongolia\", \"Northern Mariana Islands\", \"Mozambique\", \"Mauritania\", \"Mauritius\", \"Malawi\", \"Malaysia\", \"Namibia\", \"New Caledonia\", \"Niger\", \"Nigeria\", \"Nicaragua\", \"Netherlands\", \"Norway\", \"Nepal\", \"Nauru\", \"New Zealand\", \"Oman\", \"Pakistan\", \"Panama\", \"Peru\", \"Philippines\", \"Palau\", \"Papua New Guinea\", \"Poland\", \"Puerto Rico\", \"Korea, Dem. People's Rep.\", \"Portugal\", \"Paraguay\", \"West Bank and Gaza\", \"French Polynesia\", \"Qatar\", \"Romania\", \"Russian Federation\", \"Rwanda\", \"Saudi Arabia\", \"Sudan\", \"Senegal\", \"Singapore\", \"Solomon Islands\", \"Sierra Leone\", \"El Salvador\", \"San Marino\", \"Somalia\", \"Serbia\", \"South Sudan\", \"Sao Tome and Principe\", \"Suriname\", \"Slovak Republic\", \"Slovenia\", \"Sweden\", \"Eswatini\", \"Sint Maarten (Dutch part)\", \"Seychelles\", \"Syrian Arab Republic\", \"Turks and Caicos Islands\", \"Chad\", \"Togo\", \"Thailand\", \"Tajikistan\", \"Turkmenistan\", \"Timor-Leste\", \"Tonga\", \"Trinidad and Tobago\", \"Tunisia\", \"Turkiye\", \"Tuvalu\", \"Tanzania\", \"Uganda\", \"Ukraine\", \"Uruguay\", \"United States\", \"Uzbekistan\", \"St. Vincent and the Grenadines\", \"Venezuela, RB\", \"British Virgin Islands\", \"Virgin Islands (U.S.)\", \"Vietnam\", \"Vanuatu\", \"Samoa\", \"Yemen\", \"South Africa\", \"Zambia\", \"Zimbabwe\")\n ) %>%\n col_is_character(\n columns = c(\"country_code_2\")\n ) %>%\n col_vals_in_set(\n columns = c(\"country_code_2\"),\n set = c(\"AD\", \"AE\", \"AF\", \"AG\", \"AI\", \"AL\", \"AM\", \"AO\", \"AQ\", \"AR\", \"AS\", \"AT\", \"AU\", \"AW\", \"AX\", \"AZ\", \"BA\", \"BB\", \"BD\", \"BE\", \"BF\", \"BG\", \"BH\", \"BI\", \"BJ\", \"BL\", \"BM\", \"BN\", \"BO\", \"BQ\", \"BR\", \"BS\", \"BT\", \"BV\", \"BW\", \"BY\", \"BZ\", \"CA\", \"CC\", \"CD\", \"CF\", \"CG\", \"CH\", \"CI\", \"CK\", \"CL\", \"CM\", \"CN\", \"CO\", \"CR\", \"CU\", \"CV\", \"CW\", \"CX\", \"CY\", \"CZ\", \"DE\", \"DJ\", \"DK\", \"DM\", \"DO\", \"DZ\", \"EC\", \"EE\", \"EG\", \"EH\", \"ER\", \"ES\", \"ET\", \"FI\", \"FJ\", \"FK\", \"FM\", \"FO\", \"FR\", \"GA\", \"GB\", \"GD\", \"GE\", \"GF\", \"GG\", \"GH\", \"GI\", \"GL\", \"GM\", \"GN\", \"GP\", \"GQ\", \"GR\", \"GS\", \"GT\", \"GU\", \"GW\", \"GY\", \"HK\", \"HM\", \"HN\", \"HR\", \"HT\", \"HU\", \"ID\", \"IE\", \"IL\", \"IM\", \"IN\", \"IO\", \"IQ\", \"IR\", \"IS\", \"IT\", \"JE\", \"JM\", \"JO\", \"JP\", \"KE\", \"KG\", \"KH\", \"KI\", \"KM\", \"KN\", \"KP\", \"KR\", \"KW\", \"KY\", \"KZ\", \"LA\", \"LB\", \"LC\", \"LI\", \"LK\", \"LR\", \"LS\", \"LT\", \"LU\", \"LV\", \"LY\", \"MA\", \"MC\", \"MD\", \"ME\", \"MF\", \"MG\", \"MH\", \"MK\", \"ML\", \"MM\", \"MN\", \"MO\", \"MP\", \"MQ\", \"MR\", \"MS\", \"MT\", \"MU\", \"MV\", \"MW\", \"MX\", \"MY\", \"MZ\", \"NA\", \"NC\", \"NE\", \"NF\", \"NG\", \"NI\", \"NL\", \"NO\", \"NP\", \"NR\", \"NU\", \"NZ\", \"OM\", \"PA\", \"PE\", \"PF\", \"PG\", \"PH\", \"PK\", \"PL\", \"PM\", \"PN\", \"PR\", \"PS\", \"PT\", \"PW\", \"PY\", \"QA\", \"RE\", \"RO\", \"RS\", \"RU\", \"RW\", \"SA\", \"SB\", \"SC\", \"SD\", \"SE\", \"SG\", \"SH\", \"SI\", \"SJ\", \"SK\", \"SL\", \"SM\", \"SN\", \"SO\", \"SR\", \"SS\", \"ST\", \"SV\", \"SX\", \"SY\", \"SZ\", \"TC\", \"TD\", \"TF\", \"TG\", \"TH\", \"TJ\", \"TK\", \"TL\", \"TM\", \"TN\", \"TO\", \"TR\", \"TT\", \"TV\", \"TW\", \"TZ\", \"UA\", \"UG\", \"UM\", \"US\", \"UY\", \"UZ\", \"VA\", \"VC\", \"VE\", \"VG\", \"VI\", \"VN\", \"VU\", \"WF\", \"WS\", \"YE\", \"YT\", \"ZA\", \"ZM\", \"ZW\")\n ) %>%\n col_is_character(\n columns = c(\"country_code_3\")\n ) %>%\n col_vals_in_set(\n columns = c(\"country_code_3\"),\n set = c(\"AND\", \"ARE\", \"AFG\", \"ATG\", \"AIA\", \"ALB\", \"ARM\", \"AGO\", \"ATA\", \"ARG\", \"ASM\", \"AUT\", \"AUS\", \"ABW\", \"ALA\", \"AZE\", \"BIH\", \"BRB\", \"BGD\", \"BEL\", \"BFA\", \"BGR\", \"BHR\", \"BDI\", \"BEN\", \"BLM\", \"BMU\", \"BRN\", \"BOL\", \"BES\", \"BRA\", \"BHS\", \"BTN\", \"BVT\", \"BWA\", \"BLR\", \"BLZ\", \"CAN\", \"CCK\", \"COD\", \"CAF\", \"COG\", \"CHE\", \"CIV\", \"COK\", \"CHL\", \"CMR\", \"CHN\", \"COL\", \"CRI\", \"CUB\", \"CPV\", \"CUW\", \"CXR\", \"CYP\", \"CZE\", \"DEU\", \"DJI\", \"DNK\", \"DMA\", \"DOM\", \"DZA\", \"ECU\", \"EST\", \"EGY\", \"ESH\", \"ERI\", \"ESP\", \"ETH\", \"FIN\", \"FJI\", \"FLK\", \"FSM\", \"FRO\", \"FRA\", \"GAB\", \"GBR\", \"GRD\", \"GEO\", \"GUF\", \"GGY\", \"GHA\", \"GIB\", \"GRL\", \"GMB\", \"GIN\", \"GLP\", \"GNQ\", \"GRC\", \"SGS\", \"GTM\", \"GUM\", \"GNB\", \"GUY\", \"HKG\", \"HMD\", \"HND\", \"HRV\", \"HTI\", \"HUN\", \"IDN\", \"IRL\", \"ISR\", \"IMN\", \"IND\", \"IOT\", \"IRQ\", \"IRN\", \"ISL\", \"ITA\", \"JEY\", \"JAM\", \"JOR\", \"JPN\", \"KEN\", \"KGZ\", \"KHM\", \"KIR\", \"COM\", \"KNA\", \"PRK\", \"KOR\", \"KWT\", \"CYM\", \"KAZ\", \"LAO\", \"LBN\", \"LCA\", \"LIE\", \"LKA\", \"LBR\", \"LSO\", \"LTU\", \"LUX\", \"LVA\", \"LBY\", \"MAR\", \"MCO\", \"MDA\", \"MNE\", \"MAF\", \"MDG\", \"MHL\", \"MKD\", \"MLI\", \"MMR\", \"MNG\", \"MAC\", \"MNP\", \"MTQ\", \"MRT\", \"MSR\", \"MLT\", \"MUS\", \"MDV\", \"MWI\", \"MEX\", \"MYS\", \"MOZ\", \"NAM\", \"NCL\", \"NER\", \"NFK\", \"NGA\", \"NIC\", \"NLD\", \"NOR\", \"NPL\", \"NRU\", \"NIU\", \"NZL\", \"OMN\", \"PAN\", \"PER\", \"PYF\", \"PNG\", \"PHL\", \"PAK\", \"POL\", \"SPM\", \"PCN\", \"PRI\", \"PSE\", \"PRT\", \"PLW\", \"PRY\", \"QAT\", \"REU\", \"ROU\", \"SRB\", \"RUS\", \"RWA\", \"SAU\", \"SLB\", \"SYC\", \"SDN\", \"SWE\", \"SGP\", \"SHN\", \"SVN\", \"SJM\", \"SVK\", \"SLE\", \"SMR\", \"SEN\", \"SOM\", \"SUR\", \"SSD\", \"STP\", \"SLV\", \"SXM\", \"SYR\", \"SWZ\", \"TCA\", \"TCD\", \"ATF\", \"TGO\", \"THA\", \"TJK\", \"TKL\", \"TLS\", \"TKM\", \"TUN\", \"TON\", \"TUR\", \"TTO\", \"TUV\", \"TWN\", \"TZA\", \"UKR\", \"UGA\", \"UMI\", \"USA\", \"URY\", \"UZB\", \"VAT\", \"VCT\", \"VEN\", \"VGB\", \"VIR\", \"VNM\", \"VUT\", \"WLF\", \"WSM\", \"YEM\", \"MYT\", \"ZAF\", \"ZMB\", \"ZWE\")\n ) %>%\n col_is_integer(\n columns = c(\"year\")\n ) %>%\n col_vals_between(\n columns = c(\"year\"),\n left = 1960,\n right = 2022\n ) %>%\n col_is_integer(\n columns = c(\"population\")\n ) %>%\n col_vals_between(\n columns = c(\"population\"),\n left = 2646,\n right = 1417173200,\n na_pass = TRUE\n ) %>%\n rows_distinct(\n columns = c(\"country_name\", \"country_code_2\", \"country_code_3\", \"year\", \"population\")\n ) %>%\n col_schema_match(\n schema = col_schema(\n country_name = \"character\",\n country_code_2 = \"character\",\n country_code_3 = \"character\",\n year = \"integer\",\n population = \"integer\"\n )\n ) %>%\n interrogate()\n\nagent" diff --git a/tests/testthat/test-align_multiagent.R b/tests/testthat/test-align_multiagent.R new file mode 100644 index 000000000..c0455158f --- /dev/null +++ b/tests/testthat/test-align_multiagent.R @@ -0,0 +1,225 @@ +agent <- create_agent(small_table) +align <- function(..., display_table = FALSE) { + intel_agents <- suppressMessages(lapply(list(...), interrogate)) + multiagent <- do.call(create_multiagent, intel_agents) + get_multiagent_report( + multiagent, display_table = display_table, display_mode = "wide" + ) +} + +al <- action_levels(0.05, 0.10, 0.20) + +agent_1 <- + create_agent( + tbl = ~ small_table, + label = "An example.", + actions = al + ) %>% + # col_vals_gt(vars(date_time), vars(date), na_pass = TRUE) %>% + # col_vals_gt(vars(b), vars(g), na_pass = TRUE) %>% + rows_distinct() %>% + col_vals_gt(vars(d), 100) %>% + col_vals_equal(vars(d), vars(d), na_pass = TRUE) %>% + col_vals_between(vars(c), left = vars(a), right = vars(d), na_pass = TRUE) %>% + col_vals_not_between(vars(c), left = 10, right = 20, na_pass = TRUE) %>% + rows_distinct(vars(d, e, f)) %>% + col_is_integer(vars(a)) %>% + interrogate() + +test_that("rehashing agent created in current ver generates the same hash", { + expect_identical( + agent_1$validation_set$sha1, + rehash_agent(agent_1)$validation_set$sha1 + ) + expect_identical( + rehash_agent(agent_1)$validation_set$sha1, + rehash_agent(agent_1)$validation_set$sha1 + ) +}) + +agent_a <- agent_1 +agent_b <- agent_1 +agent_a$validation_set$sha1 <- sample(letters, nrow(agent_a$validation_set)) +agent_b$validation_set$sha1 <- sample(LETTERS, nrow(agent_b$validation_set)) + +test_that("rehashing reconstructs hash deterministically", { + expect_false(identical(agent_a, agent_b)) + expect_identical( + rehash_agent(agent_a), + rehash_agent(agent_b) + ) + expect_identical( + rehash_agent(agent_a), + rehash_agent(rehash_agent(agent_a)) + ) +}) + +test_that("multiagent uses rehashing for alignment", { + multiagent <- create_multiagent(agent_a, agent_b) + expect_equivalent( + rehash_agent(agent_a), + multiagent$agents[[1]] + ) + expect_equivalent( + rehash_agent(agent_b), + multiagent$agents[[2]] + ) + expect_identical( + multiagent$agents[[1]]$validation_set$sha1, + multiagent$agents[[2]]$validation_set$sha1 + ) + multiagent_report <- get_multiagent_report(multiagent, display_table = FALSE) + expect_equal(nrow(multiagent_report), nrow(agent_1$validation_set)) +}) + +test_that("multiagent alignment is not sensitive to environment", { + + # Insensitive to `vars()` quosure environment + agent1a <- local({ + agent %>% + col_vals_gt(c, value = vars(a)) + }) + agent1b <- agent %>% + col_vals_gt(c, value = vars(a)) + expect_false(identical( + agent1a$validation_set$values, + agent1b$validation_set$values + )) + expect_equal(nrow(align(agent1a, agent1b)), 1) + + # Insensitive to formula environment + agent2a <- local({ + agent %>% + col_vals_not_null(c, preconditions = ~ . %>% identity()) + }) + agent2b <- agent %>% + col_vals_not_null(c, preconditions = ~ . %>% identity()) + expect_false(identical( + agent2a$validation_set$preconditions, + agent2b$validation_set$preconditions + )) + expect_equal(nrow(align(agent2a, agent2b)), 1) + + # Insensitive to function environment + agent3a <- local({ + agent %>% + col_vals_not_null(c, preconditions = . %>% identity()) + }) + agent3b <- agent %>% + col_vals_not_null(c, preconditions = . %>% identity()) + expect_false(identical( + agent3a$validation_set$preconditions, + agent3b$validation_set$preconditions + )) + expect_equal(nrow(align(agent3a, agent3b)), 1) + + # But still sensitive to function definition + fn <- function(x) identity(x) + agent4a <- agent %>% + col_vals_not_null(c, preconditions = fn) + fn <- function(x) force(x) + agent4b <- agent %>% + col_vals_not_null(c, preconditions = fn) + expect_false(identical( + agent4a$validation_set$preconditions, + agent4b$validation_set$preconditions + )) + expect_false(identical( + agent4a$validation_set$sha1, + agent4b$validation_set$sha1 + )) + expect_equal(nrow(align(agent4a, agent4b)), 2) + +}) + +test_that("multiagent alignment of special data types are correct", { + + # `vars(c)` not equivalent to `"c"` or `"~c"` or `c` + agent1a <- agent %>% + col_vals_equal(columns = c, value = "c") + agent1b <- agent %>% + col_vals_equal(columns = c, value = vars(c)) + expect_false(identical( + agent1a$validation_set$sha1, + agent1b$validation_set$sha1 + )) + expect_equal(nrow(align(agent1a, agent1b)), 2) + c <- "c" + agent1c <- agent %>% + col_vals_equal(columns = c, value = c) + expect_equal(nrow(align(agent1a, agent1c)), 1) + expect_equal(nrow(align(agent1b, agent1c)), 2) + agent1d <- agent %>% + col_vals_equal(columns = c, value = "~c") + expect_equal(nrow(align(agent1b, agent1d)), 2) + + # Aligns special data types correctly + ## Function object + agent2a <- agent %>% + rows_distinct(preconditions = identity) + agent2b <- agent %>% + rows_distinct(preconditions = identity) + expect_equal(nrow(align(agent2a, agent2b)), 1) + ## Ignores bytecode differences (`identical(force, identity)`) + agent2c <- agent %>% + rows_distinct(preconditions = force) + expect_equal(nrow(align(agent2a, agent2c)), 1) + identity2 <- function(y) y + agent2d <- agent %>% + rows_distinct(preconditions = identity2) + expect_equal(nrow(align(agent2a, agent2d)), 2) + + ## Magrittr anonymous function + agent3a <- agent %>% + rows_distinct(preconditions = . %>% identity()) + agent3b <- agent %>% + rows_distinct(preconditions = . %>% identity()) + expect_equal(nrow(align(agent3a, agent3b)), 1) + agent3c <- agent %>% + rows_distinct(preconditions = . %>% force()) + expect_equal(nrow(align(agent3a, agent3c)), 2) + + ## Formula + magrittr anonymous function + agent4a <- agent %>% + rows_distinct(preconditions = ~ . %>% identity()) + agent4b <- agent %>% + rows_distinct(preconditions = ~ . %>% identity()) + expect_equal(nrow(align(agent4a, agent4b)), 1) + agent4c <- agent %>% + rows_distinct(preconditions = ~ . %>% force()) + expect_equal(nrow(align(agent4a, agent4c)), 2) + + ## `vars()` quosures + agent5a <- agent %>% + col_vals_between(columns = c, left = vars(a), right = vars(d)) + agent5b <- agent %>% + col_vals_between(columns = c, left = vars(a), right = vars(d)) + expect_equal(nrow(align(agent5a, agent5b)), 1) + agent5c <- agent %>% + col_vals_between(columns = c, left = vars(d), right = vars(a)) + expect_equal(nrow(align(agent5a, agent5c)), 2) + + ## identical segments (same expr) + agent6a <- agent %>% + col_vals_lt(columns = c(a, c), value = vars(d), segments = vars(e, f)) + agent6b <- agent %>% + col_vals_lt(columns = c(a, c), value = vars(d), segments = vars(e, f)) + expect_equal(nrow(align(agent6a, agent6b)), 10) + ## identical segments (diff expr) + agent7a <- agent %>% + col_vals_lt(columns = c(a, c), value = vars(d), segments = vars(e)) + agent7b <- agent %>% + col_vals_lt(columns = c(a, c), value = vars(d), segments = e ~ c(TRUE, FALSE)) + expect_identical( + agent7a$validation_set$sha1, agent7b$validation_set$sha1 + ) + expect_equal(nrow(align(agent7a, agent7b)), 4) + ## subset of segments (diff expr) + agent8a <- agent %>% + col_vals_lt(columns = c(a, c), value = vars(d), segments = vars(e)) + agent8b <- agent %>% + col_vals_lt(columns = c(a, c), value = vars(d), segments = e ~ c(TRUE)) + expect_true(all(agent8b$validation_set$sha1 %in% agent8a$validation_set$sha1)) + expect_equal(nrow(align(agent8a, agent8b)), 4) + +}) diff --git a/tests/testthat/test-create_multiagent.R b/tests/testthat/test-create_multiagent.R index 0b3da7283..da33a4041 100644 --- a/tests/testthat/test-create_multiagent.R +++ b/tests/testthat/test-create_multiagent.R @@ -137,3 +137,7 @@ test_that("Creating a valid `multiagent` object is possible", { expect_is(agent_i$extracts, "list") } }) + +test_that("multiagent checks for agent input", { + expect_error(create_multiagent(1, "a"), "must be an agent") +}) diff --git a/tests/testthat/test-create_validation_steps.R b/tests/testthat/test-create_validation_steps.R index d0e0777ce..3a4318de6 100644 --- a/tests/testthat/test-create_validation_steps.R +++ b/tests/testthat/test-create_validation_steps.R @@ -1036,7 +1036,7 @@ test_that("Creating a `rows_distinct()` step is possible", { expect_equivalent(validation$tbl_name, "small_table") expect_equivalent(validation$col_names, c("date_time", "date", "a", "b", "c", "d", "e", "f")) expect_equivalent(validation$validation_set$assertion_type, "rows_distinct") - expect_true(is.na(validation$validation_set$column %>% .[[1]] %>% .[[1]])) + expect_equivalent(validation$validation_set$column %>% unlist(), "date_time, date, a, b, c, d, e, f") expect_true(is.null(validation$validation_set[["values"]][[1]])) expect_true(is.na(validation$validation_set$all_passed)) expect_true(is.na(validation$validation_set$n)) diff --git a/tests/testthat/test-draft_validation.R b/tests/testthat/test-draft_validation.R index 7e1349f09..2a4d9b253 100644 --- a/tests/testthat/test-draft_validation.R +++ b/tests/testthat/test-draft_validation.R @@ -63,7 +63,7 @@ test_that("draft validations for data tables can be generated", { write_draft_snapshot_test(dataset = dplyr::band_instruments, filename = "band_instruments") write_draft_snapshot_test(dataset = dplyr::band_members, filename = "band_members") write_draft_snapshot_test(dataset = dplyr::starwars, filename = "starwars") - write_draft_snapshot_test(dataset = dplyr::storms, filename = "storms") + # write_draft_snapshot_test(dataset = dplyr::storms, filename = "storms") write_draft_snapshot_test(dataset = tidyr::billboard, filename = "billboard") write_draft_snapshot_test(dataset = tidyr::construction, filename = "construction") diff --git a/tests/testthat/test-expectation_fns.R b/tests/testthat/test-expectation_fns.R index 0b0fa6017..c0a340d9f 100644 --- a/tests/testthat/test-expectation_fns.R +++ b/tests/testthat/test-expectation_fns.R @@ -1624,7 +1624,8 @@ test_that("pointblank expectation function produce the correct results", { test_that("expect errors to be expressed by pointblank under some conditions", { - no_col_msg <- "The value for `column` doesn't correspond to a column name." + # no_col_msg <- "The value for `column` doesn't correspond to a column name." + no_col_msg <- "column" # Errors caught and expressed when a column doesn't exist expect_error(expect_col_vals_lt(tbl, columns = vars(z), value = 0), regexp = no_col_msg) diff --git a/tests/testthat/test-get_agent_report.R b/tests/testthat/test-get_agent_report.R index 8a0790db4..d8075cb23 100644 --- a/tests/testthat/test-get_agent_report.R +++ b/tests/testthat/test-get_agent_report.R @@ -262,3 +262,43 @@ test_that("The correct title is rendered in the agent report", { # ) # ) }) + +test_that("col_vals_expr() shows used columns", { + + tbl <- + dplyr::tibble( + a = c(1, 2, 1, 7, 8, 6), + b = c(0, 0, 0, 1, 1, 1), + c = c(0.5, 0.3, 0.8, 1.4, 1.9, 1.2), + ) + c <- 1 + + agent <- tbl %>% + create_agent() %>% + # Uses column `a` + col_vals_expr(expr = ~ a %% 1 == 0) %>% + # Uses columns `a`, `b`, `c` + col_vals_expr(expr = ~ case_when( + b == 0 ~ a %>% between(0, 5) & c < 1, + b == 1 ~ a > 5 & c >= 1 + )) %>% + # Uses columns `a` and `b`, and injects global variable `c` + col_vals_expr(expr(.data$a + b == !!c)) %>% + # Uses column `a` but variable `d` is not defined (= not a column) + col_vals_expr(expr = ~ a + d > 0) %>% + interrogate() + + columns <- agent$validation_set$column + expect_equal(columns[[1]], "a") + expect_setequal(columns[[2]], c("a", "b", "c")) + expect_setequal(columns[[3]], c("a", "b")) + expect_equal(columns[[4]], "a") + + report_columns <- get_agent_report(agent, display_table = FALSE)$columns + + expect_equal(report_columns[1], "a") + expect_setequal(strsplit(report_columns[2], ", ")[[1]], c("a", "b", "c")) + expect_setequal(strsplit(report_columns[3], ", ")[[1]], c("a", "b")) + expect_equal(report_columns[4], "a") + +}) diff --git a/tests/testthat/test-get_informant_report.R b/tests/testthat/test-get_informant_report.R index 7531f962f..55b5ccabf 100644 --- a/tests/testthat/test-get_informant_report.R +++ b/tests/testthat/test-get_informant_report.R @@ -309,3 +309,54 @@ test_that("The correct title is rendered in the informant report", { # ) # ) }) + +test_that("tidyselect integration in info_columns()", { + informant <- create_informant(small_table) + informant_lazy <- create_informant(~ small_table) + + # Column headers stored in `$_private` + expect_s3_class(informant$metadata[["_private"]]$col_ptypes, "data.frame") + expect_s3_class(informant_lazy$metadata[["_private"]]$col_ptypes, "data.frame") + + cols_with_info <- function(x) { + cols_info <- sapply(x$metadata$columns, `[[`, "info") + names(which(lengths(cols_info) > 0)) + } + is_timepoint <- function(x) { + inherits(x, c("POSIXt", "POSIXct", "POSIXlt", "Date")) + } + + # String-based and class-based matches both work + expect_identical({ + informant %>% + info_columns( + columns = starts_with("date"), + info = "Time information" + ) %>% + cols_with_info() + }, { + informant %>% + info_columns( + columns = where(is_timepoint), + info = "Time information" + ) %>% + cols_with_info() + }) + # String-based and class-based matches both work + expect_identical({ + informant_lazy %>% + info_columns( + columns = starts_with("date"), + info = "Time information" + ) %>% + cols_with_info() + }, { + informant_lazy %>% + info_columns( + columns = where(is_timepoint), + info = "Time information" + ) %>% + cols_with_info() + }) + +}) diff --git a/tests/testthat/test-get_multiagent_report.R b/tests/testthat/test-get_multiagent_report.R index 1368c1b6c..5876537be 100644 --- a/tests/testthat/test-get_multiagent_report.R +++ b/tests/testthat/test-get_multiagent_report.R @@ -84,8 +84,8 @@ test_that("Getting a multiagent report is possible", { "00[1-4]_[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}" ) - # Expect 16 rows in this report - expect_equivalent(nrow(report), 17) + # Expect 14 rows in this report + expect_equivalent(nrow(report), 14) for (col_name in colnames(report)) { diff --git a/tests/testthat/test-has_columns.R b/tests/testthat/test-has_columns.R index fa856227f..820ac84b3 100644 --- a/tests/testthat/test-has_columns.R +++ b/tests/testthat/test-has_columns.R @@ -1,3 +1,5 @@ +z <- rlang::missing_arg() + test_that("the `has_columns()` function works when used directly with data", { # Expect TRUE when *all* of the given column names is present @@ -7,19 +9,70 @@ test_that("the `has_columns()` function works when used directly with data", { expect_true(small_table %>% has_columns(c(vars(a, b), vars(c)))) # Expect FALSE when *any* of the given column names is absent - expect_false(small_table %>% has_columns(vars(a, h))) - expect_false(small_table %>% has_columns(vars(h, j))) - - # Select helper functions don't work with `has_columns()` and will - # always throw errors - expect_error(small_table %>% has_columns(pointblank::contains("te"))) - expect_error(small_table %>% has_columns(pointblank::starts_with("date"))) - expect_error(small_table %>% has_columns(pointblank::ends_with("time"))) - expect_error(small_table %>% has_columns(pointblank::everything())) - expect_error(small_table %>% has_columns(pointblank::matches(".*te"))) + expect_false(small_table %>% has_columns(vars(z))) + expect_false(small_table %>% has_columns("z")) + expect_false(small_table %>% has_columns(vars(a, z))) + expect_false(small_table %>% has_columns(vars(z, zz))) + expect_false(small_table %>% has_columns(c("a", "z"))) + expect_false(small_table %>% has_columns(c("z", "zz"))) # Expect that using inputs that are not tabular result in errors expect_error(has_columns(list(a = "2"), "a")) expect_error(has_columns(c(a = 1, b = 2), "a")) expect_error(has_columns(matrix(c(1, 2, 3, 4), nrow = 2), "b")) }) + +test_that("the `has_columns()` function works with tidyselect", { + + # Select helpers work + expect_true(small_table %>% has_columns(contains("te"))) + expect_true(small_table %>% has_columns(starts_with("date"))) + expect_true(small_table %>% has_columns(ends_with("time"))) + expect_true(small_table %>% has_columns(everything())) + expect_true(small_table %>% has_columns(matches(".*te"))) + + # Empty selection from helpers is FALSE + expect_false(small_table %>% has_columns(contains("z"))) + expect_false(small_table %>% has_columns(starts_with("z"))) + expect_false(small_table %>% has_columns(ends_with("z"))) + expect_false(small_table %>% has_columns(last_col() + 1)) + expect_false(small_table %>% has_columns(matches("z"))) + + # Expect FALSE when *any* of the given column names is absent + expect_false(small_table %>% has_columns(c(a, z))) + + # Genuine evaluation errors are re-thrown and short-circuits + expect_error(small_table %>% has_columns(stop("Oh no!")), "Oh no!") + expect_error(small_table %>% has_columns(c(stop("Oh no!"))), "Oh no!") + expect_error(small_table %>% has_columns(c(a, stop("Oh no!"))), "Oh no!") + expect_error(small_table %>% has_columns(c(stop("Oh no!"), stop("Don't reach me!"))), "Oh no!") + + # Mix of selections work like AND + expect_true(small_table %>% has_columns(c(contains("da"), contains("te")))) + expect_true(small_table %>% has_columns(c(a, contains("te")))) + expect_false(small_table %>% has_columns(c(z, contains("te")))) + expect_false(small_table %>% has_columns(c(a, contains("z")))) + expect_false(small_table %>% has_columns(c(contains("da"), contains("z")))) + + # Nested vector patterns + expect_identical( + small_table %>% has_columns(c(vars(a, b), vars(c))), + small_table %>% has_columns(c(c(a, b), c)) + ) + expect_identical( + small_table %>% has_columns(c(vars(a, b), vars(c))), + small_table %>% has_columns(c(all_of(c("a", "b")), c)) + ) + + # `any_of()`/`all_of()` patterns with external vectors + has_one <- c("a", "y", "z") + has_all <- c("a", "b", "c") + has_none <- c("x", "y", "z") + expect_true(small_table %>% has_columns(any_of(has_one))) + expect_true(small_table %>% has_columns(any_of(has_all))) + expect_false(small_table %>% has_columns(any_of(has_none))) + expect_false(small_table %>% has_columns(all_of(has_one))) + expect_true(small_table %>% has_columns(all_of(has_all))) + expect_false(small_table %>% has_columns(all_of(has_none))) + +}) diff --git a/tests/testthat/test-incorporate_with_informant.R b/tests/testthat/test-incorporate_with_informant.R index 9b28651c9..3d6bf4c56 100644 --- a/tests/testthat/test-incorporate_with_informant.R +++ b/tests/testthat/test-incorporate_with_informant.R @@ -56,7 +56,7 @@ test_that("Incorporating an informant yields the correct results", { # `informant$metadata_rev` expect_equal( names(informant_inc$metadata), - c("table", "columns", "rows") + c("table", "columns", "_private", "rows") ) expect_equal( names(informant_inc$metadata_rev), diff --git a/tests/testthat/test-interrogate_simple.R b/tests/testthat/test-interrogate_simple.R index 39e7442a1..c4b9369ba 100644 --- a/tests/testthat/test-interrogate_simple.R +++ b/tests/testthat/test-interrogate_simple.R @@ -2124,3 +2124,34 @@ test_that("The inclusivity options work well for the range-based validations", { ) ) }) + +test_that("vars(col) and vars('col') both evaluate to tbl column", { + + df <- data.frame(x = Sys.Date() + 1, y = Sys.Date()) + + expect_true(test_col_vals_gt(df, x, vars(y))) + expect_true(test_col_vals_gt(df, x, vars("y"))) + +}) + +test_that("class preserved in `value`", { + + # A custom class with a `==` method that simply errors + custom_val <- structure(1L, class = "pb-test-custom-class") + registerS3method( + "==", "pb-test-custom-class", function(x, ...) stop("Bad class for `==`") + ) + + # We expect error (class preserved) vs. TRUE (class stripped) + expect_error(custom_val == 1L) + expect_true(unclass(custom_val) == 1L) + + # Error is correctly thrown and safely caught at interrogate + expect_no_error({ + agent <- create_agent(data.frame(col = custom_val)) %>% + col_vals_equal(columns = col, value = 1L) %>% + interrogate() + }) + expect_true(agent$validation_set$eval_error) + +}) diff --git a/tests/testthat/test-interrogate_with_agent.R b/tests/testthat/test-interrogate_with_agent.R index eee9c0bfa..393f1f90a 100644 --- a/tests/testthat/test-interrogate_with_agent.R +++ b/tests/testthat/test-interrogate_with_agent.R @@ -784,7 +784,7 @@ test_that("Interrogating for valid row values", { # Expect certain values in `validation$validation_set` expect_equivalent(validation$tbl_name, "small_table") expect_equivalent(validation$validation_set$assertion_type, "rows_distinct") - expect_true(is.na(validation$validation_set$column %>% unlist())) + expect_equivalent(validation$validation_set$column %>% unlist(), "date_time, date, a, b, c, d, e, f") expect_true(is.null(validation$validation_set[["values"]][[1]])) expect_false(validation$validation_set$all_passed) expect_equivalent(validation$validation_set$n, 13) @@ -807,7 +807,7 @@ test_that("Interrogating for valid row values", { # Expect certain values in `validation$validation_set` expect_equivalent(validation$tbl_name, "small_table") expect_equivalent(validation$validation_set$assertion_type, "rows_distinct") - expect_true(is.na(validation$validation_set$column %>% unlist())) + expect_equivalent(validation$validation_set$column %>% unlist(), "date_time, date, a, b, c, d, e, f") expect_true(is.null(validation$validation_set[["values"]][[1]])) expect_true(validation$validation_set$all_passed) expect_equivalent(validation$validation_set$n, 11) @@ -873,7 +873,7 @@ test_that("Interrogating for valid row values", { # Expect certain values in `validation$validation_set` expect_equivalent(validation$tbl_name, "small_table") expect_equivalent(validation$validation_set$assertion_type, "rows_complete") - expect_true(is.na(validation$validation_set$column %>% unlist())) + expect_equivalent(validation$validation_set$column %>% unlist(), "date_time, date, a, b, c, d, e, f") expect_true(is.null(validation$validation_set[["values"]][[1]])) expect_false(validation$validation_set$all_passed) expect_equivalent(validation$validation_set$n, 13) @@ -896,7 +896,7 @@ test_that("Interrogating for valid row values", { # Expect certain values in `validation$validation_set` expect_equivalent(validation$tbl_name, "small_table") expect_equivalent(validation$validation_set$assertion_type, "rows_complete") - expect_true(is.na(validation$validation_set$column %>% unlist())) + expect_equivalent(validation$validation_set$column %>% unlist(), "date_time, date, a, b, c, d, e, f") expect_true(is.null(validation$validation_set[["values"]][[1]])) expect_true(validation$validation_set$all_passed) expect_equivalent(validation$validation_set$n, 3) @@ -2016,85 +2016,3 @@ test_that("Select validation steps can be `active` or not", { ) ) }) - -test_that("Some validation steps become inactive based on select expressions", { - - agent <- create_agent(tbl = small_table, label = "::QUIET::") - - check_eval_active_false <- function(agent) { - - suppressMessages( - agent %>% - interrogate() %>% - .$validation_set %>% - dplyr::pull(eval_active) %>% - expect_false() - ) - } - - eval_select <- function(select_expr) { - rlang::eval_bare(rlang::f_rhs(select_expr)) - } - - select_exprs <- - c( - ~ starts_with("z"), - ~ ends_with("z"), - ~ contains("z"), - ~ matches("z") - ) - - for (i in seq_along(select_exprs)) { - - agent %>% col_vals_lt(eval_select(select_exprs[[i]]), value = 5) %>% - check_eval_active_false() - agent %>% col_vals_lte(eval_select(select_exprs[[i]]), value = 5) %>% - check_eval_active_false() - agent %>% col_vals_equal(eval_select(select_exprs[[i]]), value = 5) %>% - check_eval_active_false() - agent %>% col_vals_not_equal(eval_select(select_exprs[[i]]), value = 5) %>% - check_eval_active_false() - agent %>% col_vals_gte(eval_select(select_exprs[[i]]), value = 5) %>% - check_eval_active_false() - agent %>% col_vals_gt(eval_select(select_exprs[[i]]), value = 5) %>% - check_eval_active_false() - agent %>% col_vals_between(eval_select(select_exprs[[i]]), 2, 5) %>% - check_eval_active_false() - agent %>% col_vals_not_between(eval_select(select_exprs[[i]]), 2, 5) %>% - check_eval_active_false() - agent %>% col_vals_in_set(eval_select(select_exprs[[i]]), c(2, 5)) %>% - check_eval_active_false() - agent %>% col_vals_not_in_set(eval_select(select_exprs[[i]]), c(2, 5)) %>% - check_eval_active_false() - agent %>% col_vals_make_set(eval_select(select_exprs[[i]]), c(2, 5)) %>% - check_eval_active_false() - agent %>% col_vals_make_subset(eval_select(select_exprs[[i]]), c(2, 5)) %>% - check_eval_active_false() - agent %>% col_vals_null(eval_select(select_exprs[[i]])) %>% - check_eval_active_false() - agent %>% col_vals_not_null(eval_select(select_exprs[[i]])) %>% - check_eval_active_false() - agent %>% col_vals_increasing(eval_select(select_exprs[[i]])) %>% - check_eval_active_false() - agent %>% col_vals_decreasing(eval_select(select_exprs[[i]])) %>% - check_eval_active_false() - agent %>% col_vals_regex(eval_select(select_exprs[[i]]), regex = "abc") %>% - check_eval_active_false() - agent %>% col_vals_within_spec(eval_select(select_exprs[[i]]), spec = "email") %>% - check_eval_active_false() - agent %>% col_is_character(eval_select(select_exprs[[i]])) %>% - check_eval_active_false() - agent %>% col_is_numeric(eval_select(select_exprs[[i]])) %>% - check_eval_active_false() - agent %>% col_is_integer(eval_select(select_exprs[[i]])) %>% - check_eval_active_false() - agent %>% col_is_logical(eval_select(select_exprs[[i]])) %>% - check_eval_active_false() - agent %>% col_is_date(eval_select(select_exprs[[i]])) %>% - check_eval_active_false() - agent %>% col_is_posix(eval_select(select_exprs[[i]])) %>% - check_eval_active_false() - agent %>% col_is_factor(eval_select(select_exprs[[i]])) %>% - check_eval_active_false() - } -}) diff --git a/tests/testthat/test-interrogate_with_agent_db.R b/tests/testthat/test-interrogate_with_agent_db.R index 8d8d24750..cf8b57ee5 100644 --- a/tests/testthat/test-interrogate_with_agent_db.R +++ b/tests/testthat/test-interrogate_with_agent_db.R @@ -485,7 +485,7 @@ test_that("Interrogating for valid row values", { # Expect certain values in `validation$validation_set` expect_equivalent(validation$tbl_name, "small_table") expect_equivalent(validation$validation_set$assertion_type, "rows_distinct") - expect_true(is.na(validation$validation_set$column %>% unlist())) + expect_equivalent(validation$validation_set$column %>% unlist(), "date_time, date, a, b, c, d, e, f") expect_true(is.null(validation$validation_set[["values"]][[1]])) expect_false(validation$validation_set$all_passed) expect_equivalent(validation$validation_set$n, 13) @@ -510,7 +510,7 @@ test_that("Interrogating for valid row values", { # Expect certain values in `validation$validation_set` expect_equivalent(validation$tbl_name, "small_table") expect_equivalent(validation$validation_set$assertion_type, "rows_distinct") - expect_true(is.na(validation$validation_set$column %>% unlist())) + expect_equivalent(validation$validation_set$column %>% unlist(), "date_time, date, a, b, c, d, e, f") expect_true(is.null(validation$validation_set[["values"]][[1]])) expect_true(validation$validation_set$all_passed) expect_equivalent(validation$validation_set$n, 11) diff --git a/tests/testthat/test-interrogate_with_agent_segments.R b/tests/testthat/test-interrogate_with_agent_segments.R index 15a864c64..a9c0ca741 100644 --- a/tests/testthat/test-interrogate_with_agent_segments.R +++ b/tests/testthat/test-interrogate_with_agent_segments.R @@ -26,7 +26,10 @@ test_that("Agent interrogations with segments yields the correct results", { expect_equivalent( validation_1$validation_set$assertion_type, rep("col_vals_increasing", 2) ) - expect_equivalent(validation_1$validation_set$column %>% unlist(), rep("b", 2)) + # Targeted skipping of this test for {covr} + if (isFALSE(as.logical(Sys.getenv("R_COVR", "false")))) { + expect_equivalent(validation_1$validation_set$column %>% unlist(), rep("b", 2)) + } expect_equivalent( validation_1$validation_set$seg_expr[[1]], validation_1$validation_set$seg_expr[[2]] @@ -797,7 +800,7 @@ test_that("Agent interrogations with segments yields the correct results", { expect_equivalent( validation$validation_set$assertion_type, rep("col_vals_expr", 2) ) - expect_equivalent(validation$validation_set$column %>% unlist(), rep(NA_character_, 2)) + expect_equivalent(validation$validation_set$column %>% unlist(), rep("b", 2)) expect_equivalent( validation$validation_set$seg_expr[[1]], validation$validation_set$seg_expr[[2]] diff --git a/tests/testthat/test-label_glue.R b/tests/testthat/test-label_glue.R new file mode 100644 index 000000000..980c53205 --- /dev/null +++ b/tests/testthat/test-label_glue.R @@ -0,0 +1,243 @@ +test_that("label supports glue syntax for {.seg_val} {.seg_col} {.step} {.col}", { + + # Reprex from (#451) for {.seg_val} + agent1 <- small_table %>% + create_agent() %>% + col_vals_lt( + c, 8, + segments = vars(f), + label = "The `col_vals_lt()` step for group '{.seg_val}'" + ) %>% + interrogate() + expect_identical( + gsub(".*'(high|low|mid)'.*", "\\1", agent1$validation_set$label), + c("high", "low", "mid") + ) + + # {.seg_col} + agent2 <- small_table %>% + create_agent() %>% + col_vals_lt( + c, 8, + segments = vars(e, f), + label = "The `col_vals_lt()` step for group '{.seg_val}' from col '{.seg_col}'" + ) %>% + interrogate() + expect_identical( + gsub(".*'(TRUE|FALSE|high|low|mid)'.*", "\\1", agent2$validation_set$label), + c("TRUE", "FALSE", "high", "low", "mid") + ) + expect_identical( + gsub(".*'(e|f)'.*", "\\1", agent2$validation_set$label), + c("e", "e", "f", "f", "f") + ) + + # {.step} + agent3 <- small_table %>% + create_agent() %>% + col_vals_lt( + c, 8, + segments = vars(f), + label = "{.step}" + ) %>% + interrogate() + expect_true(all(agent3$validation_set$label == "col_vals_lt")) + + # {.col} + agent4 <- small_table %>% + create_agent() %>% + col_vals_lt( + columns = matches("^[acd]$"), + value = 8, + label = "{.col}" + ) %>% + interrogate() + expect_identical(agent4$validation_set$label, c("a", "c", "d")) + + # Only those internal values are available inside the glue mask + agent_all <- create_agent(small_table) %>% + col_vals_lt( + c, 8, + label = "{toString(sort(ls(all.names = TRUE)))}" + ) + expect_identical(agent_all$validation_set$label, c(".col, .seg_col, .seg_val, .step")) + +}) + +test_that("glue scope doesn't expose internal variables", { + + # Ex: should not be able to access `columns` local variable in `col_vals_lt()` + expect_error(create_agent(small_table) %>% col_vals_lt(c, 8, label = "{columns}")) + # Ex: should not be able to access `i` local variable in `create_validation_step()` + expect_error(create_agent(small_table) %>% col_vals_lt(c, 8, label = "{i}")) + + # Should be able to access global vars/fns + expect_equal( + create_agent(small_table) %>% + col_vals_lt(c, 8, label = "{match(.col, letters)}") %>% + {.$validation_set$label}, + "3" + ) + +}) + +test_that("glue env searches from the caller env of the validation function", { + + to_upper <- function(x) stop("Oh no!") + + expect_error( + create_agent(small_table) %>% + col_vals_lt(c, 8, label = "{to_upper(.col)}") %>% + {.$validation_set$label}, + "Oh no!" + ) + + expect_equal( + local({ + to_upper <- function(x) toupper(x) + create_agent(small_table) %>% + col_vals_lt(c, 8, label = "{to_upper(.col)}") %>% + {.$validation_set$label} + }), + "C" + ) + +}) + +test_that("materialized multi-length glue labels make the yaml roundtrip", { + + agent_pre <- create_agent(~ small_table) %>% + col_vals_lt( + c, 8, + segments = vars(f), + label = "The `col_vals_lt()` step for group '{.seg_val}'" + ) + # yaml_agent_string(agent_pre, expanded = FALSE) + + agent_yaml <- tempfile() + yaml_write(agent_pre, expanded = FALSE, filename = agent_yaml) + + agent_post <- yaml_read_agent(agent_yaml) + # yaml_agent_string(agent_post, expanded = FALSE) + + expect_identical( + as_agent_yaml_list(agent_pre, expanded = FALSE), + as_agent_yaml_list(agent_post, expanded = FALSE) + ) + expect_identical( + agent_pre %>% interrogate() %>% get_agent_report(display_table = FALSE), + agent_post %>% interrogate() %>% get_agent_report(display_table = FALSE) + ) + +}) + + +test_that("multi-length label collapses when possible in yaml representation", { + + agent_pre <- create_agent(~ small_table) %>% + col_vals_lt( + c, 8, + segments = vars(f), + label = "{nchar(.seg_val) * 0}" + ) + + expect_identical( + as_agent_yaml_list(agent_pre, expanded = FALSE)$steps[[1]]$col_vals_lt$label, + c("0") + ) + +}) + +test_that("glue syntax works for many segments, many columns", { + + agent <- create_agent(~ small_table) %>% + col_vals_lt( + columns = vars(a, c), + value = 8, + segments = f ~ c("high", "low"), + label = "{.col},{.seg_val}" + ) + expect_identical( + strsplit(agent$validation_set$label, ","), + list( + c("a", "high"), + c("a", "low"), + c("c", "high"), + c("c", "low") + ) + ) + +}) + +test_that("glue syntax works for custom vector of labels", { + + # Custom labels show up in order + many_labels <- strsplit("it's a feature not a bug", " ")[[1]] + agent_many_labels <- create_agent(~ small_table) %>% + col_vals_lt( + columns = vars(a, c), + value = 8, + segments = vars(f), + label = paste(many_labels, "({.col}, {.seg_val})") + ) + many_labels_out <- agent_many_labels$validation_set$label + # Loose test on set equality + expect_setequal(gsub(" \\(.*\\)", "", many_labels_out), many_labels) + # Stricter test on order + expect_identical(gsub(" \\(.*\\)", "", many_labels_out), many_labels) + # `resolve_label()` fills matrix by row bc validation functions iterate by row + expect_identical( + pointblank:::resolve_label(many_labels, c("a", "c"), unique(small_table$f)), + matrix(many_labels, nrow = 2, ncol = 3, byrow = TRUE) + ) + + # Labels show up in the order supplied, for multi-column * multi-segment step + agent_many_many_labels <- create_agent(~ small_table) %>% + col_vals_lt( + columns = vars(a, c), + value = 8, + segments = vars(f, e), + label = 1:10 + ) + expect_identical(agent_many_many_labels$validation_set$label, as.character(1:10)) + # Order preserved in the yaml round trip + agent_yaml <- tempfile() + yaml_write(agent_many_many_labels, expanded = FALSE, filename = agent_yaml) + agent_many_many_labels2 <- yaml_read_agent(agent_yaml) + expect_identical( + as_agent_yaml_list(agent_many_many_labels2, expanded = FALSE), + as_agent_yaml_list(agent_many_many_labels2, expanded = FALSE) + ) + + # Errors on length mismatch + expect_error({ + create_agent(~ small_table) %>% + col_vals_lt( + c, 8, + segments = vars(f), + label = c("label 1/3", "label 2/3") + ) + }, "must be length 1 or 3, not 2") + expect_error({ + create_agent(~ small_table) %>% + col_vals_lt( + c, 8, + segments = vars(f), + label = c("label 1/3", "label 2/3", "label 3/3", "label 4/3") + ) + }, "must be length 1 or 3, not 4") + + # NA elements in `label` passed down + some_empty <- c("{.seg_val} is 1 of 3", "{.seg_val} is 2 of 3", NA) + agent_some_empty <- create_agent(~ small_table) %>% + col_vals_lt( + c, 8, + segments = vars(f), + label = some_empty + ) + expect_identical( + agent_some_empty$validation_set$label, + c("high is 1 of 3", "low is 2 of 3", NA_character_) + ) + +}) diff --git a/tests/testthat/test-snip_fns.R b/tests/testthat/test-snip_fns.R index c50191c56..2a41730e4 100644 --- a/tests/testthat/test-snip_fns.R +++ b/tests/testthat/test-snip_fns.R @@ -511,6 +511,30 @@ test_that("the `snip_list()` function works", { small_table ) ) + + # na_rm ignores NA values in list + expect_match( + run_snip( + snip_list(column = "f", na_rm = FALSE), + small_table %>% dplyr::mutate(f = ifelse(f == "high", NA, f)) + ), + "NA" + ) + expect_no_match( + run_snip( + snip_list(column = "f", na_rm = TRUE), + small_table %>% dplyr::mutate(f = ifelse(f == "high", NA, f)) + ), + "NA" + ) + expect_equal( + run_snip( + snip_list(column = "f", na_rm = TRUE), + small_table %>% dplyr::mutate(f = NA) + ), + "---" + ) + }) test_that("the `snip_stats()` function works", { diff --git a/tests/testthat/test-sundering.R b/tests/testthat/test-sundering.R index be126edfb..e3a2d0850 100644 --- a/tests/testthat/test-sundering.R +++ b/tests/testthat/test-sundering.R @@ -548,3 +548,23 @@ test_that("an error occurs if using `get_sundered_data()` when agent has no inte get_sundered_data() ) }) + +test_that("an error occurs if using `get_sundered_data()` when agent is missing `$tbl_checked`", { + + # Expect an error if the agent performed an interrogation + # with `extract_tbl_checked = FALSE` + expect_error( + create_agent(tbl = small_table) %>% + col_vals_gt(vars(date_time), vars(date), na_pass = TRUE) %>% + col_vals_gt(vars(b), vars(g), na_pass = TRUE) %>% + rows_distinct(vars(d, e)) %>% + rows_distinct(vars(a, f)) %>% + col_vals_gt(vars(d), 100) %>% + col_vals_equal(vars(d), vars(d), na_pass = TRUE) %>% + col_vals_between(vars(c), left = vars(a), right = vars(d), na_pass = TRUE) %>% + interrogate(extract_tbl_checked = FALSE) %>% + get_sundered_data(), + "missing `tbl_checked`" + ) +}) + diff --git a/tests/testthat/test-test_fns.R b/tests/testthat/test-test_fns.R index ef2d9fd19..b54d36578 100644 --- a/tests/testthat/test-test_fns.R +++ b/tests/testthat/test-test_fns.R @@ -787,7 +787,8 @@ test_that("pointblank expectation functions produce the correct results", { test_that("expect errors to be expressed by pointblank under some conditions", { - no_col_msg <- "The value for `column` doesn't correspond to a column name." + # no_col_msg <- "The value for `column` doesn't correspond to a column name." + no_col_msg <- "column" # Errors caught and expressed when a column doesn't exist expect_error(test_col_vals_lt(tbl, columns = vars(z), value = 0), regexp = no_col_msg) diff --git a/tests/testthat/test-tidyselect-yaml_columns.R b/tests/testthat/test-tidyselect-yaml_columns.R new file mode 100644 index 000000000..c05f8ee8f --- /dev/null +++ b/tests/testthat/test-tidyselect-yaml_columns.R @@ -0,0 +1,121 @@ +test_that("explicit c()-expr make the yaml roundtrip", { + + agent_pre <- create_agent(~ small_table) %>% + col_vals_lt( + columns = c(a, c), + value = 8 + ) + + agent_yaml <- tempfile() + yaml_write(agent_pre, expanded = FALSE, filename = agent_yaml) + # Writes to c()-expr + expect_true(any(grepl("columns: c(a, c)", readLines(agent_yaml), fixed = TRUE))) + + agent_post <- yaml_read_agent(agent_yaml) + # yaml_agent_string(agent_post, expanded = FALSE) + + expect_identical( + as_agent_yaml_list(agent_pre, expanded = FALSE), + as_agent_yaml_list(agent_post, expanded = FALSE) + ) + expect_identical( + agent_pre %>% interrogate() %>% get_agent_report(display_table = FALSE), + agent_post %>% interrogate() %>% get_agent_report(display_table = FALSE) + ) + + # Defaults writing to c()-expr + expect_message( + create_agent(~ small_table) %>% col_exists(a) %>% yaml_agent_string(), + 'columns: c\\("a"\\)' + ) + +}) + +test_that("everything() default in `rows_*()` makes yaml roundtrip", { + + agent_distinct <- create_agent(~ small_table) %>% + rows_distinct() + agent_complete <- create_agent(~ small_table) %>% + rows_complete() + + expect_message(yaml_agent_string(agent_distinct), "columns: everything\\(\\)") + expect_message(yaml_agent_string(agent_complete), "columns: everything\\(\\)") + + agent_yaml <- tempfile() + # everything() makes yaml round trip for `rows_distinct()` + yaml_write(agent_distinct, expanded = FALSE, filename = agent_yaml) + expect_identical( + as_agent_yaml_list(agent_distinct, expanded = FALSE), + as_agent_yaml_list(yaml_read_agent(agent_yaml), expanded = FALSE) + ) + # everything() makes yaml round trip for `rows_complete()` + yaml_write(agent_complete, expanded = FALSE, filename = agent_yaml) + expect_identical( + as_agent_yaml_list(agent_complete, expanded = FALSE), + as_agent_yaml_list(yaml_read_agent(agent_yaml), expanded = FALSE) + ) + +}) + +test_that("complex column selection expressions make the round trip", { + + # `expanded = FALSE` preserves complex expr and makes roundtrip + agent_pre <- create_agent(~ small_table) %>% + col_vals_lt( + columns = where(is.numeric) & starts_with("c"), + value = 8 + ) + + agent_yaml <- tempfile() + yaml_write(agent_pre, expanded = FALSE, filename = agent_yaml) + agent_post <- yaml_read_agent(agent_yaml) + + expect_message(yaml_agent_string(agent_pre), 'where\\(is.numeric\\) & starts_with\\("c"\\)') + expect_message(yaml_agent_string(agent_post), 'where\\(is.numeric\\) & starts_with\\("c"\\)') + + expect_identical( + as_agent_yaml_list(agent_pre, expanded = FALSE), + as_agent_yaml_list(agent_post, expanded = FALSE) + ) + + expect_identical({ + agent_pre %>% + interrogate() %>% + get_agent_report(display_table = FALSE) + }, { + agent_post %>% + interrogate() %>% + get_agent_report(display_table = FALSE) + }) + + + # `expanded = TRUE` resolves immediately and works as expected + agent_pre <- create_agent(~ small_table) %>% + col_vals_lt( + columns = where(is.numeric) & starts_with("c"), + value = 8 + ) + + agent_yaml <- tempfile() + yaml_write(agent_pre, expanded = TRUE, filename = agent_yaml) + agent_post <- yaml_read_agent(agent_yaml) + + expect_message(yaml_agent_string(agent_pre, expanded = TRUE), 'c\\("c"\\)') + expect_message(yaml_agent_string(agent_post, expanded = TRUE), 'c\\("c"\\)') + + expect_identical( + as_agent_yaml_list(agent_pre, expanded = TRUE), + as_agent_yaml_list(agent_post, expanded = TRUE) + ) + + expect_identical({ + agent_pre %>% + interrogate() %>% + get_agent_report(display_table = FALSE) + }, { + agent_post %>% + interrogate() %>% + get_agent_report(display_table = FALSE) + }) + +}) diff --git a/tests/testthat/test-tidyselect_fails_safely.R b/tests/testthat/test-tidyselect_fails_safely.R new file mode 100644 index 000000000..e80f1e8ec --- /dev/null +++ b/tests/testthat/test-tidyselect_fails_safely.R @@ -0,0 +1,142 @@ +agent <- create_agent(small_table) +z <- rlang::missing_arg() +nonexistent_col <- "z" + +test_that("tidyselect errors signaled at report, not during development of validation plan", { + + # No immediate error for all patterns + expect_s3_class(a1 <- agent %>% col_vals_not_null(z), "ptblank_agent") + expect_s3_class(a2 <- agent %>% col_vals_not_null("z"), "ptblank_agent") + expect_s3_class(a3 <- agent %>% col_vals_not_null(all_of("z")), "ptblank_agent") + expect_s3_class(a4 <- agent %>% col_vals_not_null(all_of(nonexistent_col)), "ptblank_agent") + + # Failure signaled via report + expect_false(a1 %>% interrogate() %>% all_passed()) + expect_false(a2 %>% interrogate() %>% all_passed()) + expect_false(a3 %>% interrogate() %>% all_passed()) + expect_false(a4 %>% interrogate() %>% all_passed()) + +}) + +test_that("fail state correctly registered in the report for tidyselect errors", { + + # Adopted from test-get_agent_report.R ------------------------- + + # The following agent will perform an interrogation that results + # in all test units passing in the second validation step, but + # the first experiences an evaluation error (since column + # `z` doesn't exist in `small_table`) + agent <- + create_agent(tbl = small_table) %>% + col_vals_not_null(all_of("z")) %>% # swapped for `vars("z")` + col_vals_gt(vars(c), 1, na_pass = TRUE) %>% + interrogate() + + # Expect that the interrogation *does not* have + # a completely 'all passed' state (returning FALSE) + agent %>% all_passed() %>% expect_false() + + # If narrowing the `all_passed()` evaluation to only + # the second validation step, then we should expect TRUE + agent %>% all_passed(i = 2) %>% expect_true() + + # If narrowing the `all_passed()` evaluation to only + # the first validation step, then we should expect FALSE + agent %>% all_passed(i = 1) %>% expect_false() + +}) + +test_that("(tidy-)selecting 0 columns = fail at interrogation", { + + eval_errors <- function(x) interrogate(x)$validation_set$eval_error + + # Old behavior for vars()/NULL/ preserved: + ## 1) No immediate error for zero columns selected + expect_s3_class(a5 <- agent %>% col_vals_not_null(vars()), "ptblank_agent") + expect_s3_class(a6 <- agent %>% col_vals_not_null(NULL), "ptblank_agent") + expect_s3_class(a7 <- agent %>% col_vals_not_null(), "ptblank_agent") + ## 2) # Treated as inactive in the report + expect_true(a5 %>% eval_errors()) + expect_true(a6 %>% eval_errors()) + expect_true(a7 %>% eval_errors()) + + # Same behavior of 0-column selection replicated in tidyselect patterns + expect_length(small_table %>% dplyr::select(any_of("z")), 0) + expect_length(small_table %>% dplyr::select(c()), 0) + expect_s3_class(a8 <- agent %>% col_vals_not_null(any_of("z")), "ptblank_agent") + expect_s3_class(a9 <- agent %>% col_vals_not_null(c()), "ptblank_agent") + expect_true(a8 %>% eval_errors()) + expect_true(a9 %>% eval_errors()) + +}) + +test_that("tidyselecting 0 columns for rows_* functions = fail at interrogation", { + + expect_no_error(a_rows_distinct <- agent %>% rows_distinct(starts_with("z")) %>% interrogate()) + expect_no_error(a_rows_complete <- agent %>% rows_complete(starts_with("z")) %>% interrogate()) + expect_true(a_rows_distinct$validation_set$eval_error) + expect_true(a_rows_complete$validation_set$eval_error) + + expect_no_error(a_rows_distinct2 <- agent %>% rows_distinct(any_of("z")) %>% interrogate()) + expect_no_error(a_rows_complete2 <- agent %>% rows_complete(any_of("z")) %>% interrogate()) + expect_true(a_rows_distinct2$validation_set$eval_error) + expect_identical(unlist(a_rows_distinct2$validation_set$column), NA_character_) + expect_true(a_rows_complete2$validation_set$eval_error) + expect_identical(unlist(a_rows_complete2$validation_set$column), NA_character_) + +}) + +test_that("tidyselect errors *are* immediate for assertion/expectation/test", { + + # For validation steps used on table + expect_error(small_table %>% col_vals_not_null(z)) + expect_error(small_table %>% col_vals_not_null("z")) + expect_error(small_table %>% col_vals_not_null(all_of("z"))) + expect_error(small_table %>% col_vals_not_null(all_of(nonexistent_col))) + + # For expectations + expect_error(small_table %>% expect_col_vals_not_null(z)) + expect_error(small_table %>% expect_col_vals_not_null("z")) + expect_error(small_table %>% expect_col_vals_not_null(all_of("z"))) + expect_error(small_table %>% expect_col_vals_not_null(all_of(nonexistent_col))) + + # For tests + expect_error(small_table %>% test_col_vals_not_null(z)) + expect_error(small_table %>% test_col_vals_not_null("z")) + expect_error(small_table %>% test_col_vals_not_null(all_of("z"))) + expect_error(small_table %>% test_col_vals_not_null(all_of(nonexistent_col))) + +}) + +test_that("tidyselect errors cannot be downgraded in assertion/expectation on table", { + + # This replicates old behavior + expect_error({ + small_table %>% + col_vals_not_null(a) %>% + col_vals_not_null(z, actions = warn_on_fail()) %>% + col_vals_not_null(b) + }) + +}) + +test_that("env scoping with bare symbol patterns", { + + # `z` is external vector of valid column + z <- "a" + rlang::local_options(lifecycle_verbosity = "warning") + expect_warning(small_table %>% col_vals_not_null(z)) + rlang::local_options(lifecycle_verbosity = "quiet") + + # `z` is not character + z <- mtcars + # c() and vars() both error, but different reasons + ## c() scopes z in env and determines its invalid ("must be numeric or character") + expect_error(small_table %>% col_vals_not_null(c(z))) + ## vars() doesn't attempt to scope z in env at all ("doesn't exist") + expect_error(small_table %>% col_vals_not_null(vars(z))) + + # Cleanup + z <- rlang::missing_arg() + +}) diff --git a/tests/testthat/test-tidyselect_fails_safely_batch.R b/tests/testthat/test-tidyselect_fails_safely_batch.R new file mode 100644 index 000000000..a79369557 --- /dev/null +++ b/tests/testthat/test-tidyselect_fails_safely_batch.R @@ -0,0 +1,182 @@ +agent <- create_agent(tbl = small_table[, c("a", "b", "c")]) +z <- rlang::missing_arg() +mixed_cols <- c("a", "z") + +# Column selection expressions to test +select_exprs <- rlang::quos( + empty = , + null = NULL, + exists = a, + nonexistent = z, + mixed = c(a, z), + mixed_all = all_of(mixed_cols), + mixed_any = any_of(mixed_cols), + empty_tidyselect = starts_with("z") +) + +# Properties of `$validation_set` to test +get_behaviors <- function(vs) { + list( + n_steps = nrow(vs), + column = unlist(vs$column), + eval_error = any(vs$eval_error) + ) +} + +# Dimnames for `expected_behaviors` matrix +behaviors_dimnames <- list( + property = c("n_steps", "column", "eval_error"), + col_select = names(select_exprs) +) + +test_that("`col_*()`s show expected column selection failure/success behavior", { + + expected_behaviors <- matrix( + c( + list(1L, 1L, 1L, 1L, 2L, 2L, 1L, 1L), + list(NA_character_, NA_character_, "a", "z", c("a", "z"), c("a", "z"), "a", NA_character_), + list(T, T, F, T, T, T, F, T) + ), + ncol = length(select_exprs), byrow = TRUE, dimnames = behaviors_dimnames + ) + expected_behaviors + # | |empty/null |exists |nonexistent |mixed |mixed_all |mixed_any |empty_tidyselect | + # |:----------|:----------|:------|:-----------|:-----------|:-----------|:---------|:----------------| + # |n_steps |1 |1 |1 |2 |2 |1 |1 | + # |column |NA |a |z |c("a", "z") |c("a", "z") |a |NA | + # |eval_error |TRUE |FALSE |TRUE |TRUE |TRUE |FALSE |TRUE | + + check_behaviors <- function(agent, expr_name) { + x <- suppressMessages(interrogate(agent)) + behaviors <- get_behaviors(x$validation_set) + expect_identical(behaviors[["n_steps"]], expected_behaviors[["n_steps", expr_name]]) + expect_identical(behaviors[["column"]], expected_behaviors[["column", expr_name]]) + expect_identical(behaviors[["eval_error"]], expected_behaviors[["eval_error", expr_name]]) + } + + for (expr_name in names(select_exprs)) { + + select_expr <- select_exprs[[expr_name]] + + agent %>% col_vals_lt({{ select_expr }}, value = 5) %>% check_behaviors(expr_name) + agent %>% col_vals_lte({{ select_expr }}, value = 5) %>% check_behaviors(expr_name) + agent %>% col_vals_equal({{ select_expr }}, value = 5) %>% check_behaviors(expr_name) + agent %>% col_vals_not_equal({{ select_expr }}, value = 5) %>% check_behaviors(expr_name) + agent %>% col_vals_gte({{ select_expr }}, value = 5) %>% check_behaviors(expr_name) + agent %>% col_vals_gt({{ select_expr }}, value = 5) %>% check_behaviors(expr_name) + agent %>% col_vals_between({{ select_expr }}, 2, 5) %>% check_behaviors(expr_name) + agent %>% col_vals_not_between({{ select_expr }}, 2, 5) %>% check_behaviors(expr_name) + agent %>% col_vals_in_set({{ select_expr }}, c(2, 5)) %>% check_behaviors(expr_name) + agent %>% col_vals_not_in_set({{ select_expr }}, c(2, 5)) %>% check_behaviors(expr_name) + agent %>% col_vals_make_set({{ select_expr }}, c(2, 5)) %>% check_behaviors(expr_name) + agent %>% col_vals_make_subset({{ select_expr }}, c(2, 5)) %>% check_behaviors(expr_name) + agent %>% col_vals_null({{ select_expr }}) %>% check_behaviors(expr_name) + agent %>% col_vals_not_null({{ select_expr }}) %>% check_behaviors(expr_name) + agent %>% col_vals_increasing({{ select_expr }}) %>% check_behaviors(expr_name) + agent %>% col_vals_decreasing({{ select_expr }}) %>% check_behaviors(expr_name) + agent %>% col_vals_regex({{ select_expr }}, regex = "abc") %>% check_behaviors(expr_name) + agent %>% col_vals_within_spec({{ select_expr }}, spec = "email") %>% check_behaviors(expr_name) + agent %>% col_is_character({{ select_expr }}) %>% check_behaviors(expr_name) + agent %>% col_is_numeric({{ select_expr }}) %>% check_behaviors(expr_name) + agent %>% col_is_integer({{ select_expr }}) %>% check_behaviors(expr_name) + agent %>% col_is_logical({{ select_expr }}) %>% check_behaviors(expr_name) + agent %>% col_is_date({{ select_expr }}) %>% check_behaviors(expr_name) + agent %>% col_is_posix({{ select_expr }}) %>% check_behaviors(expr_name) + agent %>% col_is_factor({{ select_expr }}) %>% check_behaviors(expr_name) + } + +}) + +test_that("`rows_*()`s show expected column selection failure/success behavior", { + + all_cols <- toString(colnames(agent$tbl)) + + expected_behaviors <- matrix( + c( + list(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), + list(all_cols, all_cols, "a", "z", "a, z", "a, z", "a", NA_character_), + list(F, F, F, T, T, T, F, T) + ), + ncol = length(select_exprs), byrow = TRUE, dimnames = behaviors_dimnames + ) + expected_behaviors + # | |empty/null |exists |nonexistent |mixed |mixed_all |mixed_any |empty_tidyselect | + # |:----------|:----------|:------|:-----------|:-----|:---------|:---------|:----------------| + # |n_steps |1 |1 |1 |1 |1 |1 |1 | + # |column |a, b, c |a |z |a, z |a, z |a |NA | + # |eval_error |FALSE |FALSE |TRUE |TRUE |TRUE |FALSE |TRUE | + + check_behaviors <- function(agent, expr_name) { + x <- suppressMessages(interrogate(agent)) + behaviors <- get_behaviors(x$validation_set) + expect_identical(behaviors[["n_steps"]], expected_behaviors[["n_steps", expr_name]]) + expect_identical(behaviors[["column"]], expected_behaviors[["column", expr_name]]) + expect_identical(behaviors[["eval_error"]], expected_behaviors[["eval_error", expr_name]]) + } + + for (expr_name in names(select_exprs)) { + + select_expr <- select_exprs[[expr_name]] + + agent %>% rows_distinct({{ select_expr }}) %>% check_behaviors(expr_name) + agent %>% rows_complete({{ select_expr }}) %>% check_behaviors(expr_name) + + } + +}) + +test_that("`col_exists()`s show expected column selection failure/success behavior", { + + expected_behaviors <- matrix( + c( + list(1L, 1L, 1L, 1L, 2L, 2L, 1L, 1L), + list(NA_character_, NA_character_, "a", "z", c("a", "z"), c("a", "z"), "a", NA_character_), + list(T, T, F, F, F, F, F, F) + ), + ncol = length(select_exprs), byrow = TRUE, dimnames = behaviors_dimnames + ) + expected_behaviors + # | |empty/null |exists |nonexistent |mixed |mixed_all |mixed_any |empty_tidyselect | + # |:----------|:----------|:------|:-----------|:-----------|:-----------|:---------|:----------------| + # |n_steps |1 |1 |1 |2 |2 |1 |1 | + # |column |NA |a |z |c("a", "z") |c("a", "z") |a |NA | + # |eval_error |TRUE |FALSE |FALSE |FALSE |FALSE |FALSE |FALSE | + + check_behaviors <- function(agent, expr_name) { + x <- suppressMessages(interrogate(agent)) + behaviors <- get_behaviors(x$validation_set) + expect_identical(behaviors[["n_steps"]], expected_behaviors[["n_steps", expr_name]]) + expect_identical(behaviors[["column"]], expected_behaviors[["column", expr_name]]) + expect_identical(behaviors[["eval_error"]], expected_behaviors[["eval_error", expr_name]]) + } + + for (expr_name in names(select_exprs)) { + + select_expr <- select_exprs[[expr_name]] + + agent %>% col_exists({{ select_expr }}) %>% check_behaviors(expr_name) + + } + +}) + +test_that("Genuine evaluation errors are rethrown immediately (tested on a sample)", { + + errs <- rlang::quos( + "Oh no!" = stop("Oh no!"), + "not found" = all_of(I_dont_exist) + ) + simple_err1 <- rlang::quo(stop("Oh no!")) + simple_err2 <- rlang::quo(all_of(I_dont_exist)) + + for (err_regex in names(errs)) { + + err_expr <- errs[[err_regex]] + + expect_error(agent %>% col_vals_between({{ err_expr }}, 2, 5)) + expect_error(agent %>% rows_distinct({{ err_expr }})) + expect_error(agent %>% col_exists({{ err_expr }})) + + } + +}) diff --git a/tests/testthat/test-tidyselect_integration.R b/tests/testthat/test-tidyselect_integration.R new file mode 100644 index 000000000..3104242e2 --- /dev/null +++ b/tests/testthat/test-tidyselect_integration.R @@ -0,0 +1,244 @@ +tbl <- data.frame(x = 1:2, y = 1:2, nonunique = "A") +exist_col <- "y" +nonunique_col <- "nonunique" +nonexist_col <- "z" +z <- rlang::missing_arg() + +test_that("Backwards compatibility with `vars()`", { + + # Bare symbol selects column(s) + expect_success(expect_rows_distinct(tbl, vars(x))) + expect_success(expect_rows_distinct(tbl, vars(x, nonunique))) + expect_failure(expect_rows_distinct(tbl, vars(nonunique))) + + # Bare character selects column(s) + expect_success(expect_rows_distinct(tbl, vars("x"))) + expect_success(expect_rows_distinct(tbl, vars("x", "nonunique"))) + expect_failure(expect_rows_distinct(tbl, vars("nonunique"))) + + # Bang-bang in-lines value + expect_success(expect_rows_distinct(tbl, vars(!!exist_col))) + expect_failure(expect_rows_distinct(tbl, vars(!!nonunique_col))) + + # `vars()` wrapping tidyselect expressions is redundant but continues to work + expect_success(expect_rows_distinct(tbl, vars(all_of("x")))) + + # `vars()` selection of 0-columns errors *only* in non-validation-planning contexts + expect_error(rows_distinct(tbl, vars("z"))) + expect_error(expect_rows_distinct(tbl, vars("z"))) + expect_error(test_rows_distinct(tbl, vars("z"))) + expect_no_error(tbl %>% create_agent() %>% rows_distinct(vars("z"))) + expect_no_error(tbl %>% create_agent() %>% rows_distinct(vars("z")) %>% interrogate()) + +}) + +test_that("Full range of tidyselect features available in column selection", { + + # Single symbol + expect_success(expect_rows_distinct(tbl, x)) + expect_failure(expect_rows_distinct(tbl, nonunique)) + + # Preferred {tidyselect}-style `c()` syntax + expect_success(expect_rows_distinct(tbl, c(x))) + expect_success(expect_rows_distinct(tbl, c(x, nonunique))) + expect_failure(expect_rows_distinct(tbl, c(nonunique))) + + # {tidyselect} functions + expect_success(expect_rows_distinct(tbl, tidyselect::all_of("x"))) + expect_success(expect_rows_distinct(tbl, tidyselect::all_of(c("x", "nonunique")))) + expect_failure(expect_rows_distinct(tbl, tidyselect::all_of("nonunique"))) + + # NEW: {tidyselect} integer indexing + expect_success(expect_rows_distinct(tbl, 1)) + expect_success(expect_rows_distinct(tbl, c(1, 3))) + expect_failure(expect_rows_distinct(tbl, 3)) + + # NEW: {tidyselect} negative indexing + expect_success(expect_rows_distinct(tbl, -(2:3))) + expect_success(expect_rows_distinct(tbl, -2)) + expect_failure(expect_rows_distinct(tbl, -(1:2))) + + # NEW: {tidyselect} `where()` predicate: + expect_success(expect_rows_distinct(tbl, !tidyselect::where(is.character))) + expect_success(expect_rows_distinct(tbl, tidyselect::where(is.numeric))) + expect_error(expect_rows_distinct(tbl, tidyselect::where(is.character))) + + # NEW: {tidyselect} functions in complex expressions + expect_success(expect_rows_distinct(tbl, c(x, tidyselect::all_of(exist_col)))) + expect_error(expect_rows_distinct(tbl, c(x, tidyselect::all_of(nonexist_col)))) + expect_success(expect_rows_distinct(tbl, c(x, tidyselect::any_of(nonexist_col)))) + + # Supplying a character vector variable still works, but signals deprecation: + rlang::local_options(lifecycle_verbosity = "warning") + expect_success(expect_warning( + expect_rows_distinct(tbl, exist_col), + "Using an external vector in selections was deprecated in tidyselect 1.1.0." + )) + +}) + +test_that("'NULL = select everything' behavior in rows_*() validation functions", { + + # For `rows_*()` functions specifically, empty/NULL = "select everything" behavior: + expect_success(expect_rows_distinct(data.frame(x = 1, y = 2))) + expect_success(expect_rows_complete(data.frame(x = 1, y = 2))) + expect_failure(expect_rows_distinct(data.frame(x = c(1, 1)))) + expect_failure(expect_rows_complete(data.frame(x = c(1, NA)))) + expect_success(expect_rows_distinct(data.frame(x = 1, y = 2), columns = NULL)) + expect_success(expect_rows_complete(data.frame(x = 1, y = 2), columns = NULL)) + expect_failure(expect_rows_distinct(data.frame(x = c(1, 1)), columns = NULL)) + expect_failure(expect_rows_complete(data.frame(x = c(1, NA)), columns = NULL)) + + # Report shows all column names with empty `columns` argument + expect_equal({ + small_table %>% + create_agent() %>% + rows_distinct() %>% + rows_complete() %>% + interrogate() %>% + {.$validation_set$column} %>% + unlist() %>% + unique() + }, toString(colnames(small_table))) + + # Report shows all column names with explicit NULL `columns` argument + expect_equal({ + small_table %>% + create_agent() %>% + rows_distinct(columns = NULL) %>% + rows_complete(columns = NULL) %>% + interrogate() %>% + {.$validation_set$column} %>% + unlist() %>% + unique() + }, toString(colnames(small_table))) + +}) + +test_that("tidyselect coverage for `col_exists()`", { + + # Reprex from (#433) + df <- tibble::tibble( + id.x = 1:3, + id.y = 1:3, + stuff = 1:3 + ) + expect_success({ + df %>% + expect_col_exists( + columns = vars(ends_with(".x")) + ) + }) + expect_equal({ + df %>% + col_exists( + columns = vars(ends_with(".x")) + ) + }, df) + + # Multiple column selection produces multiple steps + expect_no_error({ + df_interrogated <- df %>% + create_agent() %>% + col_exists(starts_with("id")) %>% + interrogate() + }) + expect_equal(nrow(df_interrogated$validation_set), 2L) + +}) + +test_that("error/failure patterns for `col_exists`", { + + # Selecting non-existent columns signals failure + expect_error(expect_failure({ + small_table %>% + col_exists("z") + })) + expect_failure({ + small_table %>% + expect_col_exists("z") + }) + + # 0-column tidyselect selection signals failure + expect_error(expect_failure({ + small_table %>% + col_exists(starts_with("z")) + })) + expect_failure({ + small_table %>% + expect_col_exists("z") + }) + + # Unrelated evaluation errors should be chained and rethrown + expect_error({ + small_table %>% + col_exists(stop("Error!")) + }, "Error!") + expect_error({ + small_table %>% + expect_col_exists(stop("Error!")) + }, "Error!") + expect_error({ + small_table %>% + test_col_exists(stop("Error!")) + }, "Error!") + + # Test should return FALSE for 0-column and non-existent column + expect_false({ + small_table %>% + test_col_exists("z") + }) + expect_false({ + small_table %>% + test_col_exists("z") + }) + + # No failure/error during validation + expect_no_error({ + agent_nonexist_col <- create_agent(small_table) %>% + col_exists("z") %>% + interrogate() + }) + expect_false(all_passed(agent_nonexist_col)) + expect_no_error({ + agent_tidyselect_0col <- create_agent(small_table) %>% + col_exists(starts_with("z")) %>% + interrogate() + }) + expect_false(all_passed(agent_tidyselect_0col)) + +}) + +test_that("c()-expr works for serially", { + + # Example from `serially()` docs + tbl <- + dplyr::tibble( + a = c(5, 2, 6), + b = c(6, 4, 9), + c = c(1, 2, 3) + ) + agent_1 <- + create_agent(tbl = tbl) %>% + serially( + ~ test_col_is_numeric(., columns = vars(a, b)), + ~ test_col_vals_not_null(., columns = vars(a, b)), + ~ col_vals_gt(., columns = vars(b), value = vars(a)) + ) %>% + interrogate() + expect_no_error({ + agent_1_c <- + create_agent(tbl = tbl) %>% + serially( + ~ test_col_is_numeric(., columns = c(a, b)), + ~ test_col_vals_not_null(., columns = c(a, b)), + ~ col_vals_gt(., columns = b, value = vars(a)) + ) %>% + interrogate() + }) + expect_identical( + get_agent_report(agent_1, display_table = FALSE)$n_pass, + get_agent_report(agent_1_c, display_table = FALSE)$n_pass + ) + +}) diff --git a/tests/testthat/test-x_list.R b/tests/testthat/test-x_list.R index 3f1710c50..bd48b4775 100644 --- a/tests/testthat/test-x_list.R +++ b/tests/testthat/test-x_list.R @@ -152,11 +152,11 @@ test_that("An x-list for a step is structurally correct", { expect_is(x_list_after$capture_stack, "list") expect_equal( length(x_list_after$capture_stack %>% unlist(recursive = FALSE)), - 2 + 3 ) expect_equal( names(x_list_after$capture_stack %>% unlist(recursive = FALSE)), - c("warning", "error") + c("warning", "error", "pb_call") ) expect_is(x_list_after$n, "numeric") expect_equal(x_list_after$n, 13) diff --git a/tests/testthat/test-yaml.R b/tests/testthat/test-yaml.R index 7c0447f9b..22ba9bcdc 100644 --- a/tests/testthat/test-yaml.R +++ b/tests/testthat/test-yaml.R @@ -800,7 +800,7 @@ test_that("Individual validation steps make the YAML round-trip successfully", { expect_equal( get_oneline_expr_str(agent %>% rows_distinct()), - "rows_distinct()" + "rows_distinct(columns = everything())" ) expect_equal( get_oneline_expr_str(agent %>% rows_distinct(columns = vars(a, b))), @@ -888,3 +888,4 @@ test_that("Individual validation steps make the YAML round-trip successfully", { "col_schema_match(schema = col_schema(a = \"integer\",b = \"character\"),label = \"my_label\")" ) }) + diff --git a/tests/testthat/test-yaml_read_informant.R b/tests/testthat/test-yaml_read_informant.R index 3ca8bb101..3291f5178 100644 --- a/tests/testthat/test-yaml_read_informant.R +++ b/tests/testthat/test-yaml_read_informant.R @@ -35,7 +35,6 @@ test_that("Reading an informant from YAML is possible", { section_name = "rows", row_count = "There are {row_count} rows available." ) - yaml_write(informant, filename = "informant-test_table.yml") informant_from_yaml <- yaml_read_informant(filename = "informant-test_table.yml") @@ -60,6 +59,8 @@ test_that("Reading an informant from YAML is possible", { # Expect that the informant (which never had `incorporate()` # run on it) is equivalent to the informant object created # via `yaml_read_informant()` (i.e., reading in the YAML file) + # - *Except* private fields which are note written + informant$metadata$`_private` <- NULL expect_equivalent(informant, informant_from_yaml) # Use `incorporate()` on the informant; this creates the list diff --git a/vignettes/INFO-1.Rmd b/vignettes/INFO-1.Rmd index cea9ff8c0..c2bf67805 100644 --- a/vignettes/INFO-1.Rmd +++ b/vignettes/INFO-1.Rmd @@ -71,7 +71,7 @@ informant <- description = "This table is included in the **pointblank** pkg." ) %>% info_columns( - columns = "date_time", + columns = date_time, info = "This column is full of timestamps." ) %>% info_section( @@ -97,7 +97,7 @@ The `info_tabular()` function adds information to the **TABLE** section. We use ```{r eval=FALSE} informant %>% - info_tabular(`🔄 updates` = "This table is not regularly updated.") + info_tabular("🔄 updates" = "This table is not regularly updated.") ```
% info_columns( - columns = "species", + columns = species, `ℹ️` = "A factor denoting penguin species (*Adélie*, *Chinstrap*, and *Gentoo*)." ) %>% info_columns( - columns = "island", + columns = island, `ℹ️` = "A factor denoting island in Palmer Archipelago, Antarctica (*Biscoe*, *Dream*, or *Torgersen*)." ) %>% info_columns( - columns = "bill_length_mm", + columns = bill_length_mm, `ℹ️` = "A number denoting bill length" ) %>% info_columns( - columns = "bill_depth_mm", + columns = bill_depth_mm, `ℹ️` = "A number denoting bill depth" ) %>% info_columns( - columns = "flipper_length_mm", + columns = flipper_length_mm, `ℹ️` = "An integer denoting flipper length" ) %>% info_columns( @@ -153,15 +153,15 @@ informant_pp <- `ℹ️` = "(in units of millimeters)." ) %>% info_columns( - columns = "body_mass_g", + columns = body_mass_g, `ℹ️` = "An integer denoting body mass (grams)." ) %>% info_columns( - columns = "sex", + columns = sex, `ℹ️` = "A factor denoting penguin sex (`\"female\"`, `\"male\"`)." ) %>% info_columns( - columns = "year", + columns = year, `ℹ️` = "The study year (e.g., `2007`, `2008`, `2009`)." ) diff --git a/vignettes/INFO-2.Rmd b/vignettes/INFO-2.Rmd index 49ba46e76..367a58604 100644 --- a/vignettes/INFO-2.Rmd +++ b/vignettes/INFO-2.Rmd @@ -44,7 +44,7 @@ The `small_table` dataset is associated with the `informant` as the target table informant <- informant %>% info_columns( - columns = vars(d), + columns = d, info = "This column contains fairly large numbers (much larger than those numbers in column `a`. The mean value is {mean_d}, which is far greater than any number in that other column." @@ -76,7 +76,7 @@ informant <- fn = ~ . %>% .$d %>% mean() %>% round(1) ) %>% info_columns( - columns = vars(d), + columns = d, info = "This column contains fairly large numbers (much larger than those numbers in column `a`. The mean value is {mean_d}, which is far greater than any number in that other column." @@ -181,11 +181,11 @@ informant_pp <- label = "The `penguins` dataset from the **palmerpenguins** 📦." ) %>% info_columns( - columns = "species", + columns = species, `ℹ️` = "A factor denoting penguin species ({species_snippet})." ) %>% info_columns( - columns = "island", + columns = island, `ℹ️` = "A factor denoting island in Palmer Archipelago, Antarctica ({island_snippet})." ) %>% @@ -216,7 +216,7 @@ This also works for numeric values. Let's use `snip_list()` to provide a text sn informant_pp <- informant_pp %>% info_columns( - columns = "year", + columns = year, `ℹ️` = "The study year ({year_snippet})." ) %>% info_snippet( @@ -244,16 +244,16 @@ We can get the lowest and highest values from a column and inject those formatte informant_pp <- informant_pp %>% info_columns( - columns = "bill_length_mm", + columns = bill_length_mm, `ℹ️` = "A number denoting bill length" ) %>% info_columns( - columns = "bill_depth_mm", + columns = bill_depth_mm, `ℹ️` = "A number denoting bill depth (in the range of {min_depth} to {max_depth} millimeters)." ) %>% info_columns( - columns = "flipper_length_mm", + columns = flipper_length_mm, `ℹ️` = "An integer denoting flipper length" ) %>% info_columns( @@ -261,7 +261,7 @@ informant_pp <- `ℹ️` = "(in units of millimeters)." ) %>% info_columns( - columns = "flipper_length_mm", + columns = flipper_length_mm, `ℹ️` = "Largest observed is {largest_flipper_length} mm." ) %>% info_snippet( @@ -338,7 +338,7 @@ We can take portions of text and present them as labels. These will help you cal informant_pp <- informant_pp %>% info_columns( - columns = vars(body_mass_g), + columns = body_mass_g, `ℹ️` = "An integer denoting body mass." ) %>% info_columns( @@ -396,7 +396,7 @@ Continuing with our **palmerpenguins** reporting, we'll add some more *info text informant_pp <- informant_pp %>% info_columns( - columns = vars(sex), + columns = sex, `ℹ️` = "A [[factor]]<> denoting penguin sex (female or male)." ) %>% diff --git a/vignettes/VALID-I.Rmd b/vignettes/VALID-I.Rmd index 4e71df350..5e44e57b4 100644 --- a/vignettes/VALID-I.Rmd +++ b/vignettes/VALID-I.Rmd @@ -82,11 +82,11 @@ agent <- tbl_name = "small_table", label = "VALID-I Example No. 1" ) %>% - col_is_posix(vars(date_time)) %>% - col_vals_in_set(vars(f), set = c("low", "mid", "high")) %>% - col_vals_lt(vars(a), value = 10) %>% - col_vals_regex(vars(b), regex = "^[0-9]-[a-z]{3}-[0-9]{3}$") %>% - col_vals_between(vars(d), left = 0, right = 5000) %>% + col_is_posix(date_time) %>% + col_vals_in_set(f, set = c("low", "mid", "high")) %>% + col_vals_lt(a, value = 10) %>% + col_vals_regex(b, regex = "^[0-9]-[a-z]{3}-[0-9]{3}$") %>% + col_vals_between(d, left = 0, right = 5000) %>% interrogate() ``` @@ -147,11 +147,11 @@ agent <- label = "VALID-I Example No. 2", actions = al ) %>% - col_is_posix(vars(date_time)) %>% - col_vals_in_set(vars(f), set = c("low", "mid")) %>% - col_vals_lt(vars(a), value = 7) %>% - col_vals_regex(vars(b), regex = "^[0-9]-[a-w]{3}-[2-9]{3}$") %>% - col_vals_between(vars(d), left = 0, right = 4000) %>% + col_is_posix(date_time) %>% + col_vals_in_set(f, set = c("low", "mid")) %>% + col_vals_lt(a, value = 7) %>% + col_vals_regex(b, regex = "^[0-9]-[a-w]{3}-[2-9]{3}$") %>% + col_vals_between(d, left = 0, right = 4000) %>% interrogate() ``` @@ -204,11 +204,11 @@ agent <- label = "VALID-I Example No. 3", actions = al ) %>% - col_is_posix(vars(date_time)) %>% - col_vals_in_set(vars(f), set = c("low", "mid")) %>% - col_vals_lt(vars(a), value = 7) %>% - col_vals_regex(vars(b), regex = "^[0-9]-[a-w]{3}-[2-9]{3}$") %>% - col_vals_between(vars(d), left = 0, right = 4000) %>% + col_is_posix(date_time) %>% + col_vals_in_set(f, set = c("low", "mid")) %>% + col_vals_lt(a, value = 7) %>% + col_vals_regex(b, regex = "^[0-9]-[a-w]{3}-[2-9]{3}$") %>% + col_vals_between(d, left = 0, right = 4000) %>% interrogate() ``` @@ -267,7 +267,7 @@ The message in the console shows us what's available in `x`, with some indicatio glue::glue( "In Step {x$i}, there were {x$n} test units and {x$f_failed * 100}% \\ failed. STOP condition met: {tolower(x$stop)}." - ) +) ``` ``` diff --git a/vignettes/VALID-II.Rmd b/vignettes/VALID-II.Rmd index 2a51d6bd4..1d312db9c 100644 --- a/vignettes/VALID-II.Rmd +++ b/vignettes/VALID-II.Rmd @@ -19,11 +19,11 @@ Let's adapt an example used in the [*VALID-I: Data Quality Reporting Workflow*]( ```{r error=TRUE, paged.print=FALSE} small_table %>% - col_is_posix(vars(date_time)) %>% - col_vals_in_set(vars(f), set = c("low", "mid", "high")) %>% - col_vals_lt(vars(a), value = 10) %>% - col_vals_regex(vars(b), regex = "^[0-9]-[a-z]{3}-[0-9]{3}$") %>% - col_vals_between(vars(d), left = 0, right = 5000) + col_is_posix(date_time) %>% + col_vals_in_set(f, set = c("low", "mid", "high")) %>% + col_vals_lt(a, value = 10) %>% + col_vals_regex(b, regex = "^[0-9]-[a-z]{3}-[0-9]{3}$") %>% + col_vals_between(d, left = 0, right = 5000) ``` In terms of the expressions used in the pipeline, you might notice that the `create_agent()` and `interrogate()` functions are absent. This is due to the secondary role of the validation functions, where they can operate directly and immediately on the data, acting as a sort of filter. If all validations in this pipeline pass (i.e., there are no failing test units in any of the validation steps), then the `small_table` data is returned. Otherwise, as it's currently written, a stoppage will occur on any such failure. @@ -41,23 +41,23 @@ There are two helper functions that are convenient for this workflow: `warn_on_f ```{r error=TRUE, paged.print=FALSE} small_table %>% col_is_posix( - vars(date_time), + date_time, actions = stop_on_fail(stop_at = 1) ) %>% col_vals_in_set( - vars(f), set = c("low", "mid", "high"), + f, set = c("low", "mid", "high"), actions = stop_on_fail(stop_at = 1) ) %>% col_vals_lt( - vars(a), value = 10, + a, value = 10, actions = stop_on_fail(stop_at = 1) ) %>% col_vals_regex( - vars(b), regex = "^[0-9]-[a-z]{3}-[0-9]{3}$", + b, regex = "^[0-9]-[a-z]{3}-[0-9]{3}$", actions = stop_on_fail(stop_at = 1) ) %>% col_vals_between( - vars(d), left = 0, right = 5000, + d, left = 0, right = 5000, actions = stop_on_fail(stop_at = 1) ) ``` @@ -67,23 +67,23 @@ If we want to instead issue warnings, perhaps with less stringent failure thresh ```{r warn=TRUE, paged.print=FALSE} small_table %>% col_is_posix( - vars(date_time), + date_time, actions = warn_on_fail() ) %>% col_vals_in_set( - vars(f), set = c("low", "mid", "high"), + f, set = c("low", "mid", "high"), actions = warn_on_fail(warn_at = 0.2) ) %>% col_vals_lt( - vars(a), value = 10, + a, value = 10, actions = warn_on_fail(warn_at = 3) ) %>% col_vals_regex( - vars(b), regex = "^[0-9]-[a-z]{3}-[0-9]{3}$", + b, regex = "^[0-9]-[a-z]{3}-[0-9]{3}$", actions = warn_on_fail(warn_at = 0.2) ) %>% col_vals_between( - vars(d), left = 0, right = 5000, + d, left = 0, right = 5000, actions = warn_on_fail(warn_at = 1) ) ``` @@ -122,11 +122,11 @@ Finally, we will apply this object to every validation function call in the expr ```{r error=TRUE, paged.print=FALSE} small_table %>% - col_is_posix(vars(date_time), actions = al) %>% - col_vals_in_set(vars(f), set = c("low", "mid"), actions = al) %>% - col_vals_lt(vars(a), value = 7, actions = al) %>% - col_vals_regex(vars(b), regex = "^[0-9]-[a-w]{3}-[2-9]{3}$", actions = al) %>% - col_vals_between(vars(d), left = 0, right = 4000, actions = al) + col_is_posix(date_time, actions = al) %>% + col_vals_in_set(f, set = c("low", "mid"), actions = al) %>% + col_vals_lt(a, value = 7, actions = al) %>% + col_vals_regex(b, regex = "^[0-9]-[a-w]{3}-[2-9]{3}$", actions = al) %>% + col_vals_between(d, left = 0, right = 4000, actions = al) ``` In addition to an error and a warning, the `log4r_step()` function used for the `NOTIFY` condition generates, in this case, a new `"pb_log_file"` text file for logs. We can examine it with `readLines()`; it has a single entry that relates to `Step 1` (the `col_vals_in_set()` step): diff --git a/vignettes/VALID-III.Rmd b/vignettes/VALID-III.Rmd index d3938bb20..0cedadca6 100644 --- a/vignettes/VALID-III.Rmd +++ b/vignettes/VALID-III.Rmd @@ -66,7 +66,7 @@ There is no **testthat** function that tests for values between two values. The The **pointblank** version of this task makes for a more succinct and understandable expectation expression: ```{r} -expect_col_vals_between(small_table, vars(c), 2, 9, na_pass = TRUE) +expect_col_vals_between(small_table, c, 2, 9, na_pass = TRUE) ``` The arguments in the `expect_col_vals_between()` give us everything we need to check tabular data without having to do subsetting and perform other transformations. There are a few added benefits. Should data come from a data source other than a local data frame, the SQL expressions are handled internally and they have been tested extensively across all the supported database types and in Spark DataFrames as well. diff --git a/vignettes/VALID-IV.Rmd b/vignettes/VALID-IV.Rmd index 2a48969b7..0c03fc13a 100644 --- a/vignettes/VALID-IV.Rmd +++ b/vignettes/VALID-IV.Rmd @@ -223,19 +223,19 @@ If you'd like to test your **pointblank** validation skill, guess whether each o ```{r echo=FALSE, eval=FALSE} -small_table %>% test_col_is_logical(vars(e)) +small_table %>% test_col_is_logical(e) ``` ```{r echo=FALSE, eval=FALSE} -small_table %>% test_col_vals_between(vars(c), left = 1, right = 10) +small_table %>% test_col_vals_between(c, left = 1, right = 10) ``` ```{r echo=FALSE, eval=FALSE} -small_table %>% test_col_vals_between(vars(c), left = 0, right = vars(d), na_pass = TRUE, threshold = 0.5) +small_table %>% test_col_vals_between(c, left = 0, right = vars(d), na_pass = TRUE, threshold = 0.5) ``` ```{r echo=FALSE, eval=FALSE} -small_table %>% test_col_vals_between(vars(c), left = 0, right = vars(d), na_pass = TRUE, threshold = 3) +small_table %>% test_col_vals_between(c, left = 0, right = vars(d), na_pass = TRUE, threshold = 3) ``` ```{r echo=FALSE, eval=FALSE} @@ -243,21 +243,21 @@ small_table %>% test_col_schema_match(col_schema(.tbl = small_table_sqlite())) ``` ```{r echo=FALSE, eval=FALSE} -small_table %>% test_col_vals_in_set(vars(a), set = 1:10) +small_table %>% test_col_vals_in_set(a, set = 1:10) ``` ```{r echo=FALSE, eval=FALSE} -small_table %>% test_col_vals_regex(vars(b), regex = ".-[a-z]{3}.*") +small_table %>% test_col_vals_regex(b, regex = ".-[a-z]{3}.*") ``` ```{r echo=FALSE, eval=FALSE} -small_table %>% test_col_exists(columns = "g") +small_table %>% test_col_exists(g) ``` ```{r echo=FALSE, eval=FALSE} small_table %>% test_col_vals_gt( - vars(z), value = vars(a), + z, value = vars(a), preconditions = ~ . %>% dplyr::mutate(z = c + e), threshold = 0.5 ) ``` diff --git a/vignettes/VALID-VI.Rmd b/vignettes/VALID-VI.Rmd index 52b7ac583..c12927d52 100644 --- a/vignettes/VALID-VI.Rmd +++ b/vignettes/VALID-VI.Rmd @@ -26,8 +26,8 @@ To start things off, here's an example that uses an expression that takes the `s ```{r validate = TRUE} small_table %>% - col_is_date("date") %>% - col_vals_in_set(vars(f), set = c("low", "mid")) + col_is_date(date) %>% + col_vals_in_set(f, set = c("low", "mid")) ``` Clicking the above `1 validation failed.` button will reveal that the *expression* failed validation because of a validation function failing within it. If you break it down, really one validation step in the chain passed (the first one) and one failed (the second). If there were additional validation steps that would otherwise pass, we'd still get the same result and output because the failing step ends execution. @@ -38,7 +38,7 @@ Because this workflow is meant to stop an expression from executing at the first ```{r validate = TRUE} col_is_date(small_table, "date") -col_vals_in_set(small_table, vars(f), set = c("low", "mid")) +col_vals_in_set(small_table, f, set = c("low", "mid")) ``` It still says that `1 validation failed.` (this workflow focuses on the negatives) but pressing the button reveals that the first one passed and the second failed. This is much clearer and we don't run the risk of not evaluating validations because a validation failed earlier in a pipeline. @@ -48,12 +48,12 @@ Here's an example where all validations in individual expressions pass, showing ```{r validate = TRUE} -col_is_date(small_table, "date") -col_is_posix(small_table, vars(date_time)) -col_vals_in_set(small_table, vars(f), set = c("low", "mid", "high")) -col_vals_lt(small_table, vars(a), value = 10) -col_vals_regex(small_table, vars(b), regex = "^[0-9]-[a-z]{3}-[0-9]{3}$") -col_vals_between(small_table, vars(d), left = 0, right = 10000) +col_is_date(small_table, date) +col_is_posix(small_table, date_time) +col_vals_in_set(small_table, f, set = c("low", "mid", "high")) +col_vals_lt(small_table, a, value = 10) +col_vals_regex(small_table, b, regex = "^[0-9]-[a-z]{3}-[0-9]{3}$") +col_vals_between(small_table, d, left = 0, right = 10000) ``` It's worth reminding at this point that failed validations do not stop execution of the R Markdown rendering. Otherwise you wouldn't see a document with any failing validations, and, you wouldn't know where those failed validations occurred. The expectation for this workflow is to add in the relevant validation expressions at key junctures and should any failures occur, one can fix the underlying issues until all (or enough) validations pass. @@ -92,11 +92,11 @@ create_agent( label = "VALID-I Example No. 2", actions = al ) %>% - col_is_posix(vars(date_time)) %>% - col_vals_in_set(vars(f), set = c("low", "mid")) %>% - col_vals_lt(vars(a), value = 7) %>% - col_vals_regex(vars(b), regex = "^[0-9]-[a-w]{3}-[2-9]{3}$") %>% - col_vals_between(vars(d), left = 0, right = 4000) %>% + col_is_posix(date_time) %>% + col_vals_in_set(f, set = c("low", "mid")) %>% + col_vals_lt(a, value = 7) %>% + col_vals_regex(b, regex = "^[0-9]-[a-w]{3}-[2-9]{3}$") %>% + col_vals_between(d, left = 0, right = 4000) %>% interrogate() ```