Multiple, Unpacking, and Destructuring Assignment

Provides a %<-% operator to perform multiple, unpacking, and destructuring assignment in R. The operator unpacks the right-hand side of an assignment into multiple values and assigns these values to variables on the left-hand side of the assignment.

Variable assignment with zeal!

alt text alt text alt text alt text alt text

What's there to be excited about?

zeallot allows multiple, unpacking, or destructuring assignment in R by providing the %<-% operator. With zeallot you can tighten code with explicit variable names, unpack pieces of a lengthy list or the entirety of a small list, destructure and assign object elements, or do it all at once.

Unpack a vector of values.

c(x, y) %<-% c(0, 1)
#> x
#[1] 0
#> y
#[1] 1

Unpack a list of values.

c(r, d) %<-% list(2, 2)
#> r
#[1] 2
#> d
#[1] 2

Destructure a data frame and assign its columns.

c(duration, wait) %<-% head(faithful)
#> duration
#[1] 3.600 1.800 3.333 2.283 4.533 2.883
#> wait
#[1] 79 54 74 62 85 55

Unpack a nested list into nested left-hand side variables.

c(c(a, b), c(c, d)) %<-% list(list(1, 2), list(3, 4))
#> a
#[1] 1
#> b  
#[1] 2
#> c
#[1] 3
#> d
#[1] 4

Destructure and partially unpack a list. "a" is assigned to first, but "b", "c", "d", and "e" are grouped and assigned to one variable.

c(first, %<-% list("a", "b", "c", "d", "e")
#[1] "a"
#[1] "b"
#[1] "c"
#[1] "d"
#[1] "e"


You can install zeallot from CRAN.


Use devtools to install the latest, development version of zeallot from GitHub.


Getting Started

Below is a simple example using the purrr package and the safely function.

Safe Functions

The purrr::safely function returns a "safe" version of a function. The following example is borrowed from the safely documentation. In this example a safe version of the log function is created.

safe_log <- purrr::safely(log)
#[1] 2.302585
#<simpleError in .f(...): non-numeric argument to mathematical function>

A safe function always returns a list of two elements and will not throw an error. Instead of throwing an error, the error element of the return list is set and the value element is NULL. When called successfully the result element is set and the error element is NULL.

Safe functions are a great way to write self-documenting code. However, dealing with a return value that is always a list could prove tedious and may undo efforts to write concise, readable code. Enter zeallot.

The %<-% Operator

With zeallot's unpacking operator %<-% we can unpack a safe function's return value into two explicit variables and avoid dealing with the list return value all together.

c(res, err) %<-% safe_log(10)
#[1] 2.302585

The name structure of the operator is a flat or nested set of bare variable names built with calls to c(). . These variables do not need to be previously defined. On the right-hand side is a vector, list, or other R object to unpack. %<-% unpacks the right-hand side, checks the number of variable names against the number of unpacked values, and then assigns each unpacked value to a variable. The result, instead of dealing with a list of values there are two distinct variables, res and err.

Further Reading and Examples

For more on the above example, other examples, and a thorough introduction to zeallot check out the vignette on unpacking assignment.

Below are links to discussions about multiple, unpacking, and destructuring assignment in R,

Related work

The vadr package includes a bind operation with much of the same functionality as %<-%. As the author states, "[they] strongly prefer there to be a <- anywhere that there is a modification to the environment." If you feel similarly I suggest looking at vadr. Unfortunately the vadr package is not on CRAN and will need to be installed using devtools::install_github().

Thank you to Paul Teetor for inspiring me to build zeallot.

Without his encouragement nothing would have gotten off the ground.


zeallot 0.1.0

Major Improvements

  • Bumped to stable version.

Minor Improvements

  • Removed outdate language in the unpacking assignment vignette. (#36)

Bug Fixes

  • Destructuring objects with multiple classes will no longer raise a warning. (#35)


Bug Fixes

  • Resolved problem where collector variables would not be assigned the correct default value. (#34)

zeallot 0.0.6

Major Improvements

  • The left-hand side may now contain calls to [[, [, and $ allowing assignment of parts of objects. The parent object must already exist, otherwise an error is raised. (@rafaqz, #32)

zeallot 0.0.5

Major Changes

  • The bracket and colon syntax has been completely removed, users will now see an "unexpected call {" error message when attempting to use the old syntax. Please use the c() syntax for the name structure.

Major Improvements

  • A %->% operator has been added. The right operator performs the same operation as %<-% with the name structure on the right-hand side and the values to assign on the left-hand side.
  • = may be used to specify the default value of a variable. A default value is used when there are an insufficient number of values.

zeallot 0.0.4

Major Changes

  • The bracket and colon syntax has been deprecated in favor of a lighter syntax which uses calls to c(). Documentation and vignettes has been updated accordingly. Using the old syntax now raises a warning and will be removed in future versions of zeallot. (@hadley, #21)

Minor Improvements

  • %<-% can now be used for regular assignment. (@hadley, #17)
  • ... can now be used to skip multiple values without assigning those values and is recommended over the previously suggested ..... (@hadley, #18)

Miscellaneous Changes

  • massign() is no longer exported.

Bug Fixes

  • Numerics on left-hand side are no longer unintentionally quoted, thus no longer treated as valid variable names, and will now raise an error. (@hadley, #20)
  • Language objects on left-hand side are no longer treated as symbols and will now raise an error. (@hadley, #20)

zeallot 0.0.3

  • see notes for additional updates

Minor Improvements

  • Examples now consistently put spaces around colons separating left-hand side variables, e.g. a : b instead of a: b.

Bug Fixes

  • When unpacking an atomic vector, a collector variable will now collect values as a vector. Previously, values were collected as a list (#14).


  • Not on CRAN, changes will appear under version 0.0.3

  • Added missing URL and BugReports fields to DESCRIPTION

  • Fixed broken badges in README

zeallot 0.0.2

  • Initial CRAN release
  • zeallot 0.0.1 may be installed from GitHub

Reference manual

It appears you don't have a PDF plugin for this browser. You can click here to download the reference manual.


0.1.0 by Nathan Teetor, 3 years ago

Report a bug at

Browse source code at

Authors: Nathan Teetor [aut, cre] , Paul Teetor [ctb]

Documentation:   PDF Manual  

MIT + file LICENSE license

Suggests testthat, knitr, rmarkdown, purrr, magrittr

Imported by add2ggplot, completejourney, graphTweets, hacksaw, ipmisc, ipumsr, keras, mlflow.

Suggested by CSTools, SDMtune, listarrays, vctrs.

See at CRAN