Learn R Programming

The iterors package: Fast, compact iteration and tools

A fresh take on iterators in R, leading to faster, shorter code.

Features

  • Main method nextOr(iter, or); allows simpler and faster code.
  • iteror objects are cross-compatible with existing code using iterators (such as the foreach package.)
  • Optimized performance, with often several times less overhead per item.
  • Compatible with Python iterators, via the reticulate package.
  • Comes with batteries included: a complete collection of iterator functions, ported, curated and harmonized from packages iterators, itertools, and itertools2,

How is it different from iterators?

iterors uses the method nextOr(it, or) to retrieve the next element. The trick is that the second argument or is lazily evaluated, so it can specify a return value or an action to take at the end of iteration. In particular, or can be a control flow operator like break or next or return.

For example, this is how you can compute a sum over an iteror it:

total <- 0
repeat total <- total + nextOr(it, break)

To contrast with the previous iterators package: In that package nextElem signals end of iteration by throwing an exception, which means all iterator code had to be written inside a tryCatch. Computing a sum over an iterator looked like this:

total <- 0
tryCatch(
  repeat total <- total + nextElem(it),
  error=function(x) {
    if (conditionMessage(x) != "StopIteration") stop(x)
  }
)

Besides requiring less boilerplate, iterator code written using nextOr also performs faster, particularly when using higher-order iterator functions. This is because tryCatch is a relatively expensive operation in R, especially when used once per item. It is also not possible(*) to use break or next to exit an outer loop from inside a tryCatch handler function. while nextOr is designed with that use in mind.

The benchmarking vignette illustrates that computations using iterors can execute several times faster than using iterators.

The iterors package grew out of, and is a complement to, the generators implemented in the async package. async::gen lets you construct iterators with complex logic, using familiar imperative code with ordinary flow control constructs like if for, switch and so on. Meanwhile, functions in this package iterors let you manipulate the output of such a generator in functional style. These two packages form two complementary ways to work with sequential processes.

More reading

For a quick introduction, see vignette("iterors")

For an index of iteror functions organized by task, see vignette("categories", "iterors")

If you are familiar with packages iterators/itertools/itertools2, some functions have been moved. See vignette("cross-reference", "iterors")

To learn how to build custom iterors, see vignette("writing", "iterors")

Installation

For prerelease, run the following after installing devtools:

devtools::install_github('crowding/iterors')

When the package is released, you will be able to install the stable version from CRAN:

install.packages('iterors', dependencies=TRUE)

License

Copyright (c) 2023 Peter Meilstrup. This package as a whole is released under the GNU General Public License (GPL) version 3.0, or (at your option) any later version.

Portions of this package are derived from the iterators package, copyright (c) 2008-2010 Revolution Analytics.

Portions of this package are derived from the itertoolspackage, copyright (c) 2015 Steve Weston.

Portions of this package are derived from the itertools2 package, copyright (c) 2015 John A. Ramey.

Where functions in this package are derived from previous works, this is noted in the Rd documentation, and the original license notice is retained at the top of the relevant source files.

Copy Link

Version

Install

install.packages('iterors')

Monthly Downloads

188

Version

1.0

License

GPL (>= 3)

Issues

Pull Requests

Stars

Forks

Maintainer

Peter Meilstrup

Last Published

May 18th, 2023

Functions in iterors (1.0)

i_pad

Iterator that returns an object followed indefinitely by a fill value
i_recycle

Create a recycling iterator
ireaddf

Create an iterator to read data frames from files
is.iteror

is.iteror indicates if an object is an iteror.
i_break

Create an iterator that can be told to stop.
as.list.iteror

Collect all (or some given number of) values from an iteror, returning a vector of the given type.
i_concat

Iteror that chains multiple arguments together into a single iterator
i_slice

Iteror that returns selected elements from an iterable.
dotproduct

Computes the dot product of two iterable objects.
i_starmap

Iteror that applies a given function to the elements of an iterable.
hasNext

Does This Iterator Have A Next Element
icount

Counting Iterators
concat

Concatenate contents of multiple iterators into a vector.
i_enumerate

Iterator that returns the elements of an object along with their indices
i_keep

Iterator that filters elements not satisfying a predicate function
idedup

Drop duplicated items from an iterator.
i_keepwhile

Iterator that returns elements while a predicate function returns TRUE
i_limit

Limit the length of an iterator.
i_rle

Run-length encoding iterator.
i_roundrobin

Iteror that traverses each given iterable in a roundrobin order
i_tee

Create multiple iterators from one source
ipermutations

Iterator that generates all permutations of a vector.
i_timeout

Create a timeout iterator
makeIwrapper

Iterator Constructor-Constructor Function Wrapper
i_zip

Combine several iterables in parallel.
consume

Consumes the first n elements of an iterator
count

Consumes an iterator and computes its length
icombinations

Iterator that generates all combinations of a vector taken m at a time.
nextOr

Retreive the next element from an iteror.
i_map

Iterator that applies a given function to several iterables concurrently.
iread.table

Iterator over Rows of a Data Frame Stored in a File
i_mask

Iterator that filters elements where corresponding selector is false.
iseq

Iterators for sequence generation
i_unique

Iterator that extracts the unique elements from an iterable object
reduce

Compute the sum, product, or general reduction of an iterator.
nth

Returns the nth item of an iteror
iRNGStream

Iterators returning distant random-number seeds.
isplit

Split Iterator
quantify

Count the number of times an iterable object is TRUE
i_apply

Apply a function to each element of an iterator.
i_window

Construct a sliding window over an iterator
i_chunk

Combine an iterator's values into chunks.
i_dropwhile

Iterator that drops elements until the predicate function returns FALSE
i_rep

Repeat values from an iterator.
i_repeat

Create a repeating iterator
irnorm

Random Number Iterators
idiv

Dividing Iterator
igrid

Iterator that covers the Cartesian product of the arguments.
ireadBin

Create an iterator to read binary data from a connection
iteror.array

Iterate over an array or data frame by a specified dimension.
ireadLines

Iterator over Lines of Text from a Connection
r_to_py.iteror

Wrap an iteror to appear as a Python iterator or vice versa.
record

Record and replay iterators
iteror.function

Construct an iteror object with custom-programmed behavior.
itabulate

Iterator that maps a function to a sequence of numeric values
iteror

Make an iteror from a given object.
take

Return the first n elements of an iterable object in a vector.