Skip to content

Commit 195159c

Browse files
committed
Add keep_names() to preserve names from string when suitable.
1 parent 32ee982 commit 195159c

File tree

2 files changed

+77
-0
lines changed

2 files changed

+77
-0
lines changed

R/utils.R

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,36 @@ tr_ <- function(...) {
3333
copy_names <- function(from, to) {
3434
set_names(to, names(from))
3535
}
36+
37+
#' Preserve names based on inputs
38+
#'
39+
#' Decides whether to propagate `names(string)` to `out` based on the
40+
#' relationship between `string` and `pattern`, then applies those names to
41+
#' the appropriate structure.
42+
#'
43+
#' Names are preserved when `pattern` is missing, has length 1, or has the
44+
#' same length as `string`. For matrix outputs, row names are set; for vector
45+
#' or list outputs, names are set.
46+
#'
47+
#' @param out The result to potentially name; a vector, list, or matrix.
48+
#' @param string The primary input character vector whose names may be copied.
49+
#' @param pattern Optional pattern input used to decide if names should be
50+
#' preserved.
51+
#' @return `out`, with `names(out)` or `rownames(out)` set from
52+
#' `names(string)` when appropriate.
53+
#' @keywords internal
54+
#' @noRd
55+
keep_names <- function(out, string, pattern = NULL) {
56+
nm <- names(string)
57+
if (is.null(nm)) return(out)
58+
59+
keep <- is.null(pattern) || length(pattern) == 1L || length(pattern) == length(string)
60+
if (!keep) return(out)
61+
62+
if (is.matrix(out)) {
63+
rownames(out) <- nm
64+
} else {
65+
names(out) <- nm
66+
}
67+
out
68+
}

tests/testthat/test-utils.R

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
test_that("keep_names preserves names when pattern is missing", {
2+
x <- c(A = "a", B = "b")
3+
4+
# vector output
5+
out_vec <- c("x", "y")
6+
res_vec <- keep_names(out_vec, x)
7+
expect_equal(names(res_vec), names(x))
8+
9+
# matrix output
10+
out_mat <- matrix(c("x", "y"), nrow = 2)
11+
res_mat <- keep_names(out_mat, x)
12+
expect_equal(rownames(res_mat), names(x))
13+
})
14+
15+
test_that("keep_names preserves names when pattern has length 1", {
16+
x <- c(A = "a", B = "b")
17+
pattern <- "p"
18+
19+
# vector output
20+
out_vec <- c("x", "y")
21+
res_vec <- keep_names(out_vec, x, pattern)
22+
expect_equal(names(res_vec), names(x))
23+
24+
# matrix output
25+
out_mat <- matrix(c("x", "y"), nrow = 2)
26+
res_mat <- keep_names(out_mat, x, pattern)
27+
expect_equal(rownames(res_mat), names(x))
28+
})
29+
30+
test_that("keep_names preserves names when pattern matches string length", {
31+
x <- c(A = "a", B = "b")
32+
pattern <- c("p1", "p2")
33+
34+
# vector output
35+
out_vec <- c("x", "y")
36+
res_vec <- keep_names(out_vec, x, pattern)
37+
expect_equal(names(res_vec), names(x))
38+
39+
# matrix output
40+
out_mat <- matrix(c("x", "y"), nrow = 2)
41+
res_mat <- keep_names(out_mat, x, pattern)
42+
expect_equal(rownames(res_mat), names(x))
43+
})
44+

0 commit comments

Comments
 (0)