Удобный способ размещения строк данных в соответствии с целевыми порядками сортировки - PullRequest
1 голос
/ 06 ноября 2019

В 2015 году я задал похожий вопрос по этому вопросу, но я хотел бы найти аккуратный способ сделать это.

Это лучшее, что я мог придуматьдо сих пор. Это работает, но необходимость менять типы столбцов только для сортировки кажется «неправильной». Однако то же самое относится и к dplyr::*_join(), а match() имеет свои собственные уловы (плюс его трудно использовать в аккуратном контексте).

Так есть ли хороший / рекомендуемый способ сделать это в тидиверсе?

Определить функцию

library(magrittr)

arrange_by_target <- function(
  x,
  targets
) {
  x %>%
    # Transform arrange-by columns to factors so we can leverage the order of
    # the levels:
    dplyr::mutate_at(
      names(targets),
      function(.x, .targets = targets) {
        .col <- deparse(substitute(.x))
        factor(.x, levels = .targets[[.col]])
      }
    ) %>%
    # Actual arranging:
    dplyr::arrange_at(
      names(targets)
    ) %>%
    # Clean up by recasting factor columns to their original type:
    dplyr::mutate_at(
      .vars = names(targets),
      function(.x, .targets = targets) {
        .col <- deparse(substitute(.x))
        vctrs::vec_cast(.x, to = class(.targets[[.col]]))
      }
    )
}

Тест

x <- tibble::tribble(
  ~group, ~name, ~value,
  "A", "B", 1,
  "A", "C", 2,
  "A", "A", 3,
  "B", "B", 4,
  "B", "A", 5
)

x %>%
  arrange_by_target(
    targets = list(
      group = c("B", "A"),
      name = c("A", "B", "C")
    )
  )
#> # A tibble: 5 x 3
#>   group name  value
#>   <chr> <chr> <dbl>
#> 1 B     A         5
#> 2 B     B         4
#> 3 A     A         3
#> 4 A     B         1
#> 5 A     C         2

x %>%
  arrange_by_target(
    targets = list(
      group = c("B", "A"),
      name = c("A", "B", "C") %>% rev()
    )
  )
#> # A tibble: 5 x 3
#>   group name  value
#>   <chr> <chr> <dbl>
#> 1 B     B         4
#> 2 B     A         5
#> 3 A     C         2
#> 4 A     B         1
#> 5 A     A         3

Создано в2019-11-06 пакетом представ (версия 0.3.0)

1 Ответ

0 голосов
/ 06 ноября 2019

Самый простой способ сделать это - преобразовать столбцы персонажа в факторы, например:

x %>% 
  mutate(
      group = factor(group, c("A", "B")), 
      name = factor(name, c("C", "B", "A"))
  ) %>% 
  arrange(group, name)

Другой вариант, который я часто использую, - это использование объединений. Например:

x <- tibble::tribble(
  ~group, ~name, ~value,
  "A", "B", 1,
  "A", "C", 2,
  "A", "A", 3,
  "B", "B", 4,
  "B", "A", 5,
  "A", "A", 6,
  "B", "C", 7,
  "A", "B", 8,
  "B", "B", 9
)

custom_sort <- tibble::tribble(
  ~group, ~name,
  "A", "C",
  "A", "B",
  "A", "A",
  "B", "B",
  "B", "A"
)

x %>% right_join(custom_sort)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...