Skip to content

Commit

Permalink
Merge pull request #16 from poissonconsulting/str_replace_when
Browse files Browse the repository at this point in the history
Str replace when function
  • Loading branch information
aylapear authored Aug 1, 2024
2 parents 9245dae + 821931f commit a095b41
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 0 deletions.
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export(only)
export(replace_na_if)
export(str_crush)
export(str_detect2)
export(str_replace_vec)
export(str_to_snake_case)
export(summarise2)
export(summarize2)
Expand Down
34 changes: 34 additions & 0 deletions R/str-replace_vec.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#' String replace multiple strings
#'
#' String replace multiple strings in a vector.
#'
#' `str_replace_vec()` is a vectorized form of [`stringr::str_replace()`].
#'
#' This is different from passing a named vector to [`stringr::str_replace_all`],
#' which performs multiple replacements but to all pattern matches in a string.
#'
#' @param replace A character vector where the names are the patterns to look
#' for and the values are the replacement values (c(pattern1 = replacement1))
#' @inherit stringr::str_replace
#' @seealso [`stringr::str_replace()`] and [`stringr::str_replace_all()`]
#' @export
#' @examples
#' fruits <- c("two apples", "nine pears")
#' str_replace_vec(fruits, c("two" = "three", "nine" = "ten"))

str_replace_vec <- function(string, replace) {
chk_character(string)
chk_character(replace)
chk_named(replace)

if(!length(replace)) return(string)

pattern <- names(replace)

n <- length(replace)

for(i in seq_len(n)) {
string <- stringr::str_replace(string, pattern = pattern[i], replacement = replace[i])
}
string
}
35 changes: 35 additions & 0 deletions man/str_replace_vec.Rd

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

61 changes: 61 additions & 0 deletions tests/testthat/test-str-replace-vec.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
test_that("str_replace_vec works with mutate", {
data <- tibble::tibble(
x = c("one", "two", "three", "four"),
y = c("one apple", "two bananas", "three pear", "four oranges"))

data <- dplyr::mutate(data,
x2 = str_replace_vec(x, c("one" = "1",
"two" = "2",
"three" = "3",
"four" = "4")))

expect_identical(data$x2, c("1", "2", "3", "4"))
expect_identical(data$y, c("one apple", "two bananas", "three pear", "four oranges"))
})

test_that("str_replace_vec with regex", {
x <- c("REP_1", "REP1-2", "MR REP 2")

x2 <- str_replace_vec(x, c("(?<!(\\d|\\s))[:punct:]" = "-", # punctuation not preceded by a digit or space
"(?<=REP)\\s" = "-", # a space precded by REP
"REP(?=\\d)" = "REP-", # REP followed by a digit
"^[:alpha:]+\\s(?=REP)" = "")) # Letters with space at start of string followed by REP

expect_identical(x2, c("REP-1", "REP-1-2", "REP-2"))
})

test_that("str_replace_vec with non character strings", {
x <- c("one", "two", "three", "four", "five")

x2 <- str_replace_vec(x, c("one" = NULL,
"two.*" = NA_character_,
"three" = TRUE,
"four" = character(0),
"five" = 5L))

expect_identical(x2, c("one", NA_character_, "TRUE", "four", 5L))
expect_type(x2, "character")
})

test_that("str_replace_vec with x no length", {
x <- c(character(0))
expect_length(x, 0)
x2 <- str_replace_vec(x, c("one" = "1"))

expect_identical(x2, character(0))

x <- c()
expect_length(x, 0)
replace <- c("one" = "1")

expect_error(str_replace_vec(x, replace))
})

test_that("str_replace_vec with replace no length", {
x <- c("one", "two", "three", "four")
replace <- c()
expect_error(str_replace_vec(x, replace))

replace <- c(character(0))
expect_error(str_replace_vec(x, replace))
})

0 comments on commit a095b41

Please sign in to comment.