Как data.table :: setkey сортирует символы в R? [Дубликат]

10
задан jem77bfp 20 August 2013 в 14:48
поделиться

2 ответа

Обновить март 2014 года

Прозвучали некоторые споры об этом. Начиная с версии v.1.9.2 мы уже установили сортировку setkey, используя C locale; например, все заглавные буквы относятся ко всем строчным буквам, независимо от локали пользователя. Это было изменение, внесенное в v1.8.8, которое мы намеревались отменить, но застряли на данный момент.

Рассмотрим save() - таблицу с ключом в вашей локали и коллегу load() в другом регионе. Когда они присоединяются к этой таблице, она может работать некорректно, если это был порядок сортировки локали. Нам нужно подумать немного осторожнее, если setkey позволит снова упорядочить локаль, возможно, сохранив имя локали вместе с атрибутом «отсортированный», поэтому data.table может по крайней мере сравнивать и обнаруживать, отличается ли текущая локаль тот, который побежал setkey.

Это также по соображениям скорости, поскольку сортировка по языку намного медленнее, чем C locale.

Следовательно, теперь это запрос функции, и дальнейшие комментарии очень приветствуются.

FR # 4842 setkey для сортировки с использованием локализации сессии не C locale



Nice catch! Вызов setkey, в свою очередь, вызывает setkeyv и вызывает fastorder, чтобы «упорядочить» столбцы / записи, которые в свою очередь вызывает chorder.

chorder, в свою очередь, вызывает функцию C Ccountingcharacter.c. Теперь, здесь, я полагаю, проблема возникает из-за «locale».

Давайте посмотрим, что «locale» я нахожу на своем mac.

Sys.getLocale()
# [1] "en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8"

Теперь посмотрим, как order сортирует его:

x <- c("USA", "Ubuntu", "Uzbekistan")
order(x)
# [1] 2 1 3

Теперь давайте изменим «locale» на «C».

Sys.setlocale("LC_ALL", "C")
# [1] "C/C/C/C/C/en_US.UTF-8"

order(x)
# [1] 1 2 3

Из ?order:

Порядок сортировки для символьных векторов будет зависеть от последовательности сортировки используемой локали: см. Comparison.

Из ?Comparison:

Сравнение строк в символьных векторах является лексикографическим в строках с использованием последовательности сортировки используемой локали: см. локали. Последовательность сортировки локалей, таких как en_US, обычно отличается от C (которая должна использовать ASCII) и может быть удивительной. Остерегайтесь делать какие-либо предположения о порядке сортировки: например. на эстонском языке Z происходит между S и T, а сопоставление не обязательно характерно - в датском aa сортируется как одна буква после z ....

Итак, в основном, order, а также в локали «C», дает тот же порядок, что и data.table setkey. Я предполагаю, что C-функция, вызванная chorder, автоматически запускается на C-locale, которая будет сравнивать значения ascii, для которых «S» предшествует «b».

Вероятно, важно довести это до @ MatthewDowle внимание (если он еще не знает об этом). Итак, я предлагаю вам записать это как ошибку здесь (просто чтобы убедиться).

10
ответ дан Matt Dowle 28 August 2018 в 09:03
поделиться

Ну, я не уверен, что самый эффективный способ, но вы можете сделать следующее, чтобы воспроизвести результат data.frame.

dt[order(dt$cn)]

           cn
1:     Ubuntu
2:        USA
3: Uzbekistan
2
ответ дан Wolfgang Wu 28 August 2018 в 09:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: