-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy patharrange_natural.R
74 lines (71 loc) · 2.33 KB
/
arrange_natural.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#------------------------------------------------
#' Arrange rows by column values naturally
#'
#' @description
#' `arrange_natural()` orders the rows of a data frame by the values of selected
#' columns.
#'
#' Data is naturally sorted (see *Details*, below) in ascending order. Columns
#' used for sorting are converted to factors to preserve their ordering.
#' Grouping is ignored.
#'
#' @details
#' ## Natural sorting
#' `arrange_natural()` is built on [dplyr::arrange()] to provide
#' \href{https://en.wikipedia.org/wiki/Natural_sort_order}{natural sorting}
#' (sorting of strings with both letters and numerals). The underlying
#' implementation for natural sorting is based on the
#' [stringi][stringi::about_stringi] library.
#'
#' @param .data A data frame, data frame extension (e.g. a tibble), or a lazy
#' data frame (e.g. from dbplyr or dtplyr).
#' @param ... <[`data-masking`][dplyr_data_masking]> Variables to sort by.
#'
#' @return
#' An object of the same type as `.data`. The output has the following
#' properties:
#'
#' * All rows appear in the output, but (usually) in a different place.
#' * Sorted columns are converted to factors.
#' * All other columns are not modified.
#' * Data frame attributes are preserved.
#'
#' @seealso [dplyr::arrange()]
#' @export
#' @examples
#' df <- tibble::tribble(
#' ~sample, ~gene,
#' "D10-23", "atp6",
#' "D10-43", "mdr1",
#' "D10-55", "atp6",
#' "D10-5", "mdr1",
#' "D10-47", "dhps",
#' "D10-15", "atp6"
#' )
#'
#' arrange_natural(df, sample)
#' df %>% arrange_natural(sample, gene)
arrange_natural <- function(.data, ...) {
# Store variables to arrange by
dots <- enquos(..., .named = TRUE)
if (rlang::is_installed("stringi")) {
# Manipulate dots to get arrange variables
arrange_vars <- purrr::map(dots, function(var) {
expr(stringi::stri_rank(as.character(!!var), numeric = TRUE))
})
# Manipulate dots to get mutate variables
mutate_vars <- purrr::map(dots, function(var) {
expr(forcats::as_factor(as.character(!!var)))
})
} else {
cli_warn(c(
"The `stringi` package is required for natural sorting. Please install it.",
"i" = "Alphabetical sorting has been applied instead."
))
return(dplyr::arrange(.data, !!!dots))
}
# Call dplyr::arrange
.data %>%
dplyr::arrange(!!!arrange_vars) %>%
dplyr::mutate(!!!mutate_vars)
}