Почему сортировка R изменила данные, импортированные с помощью load (), после обновления с 3.5.2 до 4.0.0? - PullRequest
10 голосов
/ 06 августа 2020

Краткая версия. I load() данные в пакете. Раньше тест в пакете проходил успешно, теперь он не проходит, так как вывод sort изменился. Вот минимальный воспроизводимый пример - подробности см. Ниже:

y <- c("Schaffhausen", "Schwyz", "Seespital", "SRZ")
sort(y)
# OLD 3.5.2 [1] "Schaffhausen" "Schwyz"       "Seespital"    "SRZ"        
# NEW 4.0.0 [1] "SRZ"          "Schaffhausen" "Schwyz"       "Seespital" 
# Update 4.0.2 see comment:
# [1] "Schaffhausen" "Schwyz"       "Seespital"    "SRZ"     

# From jay.sf's comment
sort.int(y, method="radix")
# [1] "SRZ"          "Schaffhausen" "Schwyz"       "Seespital"  
sort.int(y, method="shell")
# [1] "Schaffhausen" "Schwyz"       "Seespital"    "SRZ"  

# From Henrik's comment:
data.table::fsort(y)
# [1] "SRZ"          "Schaffhausen" "Schwyz"       "Seespital"  

Единственное связанное изменение, о котором я сообщил, это

ИЗМЕНЕНИЯ В R 4.0.0 НОВЫЕ ОСОБЕННОСТИ ... При загрузке наборов данных через read.table (), data () теперь использует LC_COLLATE = C, чтобы гарантировать независимые от локали результаты для возможных преобразований строки в фактор.

Но я даже не конечно, если бы это могло объяснить то, что я вижу. Поскольку я хочу свести к минимуму количество импортированных пакетов и понимать, что происходит, я не уверен, что делать дальше. Я что-то упускаю? (Изменение на sort.int с методом radix сработало бы, но все же: Почему это изменилось? Это действительно лучше?

Я только что понял, что (спасибо Роланду) sort вызовы в моем случае sort.int:

function (x, decreasing = FALSE, na.last = NA, ...) 
{
  if (is.object(x)) 
    x[order(x, na.last = na.last, decreasing = decreasing)]
  else sort.int(x, na.last = na.last, decreasing = decreasing, 
    ...)
}

From ?sort.int:

Метод «auto» для краткости выбирает «radix» (менее 2 ^ 31 элементов) numeri c векторов, целочисленных векторов, логических векторов и множителей; в противном случае «оболочка».)

И согласно документам, sort.int не изменился с 4.0.0 на 4.0.2 .

Из ?data.table::setorder

data.table всегда переупорядочивается в "C -locale". Как следствие, порядок может отличаться от порядка, полученного с помощью base :: order. Например, в английских языковых стандартах сортировка чувствительна к регистру в C -locale. Таким образом, сортировка c («c», «a», «B») возвращает c («B», «a», «c») в data.table, но c (« a "," B "," c ") в base :: order. Обратите внимание, что это не имеет значения в большинстве случаев данных; оба возвращают идентичные результаты для идентификаторов, где присутствуют только прописные или строчные буквы («AB123» <«AC234» верно для обоих), или для названий стран и других имен собственных, которые последовательно пишутся с заглавной буквы. Например, ни "America" ​​<"Brazil", ни "america" ​​<"brazil" не затрагиваются, так как первая буква всегда пишется с заглавной буквы. </p>

Использование C -locale делает поведение сортировки в data.table более единообразно для разных сессий и локалей. Поведение base :: order зависит от предположений о локали сеанса R. В английских языковых стандартах "america" ​​<"BRAZIL" по умолчанию истинно, но ложно, если вы вводите Sys.setlocale (locale = "C") или сеанс R был запущен для вас в локали C, что может произойти на серверах / службах, поскольку локаль берется из среды, в которой был запущен сеанс R. Напротив, "america" ​​<"BRAZIL" всегда имеет значение FALSE в data.table независимо от того, как был запущен сеанс R. </p>

(Связанные вопросы Сортировка в зависимости от языка с помощью R и Рекомендация: попытаться перейти на UTF-8 в качестве языкового стандарта или можно ли оставить все как есть? )

Подробности

R.version # old              _                           
platform       x86_64-w64-mingw32          
arch           x86_64                      
os             mingw32                     
system         x86_64, mingw32             
status                                     
major          3                           
minor          5.2                         
year           2018                        
month          12                          
day            20                          
svn rev        75870                       
language       R                           
version.string R version 3.5.2 (2018-12-20)
nickname       Eggshell Igloo 

y <- c("Schaffhausen", "Schwyz", "Seespital", "SRZ")
sort(y)
# [1] "Schaffhausen" "Schwyz"       "Seespital"    "SRZ"         

stringr::str_sort(y)
# [1] "Schaffhausen" "Schwyz"       "Seespital"    "SRZ"         

stringr::str_sort(y, locale = "C")
# [1] "SRZ"          "Schaffhausen" "Schwyz"       "Seespital"   

# =======
R.version # new after upgrade
platform       x86_64-w64-mingw32          
arch           x86_64                      
os             mingw32                     
system         x86_64, mingw32             
status                                     
major          4                           
minor          0.0                         
year           2020                        
month          04                          
day            24                          
svn rev        78286                       
language       R                           
version.string R version 4.0.0 (2020-04-24)
nickname       Arbor Day

y <- c("Schaffhausen", "Schwyz", "Seespital", "SRZ")
sort(y)
# [1] "SRZ"          "Schaffhausen" "Schwyz"       "Seespital"   

stringr::str_sort(y)
# [1] "Schaffhausen" "Schwyz"       "Seespital"    "SRZ"         

stringr::str_sort(y, locale = "C")
#[1] "SRZ"          "Schaffhausen" "Schwyz"       "Seespital"  

# ==== Test with new 4.0.2
R.version
platform       x86_64-w64-mingw32          
arch           x86_64                      
os             mingw32                     
system         x86_64, mingw32             
status                                     
major          4                           
minor          0.2                         
year           2020                        
month          06                          
day            22                          
svn rev        78730                       
language       R                           
version.string R version 4.0.2 (2020-06-22)
nickname       Taking Off Again 

y <- c("Schaffhausen", "Schwyz", "Seespital", "SRZ")
sort(y)
# [1] "Schaffhausen" "Schwyz"       "Seespital"    "SRZ"         

stringr::str_sort(y)
# [1] "Schaffhausen" "Schwyz"       "Seespital"    "SRZ"         

stringr::str_sort(y, locale = "C")
# [1] "SRZ"          "Schaffhausen" "Schwyz"       "Seespital" 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...