Skip to content

Commit

Permalink
fix: list_transpose() takes into account all elements for the templ…
Browse files Browse the repository at this point in the history
…ate (#1136)

Closes #1128.
  • Loading branch information
krlmlr authored Aug 15, 2024
1 parent 72a4dcf commit 770bbfe
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 9 deletions.
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# purrr (development version)

* `list_transpose()` inspects all elements to determine the correct
template if it's not provided by the user (#1128, @krlmlr).

# purrr 1.0.2

* Fixed valgrind issue.
Expand Down
21 changes: 16 additions & 5 deletions R/list-transpose.R
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
#' @param x A list of vectors to transpose.
#' @param template A "template" that describes the output list. Can either be
#' a character vector (where elements are extracted by name), or an integer
#' vector (where elements are extracted by position). Defaults to the names
#' of the first element of `x`, or if they're not present, the integer
#' indices.
#' vector (where elements are extracted by position). Defaults to the union
#' of the names of the elements of `x`, or if they're not present, the
#' union of the integer indices.
#' @param simplify Should the result be [simplified][list_simplify]?
#' * `TRUE`: simplify or die trying.
#' * `NA`: simplify if possible.
Expand Down Expand Up @@ -74,8 +74,19 @@ list_transpose <- function(x,

if (length(x) == 0) {
template <- integer()
} else {
template <- template %||% vec_index(x[[1]])
} else if (is.null(template)) {
indexes <- map(x, vec_index)
call <- current_env()
withCallingHandlers(
template <- reduce(indexes, vec_set_union),
vctrs_error_ptype2 = function(e) {
cli::cli_abort(
"Can't combine named and unnamed vectors.",
arg = template,
call = call
)
}
)
}

if (!is.character(template) && !is.numeric(template)) {
Expand Down
6 changes: 3 additions & 3 deletions man/list_transpose.Rd

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

8 changes: 8 additions & 0 deletions tests/testthat/_snaps/list-transpose.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,11 @@
Error in `list_transpose()`:
! `template` must be a character or numeric vector, not a function.

# fail mixing named and unnamed vectors

Code
test_list_transpose()
Condition
Error in `list_transpose()`:
! Can't combine named and unnamed vectors.

12 changes: 11 additions & 1 deletion tests/testthat/test-list-transpose.R
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ test_that("can use character template", {
# Default:
expect_equal(
list_transpose(x, default = NA),
list(a = c(1, NA), b = c(2, 3))
list(a = c(1, NA), b = c(2, 3), c = c(NA, 4))
)

# Change order
Expand Down Expand Up @@ -130,3 +130,13 @@ test_that("validates inputs", {
list_transpose(list(1), template = mean)
})
})

test_that("fail mixing named and unnamed vectors", {
test_list_transpose <- function() {
x <- list(list(a = 1, b = 2), list(a = 3, b = 4))
list_transpose(list(x = list(a = 1, b = 2), y = list(3, 4)))
}
expect_snapshot(error = TRUE, {
test_list_transpose()
})
})

0 comments on commit 770bbfe

Please sign in to comment.