Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save moodymudskipper/b41262109ef1065cb7c89c9bf351f8fd to your computer and use it in GitHub Desktop.
Save moodymudskipper/b41262109ef1065cb7c89c9bf351f8fd to your computer and use it in GitHub Desktop.
alternate syntax for functionals using tags
``` r
#################################################
# DEFINE TAGS / TAG ADVERBS USING PACKAGE {tag} #
#################################################
# remotes::install_github("moodymudskipper/tag")
mapping_impl <- tag::tag(
args = alist(.pmap =),
{
# setup
call <- match.call()
f <- call[[c(1,3)]]
args <- as.list(call[-1])
# prefix detection
is_prefixed <- function(x) {
is.call(x) &&
identical(x[[1]], quote(`!`)) &&
is.call(x[[2]]) &&
identical(x[[2]][[1]], quote(`?`))
}
prefixed_lgl <- sapply(args, is_prefixed)
# remove prefix from args
args[prefixed_lgl] <- lapply(args[prefixed_lgl], `[[`,c(2,2))
# build pmap call, feed prefixed args to the .l argument, and the rest to the `...`
list_call <- as.call(c(quote(list),args[prefixed_lgl]))
pmap_call <- as.call(c(.pmap, list_call, f, args[!prefixed_lgl]))
# run in appropriate environment
eval.parent(pmap_call)
})
# define tag adverbs, with aliases
mapping <- m <- mapping_impl(quote(purrr::pmap))
mapping_chr <- m_chr <- mapping_impl(quote(purrr::pmap_chr))
mapping_dbl <- m_dbl <- mapping_impl(quote(purrr::pmap_dbl))
mapping_dfr <- m_dfr <- mapping_impl(quote(purrr::pmap_dfr))
mapping_dfc <- m_dfc <- mapping_impl(quote(purrr::pmap_dfc))
mapping_int <- m_int <- mapping_impl(quote(purrr::pmap_int))
mapping_lgl <- m_lgl <- mapping_impl(quote(purrr::pmap_lgl))
mapping_raw <- m_raw <- mapping_impl(quote(purrr::pmap_raw))
############
# EXAMPLES #
############
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# use appropriate variant instead of map
mapping$sum(!? mtcars[1:3])
#> $mpg
#> [1] 642.9
#>
#> $cyl
#> [1] 198
#>
#> $disp
#> [1] 7383.1
mapping_dbl$sum(!? mtcars[1:3])
#> mpg cyl disp
#> 642.9 198.0 7383.1
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# no need to reposition arguments, just mark them, only marked arguments are vectorized
set.seed(1)
mapping$rnorm(4, !? 1:2)
#> [[1]]
#> [1] 0.3735462 1.1836433 0.1643714 2.5952808
#>
#> [[2]]
#> [1] 2.329508 1.179532 2.487429 2.738325
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# this unifies map and pmap and avoids nesting and visual confusion in mutate/transform calls
transform(
head(iris,2),
x = mapping_dbl$median(!?Sepal.Width, !?Sepal.Length, !?Petal.Width))
#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species x
#> 1 5.1 3.5 1.4 0.2 setosa 3.5
#> 2 4.9 3.0 1.4 0.2 setosa 3.0
```
<sup>Created on 2019-10-30 by the [reprex package](https://reprex.tidyverse.org) (v0.3.0)</sup>
@moodymudskipper
Copy link
Author

!~ might be better, as ~ already has the notion of "expanding", while ? means "question"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment