Skip to content

Commit

Permalink
add options
Browse files Browse the repository at this point in the history
  • Loading branch information
strengejacke committed Nov 24, 2024
1 parent 4c34433 commit 01a4736
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 14 deletions.
58 changes: 50 additions & 8 deletions R/data_rename.R
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,24 @@
#' in `pattern`. `pattern` and `replacement` must be of the same length.
#' - `NULL`, in which case columns are numbered in sequential order.
#' - A string (i.e. character vector of length 1) with a "glue" styled pattern.
#' Currently supported tokens are `{col}` (or `{name}`) and `{n}`. `{col}`
#' will be replaced by the column name, i.e. the corresponding value in
#' `pattern`. `{n}` will be replaced by the number of the variable that is
#' replaced. For instance,
#' Currently supported tokens are:
#' - `{col}` (or `{name}`), which will be replaced by the column name, i.e.
#' the corresponding value in `pattern`.
#' - `{n}` will be replaced by the number of the variable that is replaced.
#' - `{letter}` will be replaced by alphabetical letters in sequential order.
#' - Finally, the name of a user-defined object that is available in the
#' environment can be used. In this case,
#'
#' An example for the use of tokens is...
#' ```r
#' data_rename(
#' mtcars,
#' pattern = c("am", "vs"),
#' replacement = "new_name_from_{col}"
#' )
#' ```
#' would returns new column names `new_name_from_am` and `new_name_from_vs`.
#' See 'Examples'.
#' ... which would return new column names `new_name_from_am` and
#' `new_name_from_vs`. See 'Examples'.
#'
#' If `pattern` is a named vector, `replacement` is ignored.
#' @param rows Vector of row names.
Expand Down Expand Up @@ -66,6 +71,11 @@
#' # Use glue-styled patterns
#' head(data_rename(mtcars[1:3], c("mpg", "cyl", "disp"), "formerly_{col}"))
#' head(data_rename(mtcars[1:3], c("mpg", "cyl", "disp"), "{col}_is_column_{n}"))
#' head(data_rename(mtcars[1:3], c("mpg", "cyl", "disp"), "new_{letter}"))
#'
#' # User-defined glue-styled patterns from objects in environment
#' x <- c("hi", "there", "!")
#' head(data_rename(mtcars[1:3], c("mpg", "cyl", "disp"), "col_{x}"))
#' @seealso
#' - Functions to rename stuff: [data_rename()], [data_rename_rows()],
#' [data_addprefix()], [data_addsuffix()]
Expand Down Expand Up @@ -212,7 +222,7 @@ data_rename <- function(data,
# prepare pattern
column_name <- pattern[i]
out[i] <- replacement
# replace first accepted token
# replace first pre-defined token
out[i] <- gsub(
"(.*)(\\{col\\})(.*)",
replacement = paste0("\\1", column_name, "\\3"),
Expand All @@ -224,12 +234,44 @@ data_rename <- function(data,
replacement = paste0("\\1", column_name, "\\3"),
x = out[i]
)
# replace second accepted token
# replace second pre-defined token
out[i] <- gsub(
"(.*)(\\{n\\})(.*)",
replacement = paste0("\\1", i, "\\3"),
x = out[i]
)
# replace third pre-defined token
out[i] <- gsub(
"(.*)(\\{letter\\})(.*)",
replacement = paste0("\\1", letters[i], "\\3"),
x = out[i]
)
# extract all non-standard tokens
matches <- unlist(
regmatches(out[i], gregexpr("\\{([^}]*)\\}", out[i])),
use.names = FALSE
)
# do we have any additional tokens, i.e. variable names from the environment?
# users can also specify variable names, where the
if (length(matches)) {
# if so, iterate all tokens
for (token in matches) {
# evaluate token-object from the environment
values <- .dynEval(str2lang(gsub("\\{(.*)\\}", "\\1", token)))
# check for correct length
if (length(values) != length(pattern)) {
insight::format_error(paste0(
"The number of values provided in `", token, "` (", length(values),
" values) do not match the number of the columns to rename (",
length(pattern), " columns)."
))
}
# replace token with values from the object
if (!is.null(values) && length(values)) {
out[i] <- gsub(token, values[i], out[i], fixed = TRUE)
}
}
}
}
out
}
Expand Down
24 changes: 18 additions & 6 deletions man/data_rename.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions tests/testthat/test-data_rename.R
Original file line number Diff line number Diff line change
Expand Up @@ -150,4 +150,21 @@ test_that("data_rename glue-style", {
expect_named(out, c("formerly_mpg", "formerly_cyl", "formerly_disp"))
out <- data_rename(mtcars[1:3], c("mpg", "cyl", "disp"), "{col}_is_column_{n}")
expect_named(out, c("mpg_is_column_1", "cyl_is_column_2", "disp_is_column_3"))
out <- data_rename(mtcars[1:3], c("mpg", "cyl", "disp"), "new_{letter}")
expect_named(out, c("new_a", "new_b", "new_c"))
})

skip_if_not_installed("withr")
withr::with_environment(
new.env(),
test_that("data_rename glue-style, environment", {
data(mtcars)
x <- c("hi", "there", "!")
out <- data_rename(mtcars[1:3], c("mpg", "cyl", "disp"), "col_{x}")
expect_named(out, c("col_hi", "col_there", "col_!"))
expect_error(
data_rename(mtcars[1:3], c("mpg", "disp"), "col_{x}"),
regex = "The number of values"
)
})
)

0 comments on commit 01a4736

Please sign in to comment.