Я хочу расположить столбцы в алфавитном порядке, но настроить алфавитный порядок. Мне нужно рассматривать цифры как следующие за буквами.
Например, если это мой ввод,
data.frame(x = c("a1", "a1a", "0a", "za", "2a", "a2", "0ab", "0aa"))
Мне нужно, чтобы результат выглядел так:
data.frame(x = c("a1", "a1a", "a2", "za", "0a", "0aa", "0ab", "2a"))
Какие практические методы существуют для достижения этой цели в R?
Решения Base R, Tidyverse и Data.Table приветствуются.
Худшее, но интересное решение:
library(tidyverse)
DF <- data.frame(x = c("a1", "a1a", "0a", "za", "2a", "a2", "0ab", "0aa"))
DF %>%
mutate(new_x = x %>%
str_replace_all("0", "═") %>%
str_replace_all("1", "╔") %>%
str_replace_all("2", "╚") %>%
str_replace_all("3", "╠") %>%
str_replace_all("4", "╤") %>%
str_replace_all("5", "╦") %>%
str_replace_all("6", "╧") %>%
str_replace_all("7", "╨") %>%
str_replace_all("8", "╩") %>%
str_replace_all("9", "╬")) %>%
arrange(new_x) %>%
select(-new_x)
Вместо того, чтобы заменять исходный столбец взад и вперед, лучше создайте новый столбец, отсортируйте его и затем удалите.
Вы можете сделать (я оставляю дополнительные столбцы для наглядности):
library(tidyverse)
data.frame(x = c("a1", "a1a", "0a", "za", "2a", "a2", "0ab", "0aa")) %>%
mutate(helper = str_sub(x, 1, 1),
digit = if_else(str_detect(helper, '[0-9]'), 1, 0)) %>%
arrange(digit, x)
что дает:
x helper digit
1 a1 a 0
2 a1a a 0
3 a2 a 0
4 za z 0
5 0a 0 1
6 0aa 0 1
7 0ab 0 1
8 2a 2 1
Это не работает для всей строки.
Это базовое решение R. Я предполагаю, что вы работаете в регионе, где буквы сортируются в английском алфавитном порядке, а цифры сортируются перед ними. Итак, идея состоит в том, чтобы перевести символы и отсортировать переведенные строки.
# This is standard collation order
standard <- "0123456789abcdefghijklmnopqrstuvwxyz"
# This is the special order that should be used in our string
special <- "abcdefghijklmnopqrstuvwxyz0123456789"
df <- data.frame(x = c("a1", "a1a", "0a", "za", "2a", "a2", "0ab", "0aa"))
# First, modify the "special" chars in our string to their standard
# equivalent
modified <- chartr(old = special, new = standard, tolower(df$x))
# Now sort the dataframe using the modified strings
df[order(modified),]
Я использовал tolower(df$x)
, потому что стандартная сортировка (а не компьютерная сортировка, как это делается sort()
) не различает регистр. Если ваши реальные данные имеют смешанный регистр букв и вас волнует, как сортируются такие вещи, как c("a", "A")
, тогда вы будете использовать разные векторы standard
и special
и не будете использовать tolower()
.
вы можете создать вспомогательный столбец, определяющий, является ли первый символ буквой или цифрой. Затем вы можете выполнить сортировку по а) этому вспомогательному столбцу, за которым следует б) фактическая строка.