Я пытаюсь отсортировать вектор символов в естественном порядке (как это сделал бы человек), но с учетом различий в регистрах. Например, в приведенном ниже векторе я хотел бы отсортировать все маленькие «m» и большие «M» независимо.
x<- c("m10", "M10", "m11", "m12", "m2", "M2", "m3", "M3", "m4", "M4", "yo1", "yo2")
Чтобы это выглядело так:
DesiredSort(x)
[1] "M2" "M3" "M4" "M10" "m2" "m3" "m4" "m10" "m11" "m12" "yo1" "yo2"
Из здесь я узнал, как сделать sort
принять во внимание случай:
sortC <- function(...) {
a <- Sys.getlocale("LC_COLLATE")
on.exit(Sys.setlocale("LC_COLLATE", a))
Sys.setlocale("LC_COLLATE", "C")
sort(...)
}
sortC(x)
[1] "M10" "M2" "M3" "M4" "m10" "m11" "m12" "m2" "m3" "m4" "yo1" "yo2"
Но это не дает естественного порядка. Я знаю, что mixedsort
из gtools правильно поместит m2 перед m10, так что:
mixedsort(x)
[1] "m2" "M2" "m3" "M3" "m4" "M4" "m10" "M10" "m11" "m12" "yo1" "yo2"
Но mixedsort
специально игнорирует регистр символьной строки, поэтому выполнение функции, аналогичной SortC, не работает.
У меня есть несколько векторов для сортировки таким образом, и они включают символы, не включенные в пример, поэтому было бы здорово найти общий способ сделать это.
Идеи? Может быть, я упускаю что-то очевидное. Спасибо.
1 ответ
Насколько общим должно быть решение? Это настраиваемое решение, приведенное ниже, подходит для вашего набора данных, но не совсем понятно (по крайней мере, для меня), что вы хотите сделать в общем случае вектора, содержащего произвольные строки.
DesiredSort <- function(x)
{
library(stringr)
locale <- Sys.getlocale("LC_COLLATE")
on.exit(Sys.setlocale("LC_COLLATE", locale))
Sys.setlocale("LC_COLLATE", "C")
x_matches <- str_match(x, "(^[[:alpha:]]+)([[:digit:]]+)")[, 2:3]
x_data <- data.frame(
letter = x_matches[, 1],
number = as.numeric(x_matches[, 2])
)
o <- with(x_data, order(letter, number))
x[o]
}
x <- c("m10", "M10", "m11", "m12", "m2", "M2", "m3", "M3", "m4", "M4", "yo1", "yo2")
expected <- c("M2", "M3", "M4", "M10", "m2", "m3", "m4", "m10", "m11", "m12", "yo1", "yo2")
stopifnot(identical(DesiredSort(x), expected))
testthat
или RUnit
для этого.
Похожие вопросы
Связанные вопросы
Новые вопросы
r
R — это бесплатный язык программирования с открытым исходным кодом и программная среда для статистических вычислений, биоинформатики, визуализации и общих вычислений. Пожалуйста, используйте минимально воспроизводимые примеры, которые другие могут запустить с помощью копирования и вставки. Показать желаемый результат. Используйте dput() для данных и укажите все небазовые пакеты с помощью library(). Не вставляйте изображения для данных или кода, вместо этого используйте блоки кода с отступом. Для вопросов по статистике используйте https://stats.stackexchange.com.