Title: | Quickly Evaluate Captured Side Effects |
---|---|
Description: | Map functions while capturing results, errors, warnings, messages and other output tidily, then filter and summarise data frames or lists on the basis of those side effects. |
Authors: | James Goldie [aut, cre] , Jean-Francois Zinque [ctb], Mikhail Balyasin [ctb] |
Maintainer: | James Goldie <[email protected]> |
License: | MIT + file LICENSE |
Version: | 0.5.2 |
Built: | 2024-11-13 06:15:03 UTC |
Source: | https://github.com/jimjam-slam/collateral |
map_safely()
, map_quietly()
and map_peacefully()
are variants of
purrr::map()
that wrap the supplied function .f
using purrr::safely()
and/or purrr::quietly()
in order to capture various side effects. Lists
mapped in this way have an associated class added to them, allowing them to
succinctly summarise captured side effects when displayed in a tibble.
map_safely(.x, .f, otherwise = NULL, quiet = TRUE, ...) map_quietly(.x, .f, ...) map_peacefully(.x, .f, ...) map2_safely(.x, .y, .f, otherwise = NULL, quiet = TRUE, ...) map2_quietly(.x, .y, .f, ...) map2_peacefully(.x, .y, .f, ...) pmap_safely(.l, .f, otherwise = NULL, quiet = TRUE, ...) pmap_quietly(.l, .f, ...) pmap_peacefully(.l, .f, ...) future_map_safely(.x, .f, otherwise = NULL, quiet = TRUE, ...) future_map_quietly(.x, .f, ...) future_map_peacefully(.x, .f, ...) future_map2_safely(.x, .y, .f, otherwise = NULL, quiet = TRUE, ...) future_map2_quietly(.x, .y, .f, ...) future_map2_peacefully(.x, .y, .f, ...) future_pmap_safely(.l, .f, otherwise = NULL, quiet = TRUE, ...) future_pmap_quietly(.l, .f, ...) future_pmap_peacefully(.l, .f, ...)
map_safely(.x, .f, otherwise = NULL, quiet = TRUE, ...) map_quietly(.x, .f, ...) map_peacefully(.x, .f, ...) map2_safely(.x, .y, .f, otherwise = NULL, quiet = TRUE, ...) map2_quietly(.x, .y, .f, ...) map2_peacefully(.x, .y, .f, ...) pmap_safely(.l, .f, otherwise = NULL, quiet = TRUE, ...) pmap_quietly(.l, .f, ...) pmap_peacefully(.l, .f, ...) future_map_safely(.x, .f, otherwise = NULL, quiet = TRUE, ...) future_map_quietly(.x, .f, ...) future_map_peacefully(.x, .f, ...) future_map2_safely(.x, .y, .f, otherwise = NULL, quiet = TRUE, ...) future_map2_quietly(.x, .y, .f, ...) future_map2_peacefully(.x, .y, .f, ...) future_pmap_safely(.l, .f, otherwise = NULL, quiet = TRUE, ...) future_pmap_quietly(.l, .f, ...) future_pmap_peacefully(.l, .f, ...)
.x |
A list or atomic vector. |
.f |
A function, formula or atomic vector, as specified by
|
otherwise |
Default value to use when an error occurs. |
quiet |
Hide errors ( |
... |
Other arguments supplied to |
.y |
A list or atomic vector, of the same length as |
.l |
A list of lists. The length of |
map_safely()
will summarise the returned list with a fixed-width
string of two (spaced) columns:
If a result
component is present, R
appears, and
If an error
component is present, E
appears.
If either component is missing, an underscore (_
) appears in its
place.
Similarly, map_quietly()
will summarise the returned list with a
fixed-width string of four (spaced) columns:
If a result
component is present, R
appears,
If an output
component is present, O
appears,
If a messages
component is present, M
appears, and
If a warnings
component is present, W
appears.
If any is missing, an underscore (_
) appears in its
place.
Variants for iterating over two or more inputs simultaneously
are also provided and function identically to their purrr
counterparts:
map2_safely()
map2_quietly()
pmap_safely()
pmap_quietly()
Further variants, prefixed by future_
, allow safe or quiet mapping to
happen in parallel if you have the furrr
package installed:
future_map_safely()
future_map_quietly()
future_map2_safely()
future_map2_quietly()
future_pmap_safely()
future_pmap_quietly()
A list of the same length as .x
. Each element of the returned list
is itself a named list, structured according to the captured side effects.
The Details section elaborates on these side effects.
library(tibble) library(dplyr) library(tidyr) library(collateral) # like map(), these can be used to iterate over vectors or lists list("a", 10, 100) %>% map_safely(log) list(5, -12, 103) %>% map_quietly(log) # if you're using tibbles, you can also iterate over list-columns, # such as nested data frames mtcars %>% rownames_to_column(var = "car") %>% as_tibble() %>% select(car, cyl, disp, wt) %>% # spike some rows in cyl == 4 to make them fail mutate(wt = dplyr::case_when( wt < 2 ~ -wt, TRUE ~ wt)) %>% # nest and do some operations quietly() nest(data = -cyl) %>% mutate(qlog = map_quietly(data, ~ log(.$wt)))
library(tibble) library(dplyr) library(tidyr) library(collateral) # like map(), these can be used to iterate over vectors or lists list("a", 10, 100) %>% map_safely(log) list(5, -12, 103) %>% map_quietly(log) # if you're using tibbles, you can also iterate over list-columns, # such as nested data frames mtcars %>% rownames_to_column(var = "car") %>% as_tibble() %>% select(car, cyl, disp, wt) %>% # spike some rows in cyl == 4 to make them fail mutate(wt = dplyr::case_when( wt < 2 ~ -wt, TRUE ~ wt)) %>% # nest and do some operations quietly() nest(data = -cyl) %>% mutate(qlog = map_quietly(data, ~ log(.$wt)))
Returns a logical vector indicating which elements contain a type of side effect. If you have a large data frame or list, you can use this to isolate the element that contain warnings, for example, or messages.s
has_results(x) has_errors(x) has_warnings(x) has_messages(x) has_output(x)
has_results(x) has_errors(x) has_warnings(x) has_messages(x) has_output(x)
x |
A |
The has_*()
functions power the 'tally_*()“ functions and, in turn,
the summary()
method.
A logical vector, of the same length as x
, which is TRUE
for
elements that contain a type of side effect and FALSE
otherwise.
library(tibble) library(dplyr) library(tidyr) library(collateral) list("a", 10, 100) %>% map_safely(log) %>% has_errors() list(5, -12, 103) %>% map_quietly(log) %>% has_warnings() # if you're working with list-columns, the tally functions are useful # in conjunction with dplyr::summarise() mtcars %>% rownames_to_column(var = "car") %>% as_tibble() %>% select(car, cyl, disp, wt) %>% # spike some rows in cyl == 4 to make them fail mutate(wt = dplyr::case_when( wt < 2 ~ -wt, TRUE ~ wt)) %>% # nest and do some operations quietly() nest(data = -cyl) %>% mutate(qlog = map_quietly(data, ~ log(.$wt))) %>% filter(has_warnings(qlog))
library(tibble) library(dplyr) library(tidyr) library(collateral) list("a", 10, 100) %>% map_safely(log) %>% has_errors() list(5, -12, 103) %>% map_quietly(log) %>% has_warnings() # if you're working with list-columns, the tally functions are useful # in conjunction with dplyr::summarise() mtcars %>% rownames_to_column(var = "car") %>% as_tibble() %>% select(car, cyl, disp, wt) %>% # spike some rows in cyl == 4 to make them fail mutate(wt = dplyr::case_when( wt < 2 ~ -wt, TRUE ~ wt)) %>% # nest and do some operations quietly() nest(data = -cyl) %>% mutate(qlog = map_quietly(data, ~ log(.$wt))) %>% filter(has_warnings(qlog))
The summary()
method for a safely_mapped
or quietly_mapped
list (or list-column) prints out the total number of elements (rows), as well
as the number that each returned results and errors (for
safely_mapped
) or returned results, output, messages and warnings (for
quietly_mapped
). It also invisibly returns a named vector with these
counts.
## S3 method for class 'safely_mapped' summary(object, ...) ## S3 method for class 'quietly_mapped' summary(object, ...) ## S3 method for class 'peacefully_mapped' summary(object, ...)
## S3 method for class 'safely_mapped' summary(object, ...) ## S3 method for class 'quietly_mapped' summary(object, ...) ## S3 method for class 'peacefully_mapped' summary(object, ...)
object |
A |
... |
Other arguments passed to |
Although the output can be used in tidy workflows (for automated testing, for
example), tally functions like tally_results()
tend to be more
convenient for this purpose.
Importantly, the summary()
method tells you how many elements were
returned a type of side effect, not the number of those side
effects. Some list elements might return more than one warning, for
example, and these are not counted separately.
A named vector containing counts of the components named in
map_safely()
.
library(tibble) library(dplyr) library(tidyr) library(collateral) list("a", 10, 100) %>% map_safely(log) %>% summary() list(5, -12, 103) %>% map_quietly(log) %>% summary()
library(tibble) library(dplyr) library(tidyr) library(collateral) list("a", 10, 100) %>% map_safely(log) %>% summary() list(5, -12, 103) %>% map_quietly(log) %>% summary()
Unlike summary()
, the tally functions return counts of individual
types of side effects. This makes them easy to use with
dplyr::summarise()
.
tally_results(x) tally_errors(x) tally_warnings(x) tally_messages(x) tally_output(x)
tally_results(x) tally_errors(x) tally_warnings(x) tally_messages(x) tally_output(x)
x |
A “safely_mapped |
Importantly, the tally functions tell you how many elements returned a type of side effect, not how many side effects were returned. Some list elements might return more than one warning, for example, and these are not counted separately.
An integer vector of length 1.
library(tibble) library(dplyr) library(tidyr) library(collateral) list("a", 10, 100) %>% map_safely(log) %>% tally_errors() list(5, -12, 103) %>% map_quietly(log) %>% tally_warnings() # if you're working with list-columns, the tally functions are useful # in conjunction with dplyr::summarise() mtcars %>% rownames_to_column(var = "car") %>% as_tibble() %>% select(car, cyl, disp, wt) %>% # spike some rows in cyl == 4 to make them fail mutate(wt = dplyr::case_when( wt < 2 ~ -wt, TRUE ~ wt)) %>% # nest and do some operations quietly() nest(data = -cyl) %>% mutate(qlog = map_quietly(data, ~ log(.$wt))) %>% summarise( num_results = tally_results(qlog), num_warnings = tally_warnings(qlog))
library(tibble) library(dplyr) library(tidyr) library(collateral) list("a", 10, 100) %>% map_safely(log) %>% tally_errors() list(5, -12, 103) %>% map_quietly(log) %>% tally_warnings() # if you're working with list-columns, the tally functions are useful # in conjunction with dplyr::summarise() mtcars %>% rownames_to_column(var = "car") %>% as_tibble() %>% select(car, cyl, disp, wt) %>% # spike some rows in cyl == 4 to make them fail mutate(wt = dplyr::case_when( wt < 2 ~ -wt, TRUE ~ wt)) %>% # nest and do some operations quietly() nest(data = -cyl) %>% mutate(qlog = map_quietly(data, ~ log(.$wt))) %>% summarise( num_results = tally_results(qlog), num_warnings = tally_warnings(qlog))