tidyverse/forcats

`fct_cross()` orders levels by second factor before the first factor

dchiu911 opened this issue · 1 comments

It seems a bit counter-intuitive to me that the crossed factor levels are ordered, for e.g. in the case of 2 inputs, by the second factor levels before the first factor levels.

In the reprex below, I would have expected fct_cross(f1, f2) to have its levels ordered as a4:b4 a3:b3 a2:b2 a1:b1 because levels of f1 are a4 a3 a2 a1. Instead, the new levels are ordered by the levels of f2 so we see a1:b1 as the first level.

I also understand that this is because of how expand.grid() works, but I was hoping to select rows from the output data.frame after sorting the columns from Var1 to VarN.

library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
library(forcats)
(f1 <- fct_inorder(c("a4", "a3", "a2", "a1")))
#> [1] a4 a3 a2 a1
#> Levels: a4 a3 a2 a1
(f2 <- factor(c("b4", "b3", "b2", "b1")))
#> [1] b4 b3 b2 b1
#> Levels: b1 b2 b3 b4
fct_cross(f1, f2)
#> [1] a4:b4 a3:b3 a2:b2 a1:b1
#> Levels: a1:b1 a2:b2 a3:b3 a4:b4

expand.grid(levels(f1), levels(f2))
#>    Var1 Var2
#> 1    a4   b1
#> 2    a3   b1
#> 3    a2   b1
#> 4    a1   b1
#> 5    a4   b2
#> 6    a3   b2
#> 7    a2   b2
#> 8    a1   b2
#> 9    a4   b3
#> 10   a3   b3
#> 11   a2   b3
#> 12   a1   b3
#> 13   a4   b4
#> 14   a3   b4
#> 15   a2   b4
#> 16   a1   b4
expand.grid(levels(f1), levels(f2)) %>% 
  arrange(Var1, Var2)
#>    Var1 Var2
#> 1    a4   b1
#> 2    a4   b2
#> 3    a4   b3
#> 4    a4   b4
#> 5    a3   b1
#> 6    a3   b2
#> 7    a3   b3
#> 8    a3   b4
#> 9    a2   b1
#> 10   a2   b2
#> 11   a2   b3
#> 12   a2   b4
#> 13   a1   b1
#> 14   a1   b2
#> 15   a1   b3
#> 16   a1   b4

Created on 2024-01-17 with reprex v2.0.2