Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: reorder factor levels using a user-supplied sorting function #117

Closed
russHyde opened this issue Feb 22, 2018 · 5 comments
Closed
Labels
feature a feature request or enhancement tidy-dev-day 🤓 Tidyverse Developer Day rstd.io/tidy-dev-day

Comments

@russHyde
Copy link

Hi,
I was wondering whether you might consider adding a function to forcats that sets up factor levels according to a numerically-aware string-sorting method like gtools::mixedsort.
There's a number of use cases: eg, when you end up with genomes ordered like "chr1", "chr10", "chr11" ... "chr2" rather than "chr1", "chr2", ..., in a plot if you don't hack your factors correctly

eg,

fct_alphameric/fct_alnum/fct_mixedsort <- function(x, ...) {
    factor(x, levels = gtools::mixedsort(unique(x), ...))
    }
@russHyde russHyde changed the title Feature request: number-aware alphnumeric factor order Feature request: number-aware alphanumeric factor order Feb 22, 2018
@russHyde russHyde changed the title Feature request: number-aware alphanumeric factor order Feature request: number-aware alphanumeric factor ordering Feb 22, 2018
@huftis
Copy link

huftis commented Mar 19, 2018

I think a better, more general solution would be a function to sort the levels according to a user-defined sort function. Here’s an implementation suggestion:

library(forcats)
fct_sort = function(.f, .fun = sort) {
  f = forcats:::check_factor(.f) # Not needed in dev version
  fct_relevel(f, .fun(levels(f)))
}

x = c("chr1", "chr11", "chr10", "chr2")
fct_sort(x)
#> [1] chr1  chr11 chr10 chr2 
#> Levels: chr1 chr10 chr11 chr2
fct_sort(x, gtools::mixedsort)
#> [1] chr1  chr11 chr10 chr2 
#> Levels: chr1 chr2 chr10 chr11

And perhaps support for a custom order function (e.g. gtools::mixedorder) in addition to a custom sort function would also be useful?

@billdenney
Copy link
Contributor

FYI, naturalsort::naturalfactor does what I think is being requested (working only for natural numbers).

@hadley hadley added the feature a feature request or enhancement label Jan 4, 2019
@hadley
Copy link
Member

hadley commented Jan 4, 2019

I agree with @huftis that a more general fct_sort() is the better interface here

@hadley hadley added the tidy-dev-day 🤓 Tidyverse Developer Day rstd.io/tidy-dev-day label Jan 4, 2019
@russHyde
Copy link
Author

russHyde commented Jan 4, 2019

Cool. Would you like me to work on a PR? (I'd forgotten I opened this issue)

@hadley
Copy link
Member

hadley commented Jan 4, 2019

Sure!

@russHyde russHyde changed the title Feature request: number-aware alphanumeric factor ordering Feature request: reorder factor levels using a user-supplied sorting function Jan 8, 2019
russHyde added a commit to russHyde/forcats that referenced this issue Jan 8, 2019
`fct_sort` takes a factor or character-vector (implictly converted to factor) and reorders the `levels` of that factor using a user-specified function `.fun`.

Code added to `R/sort.R`, unit tests into `tests/testthat/test-fct_sort.R`.

An example showing how to use `fct_sort` to sort number-containing character `levels` by the contained number.
@hadley hadley closed this as completed in 3050c9d Feb 16, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature a feature request or enhancement tidy-dev-day 🤓 Tidyverse Developer Day rstd.io/tidy-dev-day
Projects
None yet
Development

No branches or pull requests

4 participants