lambda <- function(expr, args = ".i") {
fun <- function() { }
formals(fun) <- structure(
rep(list(substitute()), length(args)),
class = "alist",
names = args
)
if (is.function(expr)) {
body(fun) <- substitute({
expr()
})
} else {
expr <- as.formula(expr)[[2]]
body(fun) <- substitute({
expr
})
}
fun
}
lambda(function(x) x + 1)
#> function (.i)
#> {
#> (function(x) x + 1)()
#> }
#> <environment: 0x56d7fed1a638>
lambda(~.i + 1 + .j, args = c(".i", ".j"))
#> function (.i, .j)
#> {
#> .i + 1 + .j
#> }
#> <environment: 0x56d7fd436e10>
lambda(~.i + 1 + .j, args = c(".i", ".j"))(1, 2)
#> [1] 4
apply_lambda <- function(x, expr, fun, ...) {
force(fun)
..call <- sys.call(sys.parent())
withCallingHandlers(
set_names2(do.call(fun, c(list(x, expr), list(...))), names(x)),
error = function(e) {
e$call <- ..call
stop(e)
}
)
}
apply_each <- function(x, fun) {
lapply(x, function(.i) do.call(fun, as.list(.i)))
}
set_names <- fuj::set_names
set_names2 <- function(x, names = x) {
if (is.matrix(x)) {
dimnames(x) <- list(seq_len(NROW(x)), names)
} else {
names(x) <- names
}
x
}
each <- function(x, expr, args = ".i") {
apply_lambda(x, lambda(expr, args), apply_each)
}
each_ <- function(type) {
fun <- function(x, expr, args = ".i", n = 1L) { }
body(fun) <- substitute({
res <- apply_lambda(
x,
lambda(expr, args),
vapply,
FUN.VALUE = type(n),
USE.NAMES = FALSE
)
if (is.matrix(res)) {
apply(res, 2L, as.vector, simplify = FALSE)
} else {
res
}
})
fun
}
date <- function(n = 0L) {
rep(as.Date(0L), n)
}
datetime <- function(n = 0L) {
rep(as.POSIXct(0L), n)
}
each_int <- each_(integer)
each_dbl <- each_(double)
each_chr <- each_(character)
each_lgl <- each_(logical)
each_raw <- each_(raw)
each_dte <- function(x, expr, args = ".i", n = 1L) {
res <- each_dbl(x, expr, args, n)
res[] <- as.Date.numeric(res)
res
}
each_dtm <- function(x, expr, args = ".i", n = 1L) {
res <- each_dbl(x, expr, args, n)
res[] <- as.POSIXct.numeric(res)
res
}
each(state.name, ~nchar(.i) + 1)
#> [[1]]
#> [1] 8
#>
#> [[2]]
#> [1] 7
#>
#> [[3]]
#> [1] 8
#>
#> [[4]]
#> [1] 9
#>
#> [[5]]
#> [1] 11
#>
#> [[6]]
#> [1] 9
#>
#> [[7]]
#> [1] 12
#>
#> [[8]]
#> [1] 9
#>
#> [[9]]
#> [1] 8
#>
#> [[10]]
#> [1] 8
#>
#> [[11]]
#> [1] 7
#>
#> [[12]]
#> [1] 6
#>
#> [[13]]
#> [1] 9
#>
#> [[14]]
#> [1] 8
#>
#> [[15]]
#> [1] 5
#>
#> [[16]]
#> [1] 7
#>
#> [[17]]
#> [1] 9
#>
#> [[18]]
#> [1] 10
#>
#> [[19]]
#> [1] 6
#>
#> [[20]]
#> [1] 9
#>
#> [[21]]
#> [1] 14
#>
#> [[22]]
#> [1] 9
#>
#> [[23]]
#> [1] 10
#>
#> [[24]]
#> [1] 12
#>
#> [[25]]
#> [1] 9
#>
#> [[26]]
#> [1] 8
#>
#> [[27]]
#> [1] 9
#>
#> [[28]]
#> [1] 7
#>
#> [[29]]
#> [1] 14
#>
#> [[30]]
#> [1] 11
#>
#> [[31]]
#> [1] 11
#>
#> [[32]]
#> [1] 9
#>
#> [[33]]
#> [1] 15
#>
#> [[34]]
#> [1] 13
#>
#> [[35]]
#> [1] 5
#>
#> [[36]]
#> [1] 9
#>
#> [[37]]
#> [1] 7
#>
#> [[38]]
#> [1] 13
#>
#> [[39]]
#> [1] 13
#>
#> [[40]]
#> [1] 15
#>
#> [[41]]
#> [1] 13
#>
#> [[42]]
#> [1] 10
#>
#> [[43]]
#> [1] 6
#>
#> [[44]]
#> [1] 5
#>
#> [[45]]
#> [1] 8
#>
#> [[46]]
#> [1] 9
#>
#> [[47]]
#> [1] 11
#>
#> [[48]]
#> [1] 14
#>
#> [[49]]
#> [1] 10
#>
#> [[50]]
#> [1] 8
each(list(1:2, 2:3, 3:4), ~a^b, c("a", "b"))
#> [[1]]
#> [1] 1
#>
#> [[2]]
#> [1] 8
#>
#> [[3]]
#> [1] 81
each_int(state.name, ~nchar(.i))
#> [1] 7 6 7 8 10 8 11 8 7 7 6 5 8 7 4 6 8 9 5 8 13 8 9 11 8
#> [26] 7 8 6 13 10 10 8 14 12 4 8 6 12 12 14 12 9 5 4 7 8 10 13 9 7
try(each_int(state.name, ~nchar(.i) + 2.5))
#> Error in each_int(state.name, ~nchar(.i) + 2.5) :
#> values must be type 'integer',
#> but FUN(X[[1]]) result is type 'double'
try(each(1:3, ~.i + Sys.date()))
#> Error in each(1:3, ~.i + Sys.date()) : could not find function "Sys.date"
each(1:3, ~.i + Sys.Date())
#> [[1]]
#> [1] "2024-06-03"
#>
#> [[2]]
#> [1] "2024-06-04"
#>
#> [[3]]
#> [1] "2024-06-05"
1:3 |>
set_names(letters[1:3]) |>
each(~.i + 1)
#> $a
#> [1] 2
#>
#> $b
#> [1] 3
#>
#> $c
#> [1] 4
lambda(~.i + Sys.date())
#> function (.i)
#> {
#> .i + Sys.date()
#> }
#> <environment: 0x56d802825700>
try(each_dte(1:3, ~.i + Sys.date()))
#> Error in each_dbl(x, expr, args, n) : could not find function "Sys.date"
each_dte(1:3, ~.i + Sys.Date())
#> [1] 19877 19878 19879
1:3 |>
set_names() |>
each_dte(~.i + Sys.Date())
#> 1 2 3
#> 19877 19878 19879
bench::mark(
each(1:4, ~.i + 1),
purrr::map(1:4, ~.x + 1)
)
#> # A tibble: 2 × 6
#> expression min median `itr/sec` mem_alloc `gc/sec`
#> <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl>
#> 1 each(1:4, ~.i + 1) 55.8µs 64µs 13443. 0B 14.7
#> 2 purrr::map(1:4, ~.x + 1) 46.8µs 55.1µs 15846. 59.8KB 12.5
# doesn't work
bench::mark(
each(list(1:2, 2:3, 3:4), ~.i + .j, c(".i", ".j")),
try(purrr::pmap(list(1:2, 2:3, 3:4), ~.x + .y)),
try(purrr::pmap(list(1:2, 2:3, 3:4), ~..1 + ..2)),
check = FALSE
)
#> # A tibble: 3 × 6
#> expression min median `itr/sec` mem_alloc `gc/sec`
#> <bch:expr> <bch:t> <bch:t> <dbl> <bch:byt> <dbl>
#> 1 "each(list(1:2, 2:3, 3:4), ~.i +… 55.8µs 62.8µs 13805. 0B 14.7
#> 2 "try(purrr::pmap(list(1:2, 2:3, … 107.2µs 126.3µs 6975. 46.75KB 12.5
#> 3 "try(purrr::pmap(list(1:2, 2:3, … 115.1µs 127.2µs 6754. 6.11KB 14.8
bench::mark(
each_int(state.abb, ~nchar(.i) + 1L),
purrr::map_int(state.abb, ~nchar(.x) + 1L)
)
#> # A tibble: 2 × 6
#> expression min median `itr/sec` mem_alloc `gc/sec`
#> <bch:expr> <bch> <bch:> <dbl> <bch:byt> <dbl>
#> 1 each_int(state.abb, ~nchar(.i) + 1L) 122µs 132µs 6752. 3.09KB 19.0
#> 2 purrr::map_int(state.abb, ~nchar(.x… 107µs 120µs 6934. 100.48KB 16.9
state.name |>
set_names() |>
each_int(~c(nchar(.i), 1L), n = 2)
#> $Alabama
#> [1] 7 1
#>
#> $Alaska
#> [1] 6 1
#>
#> $Arizona
#> [1] 7 1
#>
#> $Arkansas
#> [1] 8 1
#>
#> $California
#> [1] 10 1
#>
#> $Colorado
#> [1] 8 1
#>
#> $Connecticut
#> [1] 11 1
#>
#> $Delaware
#> [1] 8 1
#>
#> $Florida
#> [1] 7 1
#>
#> $Georgia
#> [1] 7 1
#>
#> $Hawaii
#> [1] 6 1
#>
#> $Idaho
#> [1] 5 1
#>
#> $Illinois
#> [1] 8 1
#>
#> $Indiana
#> [1] 7 1
#>
#> $Iowa
#> [1] 4 1
#>
#> $Kansas
#> [1] 6 1
#>
#> $Kentucky
#> [1] 8 1
#>
#> $Louisiana
#> [1] 9 1
#>
#> $Maine
#> [1] 5 1
#>
#> $Maryland
#> [1] 8 1
#>
#> $Massachusetts
#> [1] 13 1
#>
#> $Michigan
#> [1] 8 1
#>
#> $Minnesota
#> [1] 9 1
#>
#> $Mississippi
#> [1] 11 1
#>
#> $Missouri
#> [1] 8 1
#>
#> $Montana
#> [1] 7 1
#>
#> $Nebraska
#> [1] 8 1
#>
#> $Nevada
#> [1] 6 1
#>
#> $`New Hampshire`
#> [1] 13 1
#>
#> $`New Jersey`
#> [1] 10 1
#>
#> $`New Mexico`
#> [1] 10 1
#>
#> $`New York`
#> [1] 8 1
#>
#> $`North Carolina`
#> [1] 14 1
#>
#> $`North Dakota`
#> [1] 12 1
#>
#> $Ohio
#> [1] 4 1
#>
#> $Oklahoma
#> [1] 8 1
#>
#> $Oregon
#> [1] 6 1
#>
#> $Pennsylvania
#> [1] 12 1
#>
#> $`Rhode Island`
#> [1] 12 1
#>
#> $`South Carolina`
#> [1] 14 1
#>
#> $`South Dakota`
#> [1] 12 1
#>
#> $Tennessee
#> [1] 9 1
#>
#> $Texas
#> [1] 5 1
#>
#> $Utah
#> [1] 4 1
#>
#> $Vermont
#> [1] 7 1
#>
#> $Virginia
#> [1] 8 1
#>
#> $Washington
#> [1] 10 1
#>
#> $`West Virginia`
#> [1] 13 1
#>
#> $Wisconsin
#> [1] 9 1
#>
#> $Wyoming
#> [1] 7 1
1:3 |>
set_names() |>
each_dte(~Sys.Date() + c(.i, -.i), n = 2)
#> $`1`
#> [1] 19877 19875
#>
#> $`2`
#> [1] 19878 19874
#>
#> $`3`
#> [1] 19879 19873
state.abb |>
set_names() |>
each_int(~c(nchar(.i), 1L), n = 2)
#> $AL
#> [1] 2 1
#>
#> $AK
#> [1] 2 1
#>
#> $AZ
#> [1] 2 1
#>
#> $AR
#> [1] 2 1
#>
#> $CA
#> [1] 2 1
#>
#> $CO
#> [1] 2 1
#>
#> $CT
#> [1] 2 1
#>
#> $DE
#> [1] 2 1
#>
#> $FL
#> [1] 2 1
#>
#> $GA
#> [1] 2 1
#>
#> $HI
#> [1] 2 1
#>
#> $ID
#> [1] 2 1
#>
#> $IL
#> [1] 2 1
#>
#> $IN
#> [1] 2 1
#>
#> $IA
#> [1] 2 1
#>
#> $KS
#> [1] 2 1
#>
#> $KY
#> [1] 2 1
#>
#> $LA
#> [1] 2 1
#>
#> $ME
#> [1] 2 1
#>
#> $MD
#> [1] 2 1
#>
#> $MA
#> [1] 2 1
#>
#> $MI
#> [1] 2 1
#>
#> $MN
#> [1] 2 1
#>
#> $MS
#> [1] 2 1
#>
#> $MO
#> [1] 2 1
#>
#> $MT
#> [1] 2 1
#>
#> $NE
#> [1] 2 1
#>
#> $NV
#> [1] 2 1
#>
#> $NH
#> [1] 2 1
#>
#> $NJ
#> [1] 2 1
#>
#> $NM
#> [1] 2 1
#>
#> $NY
#> [1] 2 1
#>
#> $NC
#> [1] 2 1
#>
#> $ND
#> [1] 2 1
#>
#> $OH
#> [1] 2 1
#>
#> $OK
#> [1] 2 1
#>
#> $OR
#> [1] 2 1
#>
#> $PA
#> [1] 2 1
#>
#> $RI
#> [1] 2 1
#>
#> $SC
#> [1] 2 1
#>
#> $SD
#> [1] 2 1
#>
#> $TN
#> [1] 2 1
#>
#> $TX
#> [1] 2 1
#>
#> $UT
#> [1] 2 1
#>
#> $VT
#> [1] 2 1
#>
#> $VA
#> [1] 2 1
#>
#> $WA
#> [1] 2 1
#>
#> $WV
#> [1] 2 1
#>
#> $WI
#> [1] 2 1
#>
#> $WY
#> [1] 2 1
bench::mark(
each_int(state.abb, ~c(nchar(.i), 1L), n = 2),
)
#> # A tibble: 1 × 6
#> expression min median `itr/sec` mem_alloc `gc/sec`
#> <bch:expr> <bch> <bch:> <dbl> <bch:byt> <dbl>
#> 1 each_int(state.abb, ~c(nchar(.i), 1… 226µs 296µs 2799. 1.31KB 14.7
Created on 2024-06-02 with reprex v2.1.0