Skip to content

Instantly share code, notes, and snippets.

@jrosell
Last active February 12, 2026 13:53
Show Gist options
  • Select an option

  • Save jrosell/792c976825a35eba9f169fffed5f8a7c to your computer and use it in GitHub Desktop.

Select an option

Save jrosell/792c976825a35eba9f169fffed5f8a7c to your computer and use it in GitHub Desktop.
Do you want to merging R objects like dictionaries in R? It seems like using base vectors are the fastest of the explored options to merge like dictionaries in R. 15 times faster than purrr::list_modify, fastmap or collections::dict
title format
Merging R objects like dictionaries in R
html

Let's explore how to merge lists, enviroments or vectors like dictionaries in R.

pak::pak(c(
  "purrr",
  "rlang",
  "bench",
  "flextable",
  "dplyr",
  "fastmap",
  "collections"
))

Merging lists as dictionaries in R

I have this:

context <- list("language" = "en", "timezone" = "UTC", "breadcrumbs" = "None")
more_context <- list("title" = "Home", "breadcrumbs" = "Home")

I would like this output:

#$language
#[1] "en"
#
#$timezone
#[1] "UTC"
#
#$breadcrumbs
#[1] "Home"
#
#$title
#[1] "Home"

What functions can I use?

list_base_modify <- \() {
  context <- list("language" = "en", "timezone" = "UTC", "breadcrumbs" = "None")
  more_context <- list("title" = "Home", "breadcrumbs" = "Home")
  result <- context |>
    modifyList(more_context)
  result
}
list_base_modify()
list_tidyverse_modify <- \() {
  context <- list("language" = "en", "timezone" = "UTC", "breadcrumbs" = "None")
  more_context <- list("title" = "Home", "breadcrumbs" = "Home")
  result <- context |>
    purrr::list_modify(!!!more_context)
  result
}
list_tidyverse_modify()
library(fastmap)
list_fastmap_set <- \() {
  context <- list("language" = "en", "timezone" = "UTC", "breadcrumbs" = "None")
  more_context <- list("title" = "Home", "breadcrumbs" = "Home")
  m <- fastmap()
  m$mset(.list = context)
  m$mset(.list = more_context)
  m$as_list()
}
list_fastmap_set()
library(collections)
list_collections_dict_update <- \() {
  context <- list("language" = "en", "timezone" = "UTC", "breadcrumbs" = "None")
  more_context <- list("title" = "Home", "breadcrumbs" = "Home")
  d <- dict(context)
  d$update(dict(more_context))
  d$as_list()
}
list_collections_dict_update()

Merging enviroments as dictionaries in R

For enviroments, I would like this output:

#$language
#[1] "en"
#
#$timezone
#[1] "UTC"
#
#$breadcrumbs
#[1] "Home"
#
#$title
#[1] "Home"
library(rlang)
env_rlang_list2env <- \() {
  context <- list2env(list(
    "language" = "en",
    "timezone" = "UTC",
    "breadcrumbs" = "None"
  ))
  more_context <- list("title" = "Home", "breadcrumbs" = "Home")
  env_bind(context, !!!more_context)
  result <- as.list(context)
  result
}
env_rlang_list2env()

Merging vectors as dictionaries in R

I have this:

context <- c("language" = "en", "timezone" = "UTC", "breadcrumbs" = "None")
more_context <- c("title" = "Home", "breadcrumbs" = "Home")

I would like this output:

#   language    timezone       title breadcrumbs 
#       "en"       "UTC"      "Home"      "Home" 

What functions can I use?

vectors_base_names <- \() {
  context <- c("language" = "en", "timezone" = "UTC", "breadcrumbs" = "None")
  more_context <- c("title" = "Home", "breadcrumbs" = "Home")
  context[names(more_context)] <- more_context
  context
}
vectors_base_names()
vectors_tidyverse_names <- \() {
  context <- c("language" = "en", "timezone" = "UTC", "breadcrumbs" = "None")
  more_context <- c("title" = "Home", "breadcrumbs" = "Home")
  result <- context |>
    purrr::discard_at(names(more_context)) |>
    c(more_context)
  result
}
vectors_tidyverse_names()

Conclusions

library(bench)
library(flextable)
library(dplyr)

results <- bench::mark(
  iterations = 10000,
  check = FALSE,
  list_base_modify(),
  list_tidyverse_modify(),
  list_fastmap_set(),
  list_collections_dict_update(),
  env_rlang_list2env(),
  vectors_base_names(),
  vectors_tidyverse_names()
)

ranking <- results |>
  select(expression, median, `itr/sec`) |>
  mutate(expression = as.character(expression)) |>
  arrange(desc(`itr/sec`))
ranking$faster <- as.double(ranking$median[[nrow(ranking)]] / ranking$median)
ranking
ranking |>
  flextable() |>
  colformat_double(j = "faster", digits = 2)

It seems like using base vectors are the fastest of the explored options to merge like dictionaries in R. 15 times faster than purrr::list_modify, fastmap or collections::dict

@jrosell
Copy link
Author

jrosell commented Feb 12, 2026

# A tibble: 7 × 4
  expression                       median `itr/sec` faster
                                   
1 vectors_base_names()             1.44µs   659799.  15.8 
2 list_base_modify()               5.39µs   177834.   4.22
3 env_rlang_list2env()             6.66µs   144925.   3.42
4 list_collections_dict_update()  19.95µs    49000.   1.14
5 vectors_tidyverse_names()       20.66µs    45073.   1.10
6 list_tidyverse_modify()          21.5µs    45050.   1.06
7 list_fastmap_set()              22.76µs    42821.   1  

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment