Using the `iterors` package
Rich Calaway
(originally for package iterators
)
Peter Meilstrup
(adapted for package iterors
)
Source: vignettes/iterors.Rmd
iterors.Rmd
Introduction
An iterator is a special type of object that generalizes the
notion of a looping variable. When passed as an argument to a function
that knows what to do with it, the iterator supplies a sequence of
values. The iterator also maintains information about its state, in
particular its current index. The iteror
package includes a
number of functions for creating iterators, starting
iteror
, which takes virtually any R object and turns it
into an iterator object. The simplest function that operates on
iterators is the nextOr
function, which when given an
iterator, returns the next value of the iterator. For example, here we
create an iterator object from the sequence 1 to 10, and then use
nextOr
to iterate through the values:
## [1] 1
nextOr(i1)
## [1] 2
You can create iterators from matrices and data frames, using the
by
argument to specify whether to iterate by row or
column:
## Population Income Illiteracy Life Exp Murder HS Grad Frost Area
## Alabama 3615 3624 2.1 69.05 15.1 41.3 20 50708
nextOr(istate)
## Population Income Illiteracy Life Exp Murder HS Grad Frost Area
## Alaska 365 6315 1.5 69.31 11.3 66.7 152 566432
Iterators can also be created from functions, in which case the iterator can be an endless source of values:
## [1] 3 0 9 2
nextOr(ifun)
## [1] 5 2 6 1
For practical applications, iterators can be paired with
foreach
to obtain parallel results quite easily:
> library(foreach)
foreach: simple, scalable parallel programming from Revolution Analytics
Use Revolution R for scalability, fault tolerance and more.
http://www.revolutionanalytics.com
> x <- matrix(rnorm(1e+06), ncol = 10000)
> itx <- iteror(x, by = "row")
> foreach(i = itx, .combine = c) %dopar% mean(i)
[1] -0.0069652059 0.0161112989 0.0080068074 -0.0120020610 0.0017168149
[6] 0.0139835943 -0.0078172106 -0.0024762273 -0.0031558268 -0.0072662893
[11] -0.0055142639 0.0015717907 -0.0100842965 -0.0123601527 0.0136420084
[16] -0.0242922105 -0.0126416949 -0.0052951152 0.0216329326 -0.0262476648
[21] 0.0041937609 0.0121253368 -0.0110165729 0.0044267635 0.0080241894
[26] 0.0042995539 -0.0102826632 0.0051185628 -0.0013970812 -0.0172380786
[31] 0.0096079613 0.0046837729 -0.0080726970 0.0083781727 -0.0234620163
[36] -0.0099883966 0.0026883628 0.0029367320 0.0205825899 0.0035303940
[41] 0.0204990426 -0.0010804987 -0.0033665481 -0.0127492019 -0.0147443195
[46] 0.0027046346 0.0016449793 0.0155575490 -0.0003488394 -0.0079238019
[51] 0.0086390030 -0.0039033309 0.0168593825 -0.0067189572 -0.0009925288
[56] -0.0162907048 -0.0059171838 0.0093806072 0.0100886929 -0.0111677408
[61] 0.0021754963 -0.0056770907 0.0081200698 -0.0029828717 -0.0163704350
[66] 0.0057266267 -0.0017156156 0.0214172738 -0.0141379874 -0.0126593342
[71] 0.0087124575 0.0040231519 0.0038515673 0.0066066908 0.0023586046
[76] -0.0044167901 -0.0090543553 0.0010806096 0.0102288061 0.0039881702
[81] -0.0054549319 -0.0127997275 -0.0031697122 -0.0016100996 -0.0143468118
[86] 0.0035904125 -0.0059399479 0.0085565480 -0.0159064868 0.0054120554
[91] -0.0084420572 0.0194448129 -0.0103192553 -0.0062924628 0.0215069258
[96] 0.0015749065 0.0109657488 0.0152237842 -0.0057181022 0.0035530715
Some Special Iterators
The notion of an iterator is new to R, but should be familiar to
users of languages such as Python. The iterors
package
includes a number of special functions that generate iterators for some
common scenarios. For example, the irnorm
function creates
an iterator for which each value is drawn from a specified random normal
distribution:
## [1] 1.24064062 1.72238239 -0.82900606 1.38497090 -0.20982904 0.07407742
## [7] 1.33183810 -1.04525362 0.08675409 -0.24610433
nextOr(itrn)
## [1] 1.5911071 -1.0213710 -0.1086336 0.3175405 -0.2053331 -1.1374459
## [7] 2.8938814 -1.4785899 0.7855158 1.7803214
Similarly, the irunif
, irbinom
, and
irpois
functions create iterators which draw their values
from uniform, binomial, and Poisson distributions, respectively.
We can then use these functions just as we used
irnorm
:
## [1] 0.83799382 0.46098146 0.75176655 0.34154975 0.63048241 0.41401893
## [7] 0.46108616 0.07897342 0.29397415 0.06656806
nextOr(itru)
## [1] 0.7628841 0.0375041 0.1608400 0.9760850 0.9338968 0.2859095 0.4852197
## [8] 0.7455242 0.6082009 0.1302547
These random number generators are an indefinite process, but
generally, iterators can come to an end. To specify what to do it the
iterator ends, give nextOr
a second argument, named
or
.
The icount
function returns an iterator that counts
starting from one:
## [1] 1
nextOr(it, NULL)
## [1] 2
nextOr(it, NULL)
## [1] 3
nextOr(it, NULL) #is now ended
## NULL
If you call nextOr
in a loop you can tell nextOr to
break
to exit the loop.
## [1] 0
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")