Reputation: 837
The expand.grid gives the results ordered by the last entered set, but I need it based on the first set.
Given the following code:
expand.grid(a=(1:2),b=c("a","b","c"))
a b
1 1 a
2 2 a
3 1 b
4 2 b
5 1 c
6 2 c
Notice how column a changes most often with b less often.
The algorithm it seems is lock the 2nd or Nth variable b and then alternate the 1st or (N-1) variable until the grid gets to every combination possible in the grid.
I need to expand.grid or a similar function that first sets the 1st variable and then adjusts the 2nd variable and so on until it gets to all N.
The desired result for the example is:
a b
1 1 a
2 1 b
3 1 c
4 2 a
5 2 b
6 2 c
One way I that works for the example is simply to order by column a, but that does not work as I would need to be able to order by N columns in order and I have not found a way to do so.
It seems so trivial, but I cannot find a way to get expand.grid to behave like I need.
Any solution must work on any arbitrary number of entries to expand.grid and of any arbitrary size. Thank you.
Upvotes: 3
Views: 1188
Reputation: 341
Here is a base-R solution, that works with any amount of variables without knowing the content beforehand.
Gather all the variables in a list, with the desired order in which you want to expand. Apply a reverse function rev
first on the list in expand.grid
and a second time on the output to get the desired expanding result.
Your example:
l <- list(a=(1:2),b=c("a","b","c"))
rev(expand.grid(rev(l)))
#> a b
#> 1 1 a
#> 2 1 b
#> 3 1 c
#> 4 2 a
#> 5 2 b
#> 6 2 c
An example with 3 variables:
var1 <- c("SR", "PL")
var2 <- c(1,2,3)
var3 <- c("A",'B')
l <- list(var1,var2,var3)
rev(expand.grid(rev(l)))
#> Var3 Var2 Var1
#> 1 SR 1 A
#> 2 SR 1 B
#> 3 SR 2 A
#> 4 SR 2 B
#> 5 SR 3 A
#> 6 SR 3 B
#> 7 PL 1 A
#> 8 PL 1 B
#> 9 PL 2 A
#> 10 PL 2 B
#> 11 PL 3 A
#> 12 PL 3 B
Upvotes: 4
Reputation: 887951
We can use crossing
from tidyr
library(tidyr)
crossing(a = 1:2, b = c('a', 'b', 'c'))
# A tibble: 6 x 2
# a b
# <int> <chr>
#1 1 a
#2 1 b
#3 1 c
#4 2 a
#5 2 b
#6 2 c
Upvotes: 3
Reputation: 8880
try to do so
library(tidyverse)
df <- expand.grid(a=(1:2),b=c("a","b","c"))
df %>%
arrange_all()
Upvotes: 4
Reputation: 125797
Try this:
expand.grid(b=c("a","b","c"), a=(1:2))[, c("a", "b")]
#> a b
#> 1 1 a
#> 2 1 b
#> 3 1 c
#> 4 2 a
#> 5 2 b
#> 6 2 c
Created on 2020-03-19 by the reprex package (v0.3.0)
Upvotes: 1