#r
Вопрос:
У меня есть вектор строк, которые я хочу отсортировать в алфавитном порядке, а затем отсортировать по номеру, который находится в конце строк. Конечный результат должен быть "AGSHIM1", "AGSHIU1", "AGSHIZ1","AGSHIH2", "AGSHIM2","AGSHIU2", "AGSHIZ2"
d<-c("AGSHIZ2", "AGSHIZ1", "AGSHIU1", "AGSHIM1", "AGSHIH2", "AGSHIM2",
"AGSHIU2")
d[order(d,as.numeric(substr(d, nchar(d), nchar(d))))]
>"AGSHIH2" "AGSHIM1" "AGSHIM2" "AGSHIZ1" "AGSHIZ2" "AGSHIU1" "AGSHIU2"
Ответ №1:
Что вы можете сделать, так это отделить число от строки и сначала отсортировать по номеру, а затем внутри каждой группы чисел отсортировать в алфавитном порядке:
sortSpecial <- function(d) {
df <- data.frame(
original = d,
chars = gsub("[[:digit:]]", "", d),
nums = gsub("[^[:digit:]]", "", d)
)
df <- df[with(df, order(nums, chars)),]
return(df$original)
}
d <- sortSpecial(d)
d
# [1] "AGSHIM1" "AGSHIU1" "AGSHIZ1" "AGSHIH2" "AGSHIM2" "AGSHIU2" "AGSHIZ2"
Должен быть более элегантный подход, я просто этого не знаю. Тем не менее, дайте мне знать, если это поможет.
Обновить
Я не мог не вдохновиться подходом Картика С. Если вы не хотите сначала генерировать функцию, вы можете выполнить те же действия, что и перед использованием dplyr:
library(dplyr)
d <- data.frame(d = d) %>%
mutate(
chars = gsub("[[:digit:]]", "", d),
nums = gsub("[^[:digit:]]", "", d)
) %>%
arrange(nums, chars) %>%
pull(d)
Опять же, шаги идентичны, поэтому выбор подхода является вопросом предпочтения.
Ответ №2:
Другой подход. Но я уверен, что, скорее всего, существует более короткое решение.
library(dplyr)
library(stringr)
library(tibble)
d %>% as.tibble() %>%
transmute(dig = str_extract(value,'\d'), ltrs = str_remove(value, '\d')) %>% type.convert(as.is = 1) %>%
arrange(dig,ltrs) %>% transmute(d = str_c(ltrs,dig, sep = '')) %>% pull(d)
[1] "AGSHIM1" "AGSHIU1" "AGSHIZ1" "AGSHIH2" "AGSHIM2" "AGSHIU2" "AGSHIZ2"
Комментарии:
1. Просто комментарий, я считаю, что если вы используете
mutate
вместо первогоtransmute
, то вам не понадобится втораяtransmute
операция. Однако вам нужно было быpull(value)
вместоpull(d)
этого.
Ответ №3:
Вот один базовый вариант R, использующий gsub
order
> d[order(as.numeric(gsub("\D", "", d)), d)]
[1] "AGSHIM1" "AGSHIU1" "AGSHIZ1" "AGSHIH2" "AGSHIM2" "AGSHIU2" "AGSHIZ2"