Skip to contents

Given a number of vectors as arguments, constructs an iterator that enumerates the Cartesian product of all arguments.

Usage

igrid(
  ...,
  recycle = FALSE,
  chunkSize,
  chunks,
  simplify = FALSE,
  rowMajor = TRUE
)

Arguments

...

Named vectors to iterate over.

recycle

If TRUE, the iteror starts over on reaching the end.

chunkSize

Optional; how many rows to return in each step.

chunks

Optional; how many chunks to divide the input into.

simplify

If TRUE, inputs are coerced to a common data type and results are returned in a vector (or matrix if chunking is enabled). If FALSE, results are returned as a list (or data.frame if chunking).

rowMajor

If TRUE, the left-most indices change fastest. If FALSE the rightmost indices change fastest.

Value

an iteror that iterates through each element from the Cartesian product of its arguments.

Details

Although they share the same end goal, igrid can yield drastic memory savings compared to expand.grid.

Examples

# Simulate a doubly-nested loop with a single while loop
it <- igrid(a=1:3, b=1:2)
repeat {
  x <- nextOr(it, break)
  cat(sprintf('a = %d, b = %d\n', x$a, x$b))
}
#> a = 1, b = 1
#> a = 2, b = 1
#> a = 3, b = 1
#> a = 1, b = 2
#> a = 2, b = 2
#> a = 3, b = 2

it <- igrid(x=1:3, y=4:5)
nextOr(it, NA) # list(x=1, y=4)
#> $x
#> [1] 1
#> 
#> $y
#> [1] 4
#> 
nextOr(it, NA) # list(x=1, y=5)
#> $x
#> [1] 2
#> 
#> $y
#> [1] 4
#> 
nextOr(it, NA) # list(x=2, y=4)
#> $x
#> [1] 3
#> 
#> $y
#> [1] 4
#> 
nextOr(it, NA) # list(x=2, y=5)
#> $x
#> [1] 1
#> 
#> $y
#> [1] 5
#> 
nextOr(it, NA) # list(x=3, y=4)
#> $x
#> [1] 2
#> 
#> $y
#> [1] 5
#> 
nextOr(it, NA) # list(x=3, y=5)
#> $x
#> [1] 3
#> 
#> $y
#> [1] 5
#> 

# Second Cartesian product
nextOr(it, NA) # list(x=1, y=4)
#> [1] NA
nextOr(it, NA) # list(x=1, y=5)
#> [1] NA
nextOr(it, NA) # list(x=2, y=4)
#> [1] NA
nextOr(it, NA) # list(x=2, y=5)
#> [1] NA
nextOr(it, NA) # list(x=3, y=4)
#> [1] NA
nextOr(it, NA) # list(x=3, y=5)
#> [1] NA

# igrid is an iterator equivalent to base::expand.grid()
# Large data.frames are not created unless the iterator is manually consumed
a <- 1:2
b <- 3:4
c <- 5:6
it3 <- igrid(a=a, b=b, c=c)
df_igrid <- do.call(rbind, as.list(it3))
df_igrid <- data.frame(df_igrid)

# Compare df_igrid with the results from base::expand.grid()
base::expand.grid(a=a, b=b, c=c)
#>   a b c
#> 1 1 3 5
#> 2 2 3 5
#> 3 1 4 5
#> 4 2 4 5
#> 5 1 3 6
#> 6 2 3 6
#> 7 1 4 6
#> 8 2 4 6