-
Notifications
You must be signed in to change notification settings - Fork 292
Expand file tree
/
Copy pathmap-mapper.R
More file actions
88 lines (81 loc) · 2.6 KB
/
map-mapper.R
File metadata and controls
88 lines (81 loc) · 2.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#' Convert an object into a mapper function
#'
#' `as_mapper` is the powerhouse behind the varied function
#' specifications that most purrr functions allow. It is an S3
#' generic. The default method forwards its arguments to
#' [rlang::as_function()].
#'
#' @param .f A function, formula, or vector (not necessarily atomic).
#'
#' If a __function__, it is used as is.
#'
#' If a __formula__, e.g. `~ .x + 2`, it is converted to a function.
#' No longer recommended.
#'
#' If __character vector__, __numeric vector__, or __list__, it is
#' converted to an extractor function. Character vectors index by
#' name and numeric vectors index by position; use a list to index
#' by position and name at different levels. If a component is not
#' present, the value of `.default` will be returned.
#' @param .default,.null Optional additional argument for extractor functions
#' (i.e. when `.f` is character, integer, or list). Returned when
#' value is absent (does not exist) or empty (has length 0).
#' `.null` is deprecated; please use `.default` instead.
#' @param ... Additional arguments passed on to methods.
#' @export
#' @examples
#' as_mapper(\(x) x + 1)
#' as_mapper(1)
#'
#' as_mapper(c("a", "b", "c"))
#' # Equivalent to function(x) x[["a"]][["b"]][["c"]]
#'
#' as_mapper(list(1, "a", 2))
#' # Equivalent to function(x) x[[1]][["a"]][[2]]
#'
#' as_mapper(list(1, attr_getter("a")))
#' # Equivalent to function(x) attr(x[[1]], "a")
#'
#' as_mapper(c("a", "b", "c"), .default = NA)
as_mapper <- function(.f, ...) {
UseMethod("as_mapper")
}
#' @export
as_mapper.default <- function(.f, ...) {
rlang::as_function(.f)
}
#' @export
#' @rdname as_mapper
as_mapper.character <- function(.f, ..., .null, .default = NULL) {
.default <- find_extract_default(.null, .default)
plucker(as.list(.f), .default)
}
#' @export
#' @rdname as_mapper
as_mapper.numeric <- function(.f, ..., .null, .default = NULL) {
.default <- find_extract_default(.null, .default)
plucker(as.list(.f), .default)
}
#' @export
#' @rdname as_mapper
as_mapper.list <- function(.f, ..., .null, .default = NULL) {
.default <- find_extract_default(.null, .default)
plucker(.f, .default)
}
find_extract_default <- function(.null, .default) {
if (!missing(.null)) {
# warning("`.null` is deprecated; please use `.default` instead", call. = FALSE)
.null
} else {
.default
}
}
plucker <- function(i, default) {
x <- NULL # supress global variables check NOTE
i <- as.list(i)
# Use metaprogramming to create function that prints nicely
new_function(
exprs(x = , ... = ),
expr(pluck_raw(x, !!i, .default = !!default))
)
}