Reputation: 1965
I have a nested list of lists that include data tables at the bottom level. My goal is to map a function to a single table to transform the data. I'm currently trying to use purrr:map_depth
and purrr::map_at
in conjunction to create the plot. The reason I need to use map_at or map_if is the plot function I'm using takes different arguments depending on the table.
example below
library(data.table)
library(purrr)
example = list(
group1 = list(
all = data.table(
x = 1:10,
y = 10:1),
not_all = data.table(
x2 = 11:20,
y2 = 20:11)
),
group2 = list(
all = data.table(
x = 1:10,
y = 10:1),
not_all = data.table(
x2 = 11:20,
y2 = 20:11)
),
group3 = list(
all = data.table(
x = 1:10,
y = 10:1),
not_all = data.table(
x2 = 11:20,
y2 = 20:11)
),
group4 = list(
all = data.table(
x = 1:10,
y = 10:1),
not_all = data.table(
x2 = 11:20,
y2 = 20:11)
)
)
I'm planning to use highcharter::data_to_boxplot
as the mapping function.
So far I've been unable to extract a single table to map to and don't have a solid grasp of the purrr syntax yet.
map_depth(example, 2, map_at(., "all", data_to_boxplot, variable = x))
# Error: character indexing requires a named object
map_depth(example, 2, ~map_at(., "all", data_to_boxplot, variable = x))
# this prints out the entire list
# would like to try something like this too but can't figure out the piping correctly
map_depth(example, 2) %>%
map_at(., "all", data_to_boxplot, variable = x)
# Error in as_mapper(.f, ...) : argument ".f" is missing, with no default
Any help would be greatly appreciated!
Upvotes: 3
Views: 428
Reputation: 16998
I think you need a nested map
-map_at
-construct:
library(data.table)
library(highcharter)
library(purrr)
example %>%
map(~.x %>%
map_at("all", data_to_boxplot, variable = x))
This returns
$group1
$group1$all
# A tibble: 1 x 4
name data id type
<lgl> <list> <lgl> <chr>
1 NA <list [1]> NA boxplot
$group1$not_all
x2 y2
1: 11 20
2: 12 19
3: 13 18
4: 14 17
5: 15 16
6: 16 15
7: 17 14
8: 18 13
9: 19 12
10: 20 11
$group2
$group2$all
# A tibble: 1 x 4
name data id type
<lgl> <list> <lgl> <chr>
1 NA <list [1]> NA boxplot
$group3
$group3$all
# A tibble: 1 x 4
name data id type
<lgl> <list> <lgl> <chr>
1 NA <list [1]> NA boxplot
$group4
$group4$all
# A tibble: 1 x 4
name data id type
<lgl> <list> <lgl> <chr>
1 NA <list [1]> NA boxplot
How does this work?
example
is a list
of list
s. map
applies a function to each element of this list. These elements are also lists.map
is just another map
-function, which is applied to an object named all
(here at "level 2").This is equivalent to
example %>%
map_depth(1,
~.x %>%
map_at("all", data_to_boxplot, variable = x),
)
Take a look at ?map_depth
:
map_depth(.x, .depth, .f, ..., .ragged = FALSE)
with .depth
defined as "Level of .x
to map on. Use a negative value to count up from the lowest level of the list."
map_depth(x, 0, fun)
is equivalent to fun(x)
.map_depth(x, 1, fun)
is equivalent to x <- map(x, fun)
.map_depth(x, 2, fun)
is equivalent to x <- map(x, ~ map(., fun))
.Upvotes: 4