Skip to content

Commit a29c984

Browse files
authored
Update Multiple Map Docs and Examples (#193)
* simplify multiple map implementation * update multiple map docs and examples
1 parent feac10b commit a29c984

File tree

2 files changed

+68
-61
lines changed

2 files changed

+68
-61
lines changed

R/map.R

Lines changed: 38 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,12 @@
7676
#'
7777
#' @section Multiple Map:
7878
#'
79-
#' Multiple map is performed automatically over the \strong{rows} of an object
80-
#' with \sQuote{dim} attributes such as a matrix or dataframe. This is most
81-
#' often the desired behaviour in these cases.
79+
#' If \code{.x} is a matrix or dataframe (or other object with \sQuote{dim}
80+
#' attributes), \emph{multiple} map is performed over its \strong{rows}.
81+
#'
82+
#' In this case, \code{.f} should accept at least as many arguments as the
83+
#' length of each row. If the dataframe has names, or the matrix column
84+
#' dimnames, named arguments are provided to \code{.f}.
8285
#'
8386
#' To map over \strong{columns} instead, first wrap a dataframe in
8487
#' \code{\link{as.list}}, or transpose a matrix using \code{\link{t}}.
@@ -89,25 +92,34 @@
8992
#'
9093
#' daemons(4)
9194
#'
92-
#' # map with constant args specified via '.args'
93-
#' mirai_map(1:3, rnorm, .args = list(mean = 20, sd = 2))[]
95+
#' # perform and collect mirai map
96+
#' mm <- mirai_map(c(a = 1, b = 2, c = 3), rnorm)
97+
#' mm
98+
#' mm[]
9499
#'
95-
#' # flatmap with function definition passed via '...'
96-
#' mirai_map(1:3, function(x) func(1L, x, x + 1L), func = stats::runif)[.flat]
100+
#' # map with constant args specified via '.args'
101+
#' mirai_map(1:3, rnorm, .args = list(n = 5, sd = 2))[]
97102
#'
98-
#' # sum rows of a dataframe
99-
#' (df <- data.frame(a = 1:3, b = c(4, 3, 2)))
100-
#' mirai_map(df, sum)[.flat]
103+
#' # flatmap with helper function passed via '...'
104+
#' mirai_map(
105+
#' 10^(0:9),
106+
#' function(x) rnorm(1L, valid(x)),
107+
#' valid = function(x) min(max(x, 0L), 100L)
108+
#' )[.flat]
101109
#'
102-
#' # sum rows of a matrix
110+
#' # unnamed matrix multiple map: arguments passed to function by position
103111
#' (mat <- matrix(1:4, nrow = 2L))
104-
#' mirai_map(mat, sum)[.flat]
112+
#' mirai_map(mat, function(x = 10, y = 0, z = 0) x + y + z)[.flat]
113+
#'
114+
#' # named matrix multiple map: arguments passed to function by name
115+
#' dimnames(mat)[[2L]] <- c("y", "z")
116+
#' mirai_map(mat, function(x = 10, y = 0, z = 0) x + y + z)[.flat]
105117
#'
106-
#' # map over rows of a dataframe
118+
#' # dataframe multiple map: using a function taking '...' arguments
107119
#' df <- data.frame(a = c("Aa", "Bb"), b = c(1L, 4L))
108120
#' mirai_map(df, function(...) sprintf("%s: %d", ...))[.flat]
109121
#'
110-
#' # indexed map over a vector
122+
#' # indexed map over a vector (using a dataframe)
111123
#' v <- c("egg", "got", "ten", "nap", "pie")
112124
#' mirai_map(
113125
#' data.frame(1:length(v), v),
@@ -116,15 +128,10 @@
116128
#' )[.flat]
117129
#'
118130
#' # return a 'mirai_map' object, check for resolution, collect later
119-
#' mp <- mirai_map(
120-
#' c(a = 2, b = 3, c = 4),
121-
#' function(x, y) do(x, as.logical(x %% y)),
122-
#' do = nanonext::random,
123-
#' .args = list(y = 2)
124-
#' )
131+
#' mp <- mirai_map(2:4, function(x) runif(1L, x, x + 1))
125132
#' unresolved(mp)
126133
#' mp
127-
#' mp[]
134+
#' mp[.flat]
128135
#' unresolved(mp)
129136
#'
130137
#' # progress indicator counts up from 0 to 4 seconds
@@ -134,17 +141,14 @@
134141
#'
135142
#' # generates warning as daemons not set
136143
#' # stops early when second element returns an error
137-
#' tryCatch(
138-
#' mirai_map(list(1, "a", 3), sum)[.stop],
139-
#' error = identity
140-
#' )
144+
#' tryCatch(mirai_map(list(1, "a", 3), sum)[.stop], error = identity)
141145
#'
142146
#' # promises example that outputs the results, including errors, to the console
143147
#' if (requireNamespace("promises", quietly = TRUE)) {
144148
#' daemons(1, dispatcher = FALSE)
145149
#' ml <- mirai_map(
146150
#' 1:30,
147-
#' function(x) {Sys.sleep(0.1); if (x == 30) stop(x) else x},
151+
#' function(i) {Sys.sleep(0.1); if (i == 30) stop(i) else i},
148152
#' .promise = list(
149153
#' function(x) cat(paste(x, "")),
150154
#' function(x) { cat(conditionMessage(x), "\n"); daemons(0) }
@@ -167,21 +171,19 @@ mirai_map <- function(.x, .f, ..., .args = list(), .promise = NULL, .compute = "
167171
return(mirai_map(.x = .x, .f = .f, ..., .args = .args, .promise = .promise, .compute = .compute))
168172
}
169173
xilen <- dim(.x)[1L]
170-
vec <- if (length(xilen))
174+
vec <- if (length(xilen)) {
175+
is_matrix <- is.matrix(.x)
171176
lapply(
172177
seq_len(xilen),
173-
if (is.matrix(.x)) function(i) mirai(
174-
.expr = do.call(.f, c(as.list(.x), .args)),
175-
...,
176-
.args = list(.f = .f, .x = .x[i, ], .args = .args),
177-
.compute = .compute
178-
) else function(i) mirai(
178+
function(i) mirai(
179179
.expr = do.call(.f, c(.x, .args)),
180180
...,
181-
.args = list(.f = .f, .x = lapply(.x, .subset2, i), .args = .args),
181+
.args = list(.f = .f, .x = if (is_matrix) as.list(.x[i, ]) else lapply(.x, .subset2, i), .args = .args),
182182
.compute = .compute
183183
)
184-
) else `names<-`(
184+
)
185+
} else {
186+
`names<-`(
185187
lapply(
186188
.x,
187189
function(x) mirai(
@@ -193,6 +195,7 @@ mirai_map <- function(.x, .f, ..., .args = list(), .promise = NULL, .compute = "
193195
),
194196
names(.x)
195197
)
198+
}
196199

197200
if (length(.promise))
198201
if (is.list(.promise)) {

man/mirai_map.Rd

Lines changed: 30 additions & 26 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)