{"id":32205867,"url":"https://github.com/ptfonseca/inspector","last_synced_at":"2026-02-21T03:32:29.687Z","repository":{"id":56934829,"uuid":"287588808","full_name":"ptfonseca/inspector","owner":"ptfonseca","description":"inspector: Validation of arguments and objects in user-defined functions","archived":false,"fork":false,"pushed_at":"2021-06-19T16:20:37.000Z","size":941,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-12-09T19:32:34.461Z","etag":null,"topics":["input-validation","r","r-package","statistics","validation","validations"],"latest_commit_sha":null,"homepage":"https://ptfonseca.github.io/inspector/","language":"R","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ptfonseca.png","metadata":{"files":{"readme":"README.Rmd","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-08-14T17:31:34.000Z","updated_at":"2021-06-19T16:17:07.000Z","dependencies_parsed_at":"2022-08-21T00:40:32.960Z","dependency_job_id":null,"html_url":"https://github.com/ptfonseca/inspector","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/ptfonseca/inspector","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ptfonseca%2Finspector","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ptfonseca%2Finspector/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ptfonseca%2Finspector/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ptfonseca%2Finspector/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ptfonseca","download_url":"https://codeload.github.com/ptfonseca/inspector/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ptfonseca%2Finspector/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29672704,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-21T03:11:15.450Z","status":"ssl_error","status_checked_at":"2026-02-21T03:10:34.920Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["input-validation","r","r-package","statistics","validation","validations"],"created_at":"2025-10-22T05:01:32.401Z","updated_at":"2026-02-21T03:32:29.679Z","avatar_url":"https://github.com/ptfonseca.png","language":"R","funding_links":[],"categories":[],"sub_categories":[],"readme":"---\noutput: github_document\nbibliography: inst/REFERENCES.bib\n---\n\n\u003c!-- README.md is generated from README.Rmd. Please edit that file --\u003e\n\n```{r, include = FALSE}\nknitr::opts_chunk$set(\n  collapse = TRUE,\n  comment = \"#\u003e\",\n  fig.path = \"man/figures/README-\",\n  out.width = \"100%\"\n)\n\nlibrary(inspector)\n```\n\n# inspector: Validation of Arguments and Objects in User-Defined Functions\n\n\u003c!-- badges: start --\u003e\n[![CRAN\nstatus](https://www.r-pkg.org/badges/version/inspector)](https://CRAN.R-project.org/package=inspector)\n[![Build Status](https://travis-ci.com/ptfonseca/inspector.svg?branch=master)](https://travis-ci.com/ptfonseca/inspector)\n[![R build status](https://github.com/ptfonseca/inspector/workflows/R-CMD-check/badge.svg)](https://github.com/ptfonseca/inspector/actions)\n![pkgdown](https://github.com/ptfonseca/inspector/workflows/pkgdown/badge.svg)\n[![codecov](https://codecov.io/gh/ptfonseca/inspector/branch/master/graph/badge.svg?token=08DXY4X1CR)](https://codecov.io/gh/ptfonseca/inspector)\n[![License: MIT](https://img.shields.io/badge/License-MIT-brightgreen.svg)](https://opensource.org/licenses/MIT)\n\u003c!-- badges: end --\u003e\n\n## Overview\n\nThe `inspector` package provides utility functions that implement and automate common sets of validation tasks, namely:\n\n  - `inspect_prob()` checks if an object is a numeric vector of valid probability values.\n  \n  - `inspect_log_base()` checks if an object is a valid logarithmic base.\n\n  - `inspect_true_or_false()` checks if an object is a non-missing logical value. \n\n  - `inspect_bfactor()` checks if an object is a numeric vector of valid Bayes factors values.\n  \n  - `inspect_bfactor_log()` checks if an object is a numeric vector of valid logarithmic Bayes factors values. \n  \n  - `inspect_bfactor_scale()` validates Bayes factor interpretation scales (from the [`pcal`](https://ptfonseca.github.io/pcal/) package).\n\n  - `inspect_categories()` validates factor levels.\n  \n  - `inspect_character()` validates character vectors.\n  \n  - `inspect_character_match()` validates character values with predefined allowed values.\n  \n  - `inspect_data_dichotomous()` validates dichotomous data\n\n  - `inspect_data_categorical()` and `inspect_data_cat_as_dichotom()` validate categorical data.\n\n  - `inspect_par_bernoulli()` validates parameters for the Bernoulli and Binomial distributions.\n  \n  - `inspect_par_multinomial()` validates parameters for the Multinomial distribution.\n  \n  - `inspect_par_beta()` validates parameters for the Beta distribution.\n\n  - `inspect_par_dirichlet()` validates parameters for the Dirichlet distribution.\n\n  - `inspect_par_haldane()` validates parameters for the Haldane distribution.\n  \nThese functions are particularly useful to validate inputs, intermediate objects and output values in user-defined functions, resulting in tidier and less verbose functions.\n  \n## Installation\n\nThe development version of `inspector` can be installed from\nGithub with the [`devtools`](https://devtools.r-lib.org) package:\n\n```{r, eval=FALSE}\n# install.packages(\"devtools\")\ndevtools::install_github(\"ptfonseca/inspector\")\n```\n\n## Usage\n\nImagine we want to write a function that simulates `n` flips of the same coin. Assuming that `bias` is the probability of the \"heads\" outcome:\n\n```{r}\n\nset.seed(123)\n\nflip_coins \u003c- function(n, bias) { \n  \n  sample(x = c(\"heads\", \"tails\"), size = n, replace = TRUE)\n}\n\nflip_coins(n = 5, bias = 0.5)\n```\n\nSince `bias` is a probability, it is natural that we require `flip_coins()`\nto only accept values of `bias` between 0 and 1. Furthermore, we may want to ensure that `bias` is not null, not missing, and is a numeric vector of length 1. This results an a quite verbose function body:\n\n```{r}\n\nset.seed(123)\n\nflip_coins \u003c- function(n, bias) {\n  \n  if (is.null(bias)) {\n    stop(paste(\"Invalid argument: bias is NULL.\"))\n  }\n  if (any(isFALSE(is.atomic(bias)), isFALSE(is.vector(bias)))) {\n    stop(paste(\"Invalid argument: bias must be an atomic vector.\"))\n  }\n  if (isFALSE(length(bias) == 1)) {\n    stop(paste(\"Invalid argument: bias must be of length 1.\"))\n  }\n  if (is.na(bias)) {\n    stop(paste(\"Invalid argument: bias is NA or NaN.\"))\n  }\n  if (isFALSE(is.numeric(bias))) {\n    stop(paste(\"Invalid argument: bias must be numeric.\"))\n  }\n  if (any(bias \u003e= 1, bias \u003c= 0)) {\n    stop(paste(\"Invalid argument: bias must be in the (0, 1) interval.\"))\n  }\n  \n  sample(x = c(\"heads\", \"tails\"), size = n, replace = TRUE)\n}\n\nflip_coins(n = 5, bias = 0.5)\n```\n\nThe `inspector` package was built to automate this kind of validation task. In the `flip_coins()` example, to perform an equivalent validation of inputs we can use `inspect_par_bernoulli`, since `bias` is the parameter of a Bernoulli distribution:\n\n```{r}\n\nset.seed(123)\n\nflip_coins \u003c- function(n, bias) {\n  \n  inspect_par_bernoulli(bias)\n  \n  sample(x = c(\"heads\", \"tails\"), size = n, replace = TRUE)\n}\n\nflip_coins(n = 5, bias = 0.5)\n```\n\nThis results in a tidier function body since the validation of `bias` is abstracted away from the body of the function.\n\nNow imagine we want to implement equation 4 from @bergerDelampady1987, a formula that calculates posterior probabilities using prior probabilities and Bayes factors as input. In this case we need to validate a vector of Bayes factors, lets call it `bf`, and a vector of prior probabilities, lets call it `prior_prob`. Since `bf` is expected to contain valid Bayes factor values, we need to ensure that only non-empty numeric vectors, containing only non-negative values, are accepted. Since `prior_prob` is a vector of probabilities, we need to check if it is a non-empty numeric vector containing only values between 0 and 1. Since we are now validating two inputs, the function body would be even more verbose than in the `flip_coins()` example:\n\n```{r}\nbfactor_to_prob \u003c- function(bf, prior_prob = .5) {\n\n  if (is.null(bf)) {\n    stop(paste(\"Invalid argument: bf is NULL.\"))\n  }\n  if (any(isFALSE(is.atomic(bf)), isFALSE(is.vector(bf)))) {\n    stop(paste(\"Invalid argument: bf must be an atomic vector.\"))\n  }\n  if (length(bf) == 0) {\n    stop(paste(\"Invalid argument: bf is empty.\"))\n  }\n  if (all(is.na(bf))) {\n    stop(paste(\"Invalid argument: all elements of bf are NA or NaN.\"))\n  }\n  if (isFALSE(is.numeric(bf))) {\n    stop(paste(\"Invalid argument: the type of bf must be numeric.\"))\n  }\n  if (any(bf[!is.na(bf)] \u003c 0)) {\n    stop(paste(\"Invalid argument: all elements of bf must be non-negative.\"))\n  }\n  if (is.null(prior_prob)) {\n    stop(paste(\"Invalid argument:\", output_name, \"is NULL.\"))\n  }\n  if (any(isFALSE(is.atomic(prior_prob)), isFALSE(is.vector(prior_prob)))) {\n    stop(paste(\"Invalid argument:\", output_name, \"must be an atomic vector.\"))\n  }\n  if (length(prior_prob) == 0) {\n    stop(paste(\"Invalid argument:\", output_name, \"is empty.\"))\n  }\n  if (all(is.na(prior_prob))) {\n    stop(paste(\"Invalid argument: all elements of\", output_name, \"are NA or NaN.\"))\n  }\n  if (isFALSE(is.numeric(prior_prob))) {\n    stop(paste(\"Invalid argument: the type of\", output_name, \"must be numeric.\"))\n  }\n  if (any(prior_prob[!is.na(prior_prob)] \u003c 0, prior_prob[!is.na(prior_prob)] \u003e 1)) {\n    stop(paste(\"Invalid argument: all elements of\",  output_name, \"must be in the [0, 1] interval.\"))\n  }\n\n  (1 + (1 - prior_prob) / prior_prob * (1 / bf)) ^(-1)\n}\n\nbfactor_to_prob(c(2.1, 0.5, 11))\n\n```\n\nNow lets use `inspector` instead. To perform an equivalent validation of inputs we can use `inspect_bfactor()` to validate `bf` and `inspect_prob()` to validate `prior_prob`:\n\n```{r}\nbfactor_to_prob \u003c- function(bf, prior_prob = .5) {\n\n  inspect_bfactor(bf)\n  inspect_prob(prior_prob)\n\n  (1 + (1 - prior_prob) / prior_prob * (1 / bf)) ^ (-1)\n}\n\nbfactor_to_prob(c(2.1, 0.5, 11))\n```\n\n## Getting Help\n\nIf you find a bug, please file an issue with a minimal reproducible\nexample on [GitHub](https://github.com/ptfonseca/inspector/issues).\nFeature requests are also welcome. You can find me at\n\u003cptfonseca@iseg.ulisboa.pt\u003e.\n\n## References\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fptfonseca%2Finspector","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fptfonseca%2Finspector","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fptfonseca%2Finspector/lists"}