Skip to content

Commit

Permalink
Rename all label functions and mentions to tag
Browse files Browse the repository at this point in the history
  • Loading branch information
chartgerink committed Jan 27, 2025
1 parent f934177 commit 67ca381
Show file tree
Hide file tree
Showing 68 changed files with 858 additions and 859 deletions.
476 changes: 238 additions & 238 deletions CITATION.cff

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
Package: safeframe
Title: Generic Data Labelling and Validating
Title: Generic Data Tagging and Validating
Version: 0.0.1
Authors@R: c(
person("Chris", "Hartgerink", , "[email protected]", role = c("cre", "aut"),
comment = c(ORCID = "0000-0003-1050-6809")),
person("Hugo", "Gruson", , "[email protected]", role = "rev",
comment = c(ORCID = "0000-0002-4094-1476"))
)
Description: Provides tools to help label and validate data according to user-specified rules. The 'safeframe' class adds variable level attributes to 'data.frame' columns. Once tagged, these variables can be seamlessly used in downstream analyses, making data pipelines clearer, more robust, and more reliable.
Description: Provides tools to help tag and validate data according to user-specified rules. The 'safeframe' class adds variable level attributes to 'data.frame' columns. Once tagged, these variables can be seamlessly used in downstream analyses, making data pipelines clearer, more robust, and more reliable.
License: MIT + file LICENSE
URL: https://epiverse-trace.github.io/safeframe/, https://github.com/epiverse-trace/safeframe
BugReports: https://github.com/epiverse-trace/safeframe/issues
Expand Down
14 changes: 7 additions & 7 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ S3method("[<-",safeframe)
S3method("[[<-",safeframe)
S3method("names<-",safeframe)
S3method(print,safeframe)
export(get_lost_labels_action)
export(has_label)
export(labels)
export(labels_df)
export(lost_labels_action)
export(get_lost_tags_action)
export(has_tag)
export(lost_tags_action)
export(make_safeframe)
export(set_labels)
export(set_tags)
export(tags)
export(tags_df)
export(type)
export(validate_labels)
export(validate_safeframe)
export(validate_tags)
export(validate_types)
importFrom(lifecycle,deprecated)
6 changes: 3 additions & 3 deletions R/drop_safeframe.R
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@
#'
#' @param x a `safeframe` object
#'
#' @param remove_labels a `logical` indicating if labels should be removed from
#' @param remove_tags a `logical` indicating if tags should be removed from
#' the attributes; defaults to `TRUE`
#'
#' @noRd
#'
#' @return The function returns the object without the `safeframe` class.
#'
drop_safeframe <- function(x, remove_labels = TRUE) {
drop_safeframe <- function(x, remove_tags = TRUE) {
classes <- class(x)
class(x) <- setdiff(classes, "safeframe")
if (remove_labels) {
if (remove_tags) {
# Set the label attribute to NULL for all variables in x
for (var in names(x)) {
attr(x[[var]], "label") <- NULL
Expand Down
16 changes: 8 additions & 8 deletions R/has_label.R → R/has_tag.R
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
#' A selector function to use in \pkg{tidyverse} functions
#'
#' @param labels A character vector of labels you want to operate on
#' @param tags A character vector of tags you want to operate on
#'
#' @returns A numeric vector containing the position of the columns with the
#' requested labels
#' requested tags
#'
#' @note Using this in a pipeline results in a 'safeframe' object, but does not
#' maintain the variable labels at this time. It is primarily useful to make
#' maintain the variable tags at this time. It is primarily useful to make
#' your pipelines human readable.
#'
#' @export
Expand All @@ -21,14 +21,14 @@
#'
#' if (require(dplyr) && require(magrittr)) {
#' x %>%
#' select(has_label(c("Miles per hour", "Distance in miles"))) %>%
#' select(has_tag(c("Miles per hour", "Distance in miles"))) %>%
#' head()
#' }
has_label <- function(labels) {
dat <- tidyselect::peek_data(fn = "has_label")
dat_labels <- labels(dat)
has_tag <- function(tags) {
dat <- tidyselect::peek_data(fn = "has_tag")
dat_tags <- tags(dat)

cols_to_extract <- dat_labels[dat_labels %in% labels]
cols_to_extract <- dat_tags[dat_tags %in% tags]

which(colnames(dat) %in% names(cols_to_extract))
}
20 changes: 10 additions & 10 deletions R/lost_labels.R → R/lost_tags.R
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
#' Check for lost labels and throw relevant warning or error
#' Check for lost tags and throw relevant warning or error
#'
#' This internal function checks for labels that are present in the old labels
#' but not in the new labels. If any labels are lost, it throws a warning or
#' This internal function checks for tags that are present in the old tags
#' but not in the new tags. If any tags are lost, it throws a warning or
#' error based on the specified action.
#'
#' @param old A named list of old labels.
#' @param new A named list of new labels.
#' @param old A named list of old tags.
#' @param new A named list of new tags.
#' @param lost_action A character string specifying the action to take when
#' labels are lost. Can be "none", "warning", or "error".
#' tags are lost. Can be "none", "warning", or "error".
#' @keywords internal
#' @return None. Throws a warning or error if labels are lost.
lost_labels <- function(old, new, lost_action) {
#' @return None. Throws a warning or error if tags are lost.
lost_tags <- function(old, new, lost_action) {
lost_vars <- setdiff(names(old), names(new))

if (lost_action != "none" && length(lost_vars) > 0) {
lost_labels <- lapply(lost_vars, function(label) old[[label]])
lost_tags <- lapply(lost_vars, function(tag) old[[tag]])

lost_msg <- vars_labels(lost_vars, lost_labels)
lost_msg <- vars_tags(lost_vars, lost_tags)
msg <- paste(
"The following tagged variables are lost:\n",
lost_msg
Expand Down
38 changes: 19 additions & 19 deletions R/lost_labels_action.R → R/lost_tags_action.R
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#' Check and set behaviour for lost labels
#' Check and set behaviour for lost tags
#'
#' This function determines the behaviour to adopt when tagged variables of a
#' `safeframe` are lost for example through subsetting. This is achieved using
Expand All @@ -19,39 +19,39 @@
#'
#' @export
#'
#' @rdname lost_labels_action
#' @rdname lost_tags_action
#'
#' @aliases lost_labels_action get_lost_labels_action
#' @aliases lost_tags_action get_lost_tags_action
#'
#' @examples
#' # reset default - done automatically at package loading
#' lost_labels_action()
#' lost_tags_action()
#'
#' # check current value
#' get_lost_labels_action()
#' get_lost_tags_action()
#'
#' # change to issue errors when tags are lost
#' lost_labels_action("error")
#' get_lost_labels_action()
#' lost_tags_action("error")
#' get_lost_tags_action()
#'
#' # change to ignore when tags are lost
#' lost_labels_action("none")
#' get_lost_labels_action()
#' lost_tags_action("none")
#' get_lost_tags_action()
#'
#' # reset to default: warning
#' lost_labels_action()
#' lost_tags_action()
#'
lost_labels_action <- function(action = c("warning", "error", "none"),
quiet = FALSE) {
lost_tags_action <- function(action = c("warning", "error", "none"),
quiet = FALSE) {
safeframe_options <- options("safeframe")$safeframe

action <- match.arg(action)
safeframe_options$lost_labels_action <- action
safeframe_options$lost_tags_action <- action
options(safeframe = safeframe_options)
if (!quiet) {
if (action == "warning") msg <- "Lost labels will now issue a warning."
if (action == "error") msg <- "Lost labels will now issue an error."
if (action == "none") msg <- "Lost labels will now be ignored."
if (action == "warning") msg <- "Lost tags will now issue a warning."
if (action == "error") msg <- "Lost tags will now issue an error."
if (action == "none") msg <- "Lost tags will now be ignored."
message(msg)
}
return(invisible(NULL))
Expand All @@ -61,8 +61,8 @@ lost_labels_action <- function(action = c("warning", "error", "none"),

#' @export
#'
#' @rdname lost_labels_action
#' @rdname lost_tags_action

get_lost_labels_action <- function() {
options("safeframe")$safeframe$lost_labels_action
get_lost_tags_action <- function() {
options("safeframe")$safeframe$lost_tags_action
}
24 changes: 12 additions & 12 deletions R/make_safeframe.R
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@
#' @param x a `data.frame` or a `tibble`
#'
#' @param ... <[`dynamic-dots`][rlang::dyn-dots]> A named list with variable
#' names in `x` as list names and the labels as list values. Values set to
#' `NULL` remove the label. When specifying labels, please also see
#' names in `x` as list names and the tags as list values. Values set to
#' `NULL` remove the tag When specifying tags, please also see
#' `default_values`.
#'
#' @seealso
#'
#' * An overview of the [safeframe] package
#' * [labels()]: for a list of tagged variables in a `safeframe`
#' * [set_labels()]: for modifying labels
#' * [labels_df()]: for selecting variables by labels
#' * [tags()]: for a list of tagged variables in a `safeframe`
#' * [set_tags()]: for modifying tags
#' * [tags_df()]: for selecting variables by tags
#'
#' @export
#'
Expand All @@ -33,15 +33,15 @@
#' ## print result - just first few entries
#' head(x)
#'
#' ## check labels
#' labels(x)
#' ## check tags
#' tags(x)
#'
#' ## Labels can also be passed as a list with the splice operator (!!!)
#' my_labels <- list(
#' ## tags can also be passed as a list with the splice operator (!!!)
#' my_tags <- list(
#' speed = "Miles per hour",
#' dist = "Distance in miles"
#' )
#' new_x <- make_safeframe(cars, !!!my_labels)
#' new_x <- make_safeframe(cars, !!!my_tags)
#'
#' ## The output is strictly equivalent to the previous one
#' identical(x, new_x)
Expand All @@ -52,8 +52,8 @@ make_safeframe <- function(x,
checkmate::assert_data_frame(x, min.cols = 1)
assert_not_data_table(x)

labels <- rlang::list2(...)
x <- label_variables(x, labels)
tags <- rlang::list2(...)
x <- tag_variables(x, tags)

# shape output and return object
class(x) <- c("safeframe", class(x))
Expand Down
10 changes: 5 additions & 5 deletions R/names.R
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@
#' x <- x %>%
#' rename(speed = "mph")
#' head(x)
#' labels(x)
#' tags(x)
#' }
`names<-.safeframe` <- function(x, value) {
# Strategy for renaming

# Since renaming cannot drop columns, we can update labels to match new
# Since renaming cannot drop columns, we can update tags to match new
# variable names. We do this by:

# 1. Storing old names and new names to have define replacement rules
Expand All @@ -57,9 +57,9 @@
}

# Step 2
out_labels <- labels(x, show_null = TRUE)
names(out_labels) <- new_names
out <- label_variables(out, out_labels)
out_tags <- tags(x, show_null = TRUE)
names(out_tags) <- new_names
out <- tag_variables(out, out_tags)
class(out) <- class(x)

out
Expand Down
14 changes: 7 additions & 7 deletions R/print.safeframe.R
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,17 @@ print.safeframe <- function(x, ...) {
cat("\n// safeframe object\n")
print(drop_safeframe(x))

# Extract names and values from labels(x)
label_values <- unlist(labels(x))
label_names <- names(label_values)
# Extract names and values from tags(x)
tag_values <- unlist(tags(x))
label_names <- names(tag_values)

# Construct the labels_txt string from the filtered pairs
labels_txt <- vars_labels(label_names, label_values)
# Construct the tags_txt string from the filtered pairs
tags_txt <- vars_tags(label_names, tag_values)

if (labels_txt == "") {
if (tags_txt == "") {
cat("\n[no tagged variables]\n")
} else {
cat("\ntagged variables:\n", labels_txt, "\n")
cat("\ntagged variables:\n", tags_txt, "\n")
}

invisible(x)
Expand Down
2 changes: 1 addition & 1 deletion R/remove_label.R → R/remove_tag.R
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#'
#' @noRd
#'
remove_label <- function(x, var) {
remove_tag <- function(x, var) {
attr(x[[var]], "label") <- NULL
x
}
34 changes: 17 additions & 17 deletions R/restore_labels.R → R/restore_tags.R
Original file line number Diff line number Diff line change
@@ -1,44 +1,44 @@
#' Restore labels of a safeframe
#' Restore tags of a safeframe
#'
#' Internal. This function is used to restore labels of a `safeframe` object
#' which may have lost its labels after handling for example through `dplyr`
#' Internal. This function is used to restore tags of a `safeframe` object
#' which may have lost its tags after handling for example through `dplyr`
#' verbs. Specific actions can be triggered when some of the tagged variables
#' have disappeared from the object.
#'
#' @param x a `data.frame`
#'
#' @param labels a list of labels as returned by [labels()]; if default values
#' are missing, they will be added to the new list of labels. Matches column
#' names with `x` to restore labels. Throws an error if no matches are found.
#' @param tags a list of tags as returned by [tags()]; if default values
#' are missing, they will be added to the new list of tags. Matches column
#' names with `x` to restore tags. Throws an error if no matches are found.
#'
#' @param lost_action a `character` indicating the behaviour to adopt when
#' tagged variables have been lost: "error" (default) will issue an error;
#' "warning" will issue a warning; "none" will do nothing
#'
#' @noRd
#'
#' @return The function returns a `safeframe` object with updated labels.
#' @return The function returns a `safeframe` object with updated tags.
#'

restore_labels <- function(x, newLabels,
lost_action = c("error", "warning", "none")) {
restore_tags <- function(x, newTags,
lost_action = c("error", "warning", "none")) {
# assertions
checkmate::assertClass(x, "data.frame")
checkmate::assertClass(newLabels, "list")
checkmate::assertClass(newTags, "list")
lost_action <- match.arg(lost_action)

# Match the remaining variables to the provided labels
common_vars <- intersect(names(x), names(newLabels))
# Match the remaining variables to the provided tags
common_vars <- intersect(names(x), names(newTags))
if (length(common_vars) == 0 && length(names(x)) > 0) {
stop("No matching labels provided.")
stop("No matching tags provided.")
}

lost_vars <- setdiff(names(newLabels), names(x))
lost_vars <- setdiff(names(newTags), names(x))

if (lost_action != "none" && length(lost_vars) > 0) {
lost_labels <- lapply(lost_vars, function(label) newLabels[[label]])
lost_tags <- lapply(lost_vars, function(tag) newTags[[tag]])

lost_msg <- vars_labels(lost_vars, lost_labels)
lost_msg <- vars_tags(lost_vars, lost_tags)
msg <- paste(
"The following tagged variables are lost:\n",
lost_msg
Expand All @@ -54,7 +54,7 @@ restore_labels <- function(x, newLabels,
}

for (name in common_vars) {
attr(x[[name]], "label") <- newLabels[[name]]
attr(x[[name]], "label") <- newTags[[name]]
}

# Ensure class consistency
Expand Down
Loading

0 comments on commit 67ca381

Please sign in to comment.