Home > Blockchain >  Map a list of params to a function using purrr and save the output back to the list
Map a list of params to a function using purrr and save the output back to the list

Time:11-30

I'm having trouble trying to map parameters in a nested list to be used in a function. When using purrr::map, I'm unable to separate the values as arguments and instead the sub list is passed in to .x. I can do this with lapply but would like to know a purrr solution.

Ultimately, I'd like to pass in the parameters of each sub-list into a function and then save the output of the function as a new item in each respective sub-list.

library(data.table)
library(highcharter)
library(lubridate)
library(purrr)
library(tidyr)

plot_map = list(
  apples = list(
    y_val = "apples",
    name = "Apples",
    title = "Daily Apples"
  ),
  oranges = list(
    y_val = "oranges",
    name = "Oranges",
    title = "Daily Oranges"
  ),
  pears = list(
    y_val = "pears",
    name = "Pears",
    title = "Daily Pears"
  ),
  bananas = list(
    y_val = "bananas",
    name = "Bananas",
    title = "Daily Bananas",
    y_title = "Not Count"
  )
)

d = as_date("2022-11-29")

set.seed(10)

# dummy data
d_t = data.table(
  date = seq(floor_date(d, "month"), rollforward(d), by = "day"),
  apples = round(abs(rnorm(1:30) * 10),0),
  oranges = round(abs(rnorm(1:30) * 15),0),
  pears = round(abs(rnorm(1:30) * 20),0),
  bananas = round(abs(rnorm(1:30) * 5),0)
)

create_hc_plot = function(y_val, name, title, y_title = "Count") {
  highchart(type = "chart") %>%
    hc_title(text = title) %>%
    hc_add_series(d_t, hcaes(x = date, y = !!y_val), type = "line", name = name) %>%
    hc_xAxis(type = "datetime") %>%
    hc_yAxis(title = list(text = y_title))
}

Right now the entire sub-list is passed into .x instead of mapping each named param and argument to create_hc_plot.

plot_map %>%
  map(., ~ create_hc_plot(unlist(.x)))

# or

plot_map %>%
  map(., create_hc_plot, unlist(.x))

# Error in `dplyr::mutate()`:
# ! Problem while computing `y = c(y_val = "apples", name = "Apples", title = "Daily Apples")`.
# ✖ `y` must be size 30 or 1, not 3.

Desired output as stated above, would be to save the result of the plot into the same sub-list that called it.

plot_map[['apples']]

# $y_val
# [1] "apples"
# 
# $name
# [1] "Apples"
# 
# $title
# [1] "Daily Apples"
#
# $plot
# HC PLOT here

CodePudding user response:

Instead of three arguments, the unlist(.x) inside create_hc_plot() creates one argument, a vector c(y_val = "apples", name = "Apples", title = "Daily Apples"). You want to use something like do.call:

map(plot_map, ~ do.call(create_hc_plot, .x))

Which correctly plots each graph.

Doing a quick search, I couldn't find how to save highcharts into a object/list element, so I don't know if it's possible. If it is, you could maybe do something like:

plot_map = map(plot_map, ~ c(., plot = list(do.call(create_hc_plot, .x))))
  • Related