Code
library("highcharter")
library("tidyverse")
hc_marital_bar_chart <- gss_cat |>
count(marital) |>
hchart(
type = "bar",
hcaes(x = marital,
y = n)
)
hc_marital_bar_chartError: All arguments must be named list, and why does do.call() want c(list(), list(…)) with htmlwidgets?
Charlotte Jane Hadley
December 10, 2025
Highcharts, do.call and c(list())
I love the {highcharter} package. I think it makes some of the most beautiful, engaging and accessible data visualisations amongst all the {htmlwidgets} packages that I use. It’s very customisable! But if you’re like my clients at SafeLives when you try do advanced things with the package you might get stuck on this problem:
Error: All arguments must be named list
This is just one example of where we need to introduce do.call() to provide a list of arguments to a function that get executed as if the function was called directly with those arguments.
Oooft. That gets into meta-programming and non-standard evaluation. Which gets slightly complicated by using htmlwidgets objects.
Let’s make an example chart showing how many respondents fall in each marital status from the gss_cat dataset:
Now imagine that we want to customise the x-axis within a function dependent on several arguments and data variables. Let’s say we want to customise the following:
label styles
category ordering
In realistic settings we’d likely have a lot more customisation than this.
Great! But the hc_xAxis() function will choke on that:
This is exactly the problem `do.call() from base R is designed for. Let me show you it in use and then explain it:
Here’s the template of the function, do.call(what, args)
what is the function we want to pass arguments, hc_xAxis() in our case.
args is a list of arguments that are provided to the function.
I think the documentation for do.call() is somewhat esoteric, but our motivating example allows us to see a complexity!
Why on earth are we using c(list(), list(…))?
What is a {highcharter} object?
Really under the hood the object is a list of lists, but it has the class "highchart". What about list_hc_xaxis_args?
Do you know what the c() function does? Maybe not. Particularly if you’re vibe coding and/or haven’t really used Base R. The c() function is a lot more clever than it looks, and back in 2015 when I first learned R I often read StackOverflow questions and blog posts that depended on it in some way. Let’s make a fake "highchart" object and use it in c()
list(hc_opts = list("stuff"))
That’s not a “highchart” object anymore. That is why we need to contain it within list() to preserve the structure of the object.
list(structure(list(hc_opts = list("stuff")), class = c("highchart",
"htmlwidget"), package = "highcharter"))
That’s why this fails. It’s not because the hc argument isn’t named. It’s because of type coercion - the actual thing that c() does.
Do you know what we did here? We made a REPREX. We reduced the problem down to its bare components. Without using a taskforce of agents that will lovingly hallucinate about how !!! from {rlang} will solve all your problems.
This is one of my favourite things to do as a data coach. Throw away all the complexity. Make toys. Break the toys. Build up your knowledge.
If you want to learn more about how to make a great reprex with R, get a coffee and read this StackOverflow thread without getting. summary.
