library(citeme)The citeme package provides functions for interactive user input and validation of common data types used in citation metadata. These functions ensure data quality by validating user input against established formats and standards.
The ask_yes_no() function provides a simple interface for yes/no questions with validation.
library(citeme)# Ask a yes/no question with default answer
answer <- ask_yes_no("Do you want to continue?", default = TRUE)
# Custom prompts
answer <- ask_yes_no(
"Overwrite existing file?",
default = FALSE,
prompts = c("Yes", "No", "Cancel")
)The function:
utils::askYesNo() with additional validationThe ask_orcid() function prompts for an ORCID iD, a unique persistent identifier for researchers.
# Ask for an ORCID iD
orcid <- ask_orcid()
# Custom prompt
orcid <- ask_orcid(prompt = "Enter your ORCID: ")
# Empty strings are allowed (optional ORCID)
# Valid format: 0000-0000-0000-0000 (last digit can be X)The function:
validate_orcid()The ask_ror() function prompts for a ROR identifier, which uniquely identifies research organisations.
# Ask for a ROR identifier
ror <- ask_ror()
# Valid format: https://ror.org/0abcd1234The function:
validate_ror()https://ror.org/The ask_email() function prompts for an email address with format validation.
# Ask for an email address
email <- ask_email()
# Custom prompt
email <- ask_email(prompt = "Contact email: ")The function:
validate_email()The ask_url() function prompts for a URL with validation.
# Ask for a URL
url <- ask_url("Please enter the website URL: ")
# The URL must start with http:// or https://The function:
validate_url()http:// or https:// prefixThe ask_language() function prompts for a language code following the BCP 47 standard.
# Ask for a language code
# The list of options is based on the languages used in the `org_list` object
# The user can add another language code if needed
lang <- ask_language(org = inbo_org_list())The function:
validate_language()"en-GB", "nl-BE", "fr-FR"The ask_new_license() function helps select or add a license for a project.
# Interactive license selection
org <- inbo_org_list()
license <- ask_new_license(org$get_listed_licenses)
# The function:
# 1. Lists available licenses
# 2. Allows selection or addition of new license
# 3. Validates the selectionThe menu_first() function provides an interactive menu with the first option as default. When used in a non-interactive session, it returns the index of the first option.
# Create a menu
choices <- c("Option A", "Option B", "Option C")
selection <- menu_first(choices, title = "Select an option:")
# Returns the index of the selected option
# The first option is highlighted as defaultAll validation functions return logical vectors indicating whether each element passes validation. They are designed to work with vectors, making them suitable for batch validation.
The validate_orcid() function checks both format and checksum of ORCID identifiers.
# Validate ORCID identifiers
orcids <- c(
"0000-0001-2345-6789",
"0000-0002-3456-789X",
"invalid-orcid",
""
)
validate_orcid(orcids)[1] TRUE FALSE FALSE TRUE
The function:
0000-0000-0000-0000 (last digit can be X)The validate_ror() function checks ROR identifier format and checksum.
# Validate ROR identifiers
validate_ror("02catss52")[1] TRUE
validate_ror("https://ror.org/02catss52")[1] FALSE
validate_ror("not-a-ror")[1] FALSE
The function:
The validate_email() function checks email address format.
# Validate email addresses
emails <- c(
"[email protected]",
"[email protected]",
"invalid.email",
"@example.com"
)
validate_email(emails)[1] TRUE TRUE FALSE FALSE
# Returns logical vector indicating validityThe function:
The validate_url() function checks URL format.
# Validate URLs
validate_url("https://example.com")[1] TRUE
validate_url("http://subdomain.example.org/path")[1] TRUE
validate_url("ftp://example.com") # Invalid (ftp not allowed)[1] FALSE
validate_url("not-a-url")[1] FALSE
The function:
http:// or https:// prefixThe validate_language() function checks language codes against BCP 47 standard.
# Validate language codes
validate_language("en-GB")[1] "en-GB"
validate_language("nl-BE")[1] "nl-BE"
validate_language("en")Error:
! `language` must be in xx-YY format. e.g. 'en-GB', 'nl-BE'
validate_language("invalid")Error:
! `language` must be in xx-YY format. e.g. 'en-GB', 'nl-BE'
# Returns logical vector indicating validityThe function:
The validation functions are automatically used by the interactive input functions to ensure data quality. You can also use them independently for batch validation or custom workflows.
# Batch validate ORCIDs from a data frame
contributors$valid_orcid <- validate_orcid(contributors$orcid)
# Filter to valid entries
valid_contributors <- contributors[contributors$valid_orcid, ]
# Batch validate emails
valid_emails <- contributors$email[validate_email(contributors$email)]All interactive input functions (ask_*) have sensible behaviour in non-interactive sessions:
ask_yes_no() returns the default valueask_* functions require pre-validated input or will failThis allows you to use these functions in scripts and automated workflows:
# In a non-interactive script
if (interactive()) {
email <- ask_email()
} else {
email <- Sys.getenv("USER_EMAIL")
stopifnot(validate_email(email))
}The validation functions provide clear feedback when validation fails:
# Invalid ORCID will trigger warning and re-prompt
orcid <- ask_orcid()
# User enters: "1234-5678"
# Warning: Please provide a valid ORCiD in the format `0000-0000-0000-0000`
# Invalid email will trigger warning and re-prompt
email <- ask_email()
# User enters: "not-an-email"
# Warning: Please provide a valid email addressUse validation functions early: Validate input as soon as possible to provide immediate feedback.
Batch validation: Use validation functions on vectors for efficient data cleaning.
Clear prompts: Provide informative prompts that explain the expected format.
Handle optional fields: Use empty string checks for optional identifiers like ORCID.
Non-interactive fallbacks: Always provide fallbacks for non-interactive sessions.
Combine validators: Use multiple validation functions for complex data requirements.
# Pattern: Validate before storing
if (interactive()) {
email <- ask_email()
} else {
email <- config$email
}
stopifnot("Invalid email" = validate_email(email))# Pattern: Clean and filter data frame
data$valid_orcid <- validate_orcid(data$orcid)
data$valid_email <- validate_email(data$email)
clean_data <- data[data$valid_orcid & data$valid_email, ]# Pattern: Handle optional ORCID
orcid <- ask_orcid() # Empty string is valid
if (orcid != "") {
# Use ORCID
person_comment <- c(ORCID = orcid)
}# Pattern: Validate and report issues
contributors <- read.csv("contributors.csv")
invalid_emails <- contributors$email[!validate_email(contributors$email)]
if (length(invalid_emails) > 0) {
warning(
"Invalid emails found:\n",
paste(invalid_emails, collapse = "\n")
)
}For information about managing individual contributor information, see vignette("individuals"). For organisation-level configuration, see vignette("organisations").