Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main' into issue1109
Browse files Browse the repository at this point in the history
  • Loading branch information
KimLopezGuell committed Aug 15, 2024
2 parents dca8b2b + d022c4e commit 1112106
Show file tree
Hide file tree
Showing 18 changed files with 73 additions and 35 deletions.
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export(imap_dfr)
export(imap_int)
export(imap_lgl)
export(imap_raw)
export(imap_vec)
export(imodify)
export(insistently)
export(invoke)
Expand Down
10 changes: 7 additions & 3 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# purrr (development version)

* Added `imap_vec()` (#1084)
* `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 Expand Up @@ -744,7 +748,7 @@ accessor(x[[1]])$foo
to the equivalent pluck:
```
x %>% pluck(1, accessor, "foo")
x |> pluck(1, accessor, "foo")
```
Expand Down Expand Up @@ -968,7 +972,7 @@ This is a compatibility release with dplyr 0.6.0.

* `set_names()` is a snake-case alternative to `setNames()` with stricter
equality checking, and more convenient defaults for pipes:
`x %>% set_names()` is equivalent to `setNames(x, x)` (#119).
`x |> set_names()` is equivalent to `setNames(x, x)` (#119).


## Row based functionals
Expand All @@ -980,7 +984,7 @@ functions.
* `map()` now always returns a list. Data frame support has been moved
to `map_df()` and `dmap()`. The latter supports sliced data frames
as a shortcut for the combination of `by_slice()` and `dmap()`:
`x %>% by_slice(dmap, fun, .collate = "rows")`. The conditional
`x |> by_slice(dmap, fun, .collate = "rows")`. The conditional
variants `dmap_at()` and `dmap_if()` also support sliced data frames
and will recycle scalar results to the slice size.

Expand Down
2 changes: 1 addition & 1 deletion R/deprec-when.R
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
#'
#' @keywords internal
#' @examples
#' 1:10 %>%
#' 1:10 |>
#' when(
#' sum(.) <= 50 ~ sum(.),
#' sum(.) <= 100 ~ sum(.)/2,
Expand Down
7 changes: 7 additions & 0 deletions R/imap.R
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@ imap_dbl <- function(.x, .f, ...) {
map2_dbl(.x, vec_index(.x), .f, ...)
}

#' @rdname imap
#' @export
imap_vec <- function(.x, .f, ...) {
.f <- as_mapper(.f, ...)
map2_vec(.x, vec_index(.x), .f, ...)
}


#' @export
#' @rdname imap
Expand Down
8 changes: 4 additions & 4 deletions R/keep.R
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,12 @@ compact <- function(.x, .p = identity) {
#' @export
#' @examples
#' x <- c(a = 1, b = 2, cat = 10, dog = 15, elephant = 5, e = 10)
#' x %>% keep_at(letters)
#' x %>% discard_at(letters)
#' x |> keep_at(letters)
#' x |> discard_at(letters)
#'
#' # Can also use a function
#' x %>% keep_at(~ nchar(.x) == 3)
#' x %>% discard_at(~ nchar(.x) == 3)
#' x |> keep_at(~ nchar(.x) == 3)
#' x |> discard_at(~ nchar(.x) == 3)
keep_at <- function(x, at) {
where <- where_at(x, at, user_env = caller_env())
x[where]
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 @@ -80,8 +80,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
2 changes: 1 addition & 1 deletion README.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ library(purrr)
mtcars |>
split(mtcars$cyl) |> # from base R
map(\(df) lm(mpg ~ wt, data = df)) |>
map(summary) %>%
map(summary) |>
map_dbl("r.squared")
```

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ library(purrr)
mtcars |>
split(mtcars$cyl) |> # from base R
map(\(df) lm(mpg ~ wt, data = df)) |>
map(summary) %>%
map(summary) |>
map_dbl("r.squared")
#> 4 6 8
#> 0.5086326 0.4645102 0.4229655
Expand Down
3 changes: 3 additions & 0 deletions man/imap.Rd

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

8 changes: 4 additions & 4 deletions man/keep_at.Rd

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

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.

2 changes: 1 addition & 1 deletion man/when.Rd

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

2 changes: 0 additions & 2 deletions purrr.Rproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,3 @@ BuildType: Package
PackageUseDevtools: Yes
PackageInstallArgs: --no-multiarch --with-keep.source
PackageRoxygenize: rd,collate,namespace

UseNativePipeOperator: Yes
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.

1 change: 1 addition & 0 deletions tests/testthat/test-imap.R
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ test_that("atomic vector imap works", {
expect_length(imap_chr(x, paste), 3)
expect_equal(imap_int(x, ~ .x + as.integer(.y)), x * 2)
expect_equal(imap_dbl(x, ~ .x + as.numeric(.y)), x * 2)
expect_equal(imap_vec(x, ~ .x + as.numeric(.y)), x * 2)
})

test_that("iwalk returns invisibly", {
Expand Down
15 changes: 10 additions & 5 deletions 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 @@ -131,8 +131,13 @@ test_that("validates inputs", {
})
})

test_that("works on data frames", {
expect_no_error(
list_transpose(mtcars)
)
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()
})
})

8 changes: 4 additions & 4 deletions vignettes/base.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -281,9 +281,9 @@ The pipe is particularly compelling when working with longer transformations.
For example, the following code splits `mtcars` up by `cyl`, fits a linear model, extracts the coefficients, and extracts the first one (the intercept).

```{r, eval = modern_r}
mtcars %>%
split(mtcars$cyl) %>%
map(\(df) lm(mpg ~ wt, data = df)) %>%
map(coef) %>%
mtcars |>
split(mtcars$cyl) |>
map(\(df) lm(mpg ~ wt, data = df))|>
map(coef) |>
map_dbl(1)
```
2 changes: 1 addition & 1 deletion vignettes/other-langs.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ purrr draws inspiration from many related tools:

However, the goal of purrr is not to try and simulate a purer functional programming language in R; we don't want to implement a second-class version of Haskell in R. The goal is to give you similar expressiveness to an FP language, while allowing you to write code that looks and works like R:

* Instead of point free (tacit) style, we use the pipe, `%>%`, to write code
* Instead of point free (tacit) style, we use the pipe, `|>`, to write code
that can be read from left to right.

* Instead of currying, we use `...` to pass in extra arguments.
Expand Down

0 comments on commit 1112106

Please sign in to comment.