【问题标题】:Language dependent sorting with R使用 R 进行语言相关排序
【发布时间】:2023-12-26 20:33:01
【问题描述】:

1) 如何正确排序?

任务是根据英文字母对美国各州的缩写名称进行排序。但我注意到,R 排序列表基于某种操作系统语言或区域设置。例如,在我的语言(立陶宛语)中,甚至拉丁语(非立陶宛语)字母的顺序也与英语字母表中的顺序不同。仅比较两个字母表中非立陶宛语字母的顺序:

"ABCDEFGHI Y JKLMNOPRSTUVZ"

sort(LETTERS)
 [1] "A" "B" "C" "D" "E" "F" "G" "H" "I" "Y" "J" "K" "L" "M" "N"
[16] "O" "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Z"

对比

"ABCDEFGHIJKLMNOPQRSTUVWX Y Z"

LETTERS
 [1] "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O"
[16] "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z"

所以各州的排序缩写顺序也不同(注意最后两个,它们应该是“WV”然后是“WY”):

sort(state.abb)
 [1] "AK" "AL" "AR" "AZ" "CA" "CO" "CT" "DE" "FL" "GA" "HI" "IA"
[13] "ID" "IL" "IN" "KY" "KS" "LA" "MA" "MD" "ME" "MI" "MN" "MO"
[25] "MS" "MT" "NC" "ND" "NE" "NH" "NY" "NJ" "NM" "NV" "OH" "OK"
[37] "OR" "PA" "RI" "SC" "SD" "TN" "TX" "UT" "VA" "VT" "WA" "WI"
[49] "WY" "WV"

我试过Sys.setlocale("LC_TIME","English_United States.1252")。它有助于在绘图、图表和图形中获取工作日的英文名称。

现在我需要帮助才能以“英语”方式正确排序。

2) R 初学者还应注意哪些其他重要的与语言相关的设置?

如果您有建议,R 在哪里表现依赖于语言以及如何处理,请列出。

【问题讨论】:

  • 您的操作系统语言/区域设置不是英语吗?
  • 你试过LC_ALL而不是LC_TIME吗?您可能猜到,LC_TIME 仅影响与日期/时间相关的本地化。 — 另一件事,避免使用 Windows 字符编码(例如代码页 1252)。独占使用 UTF-8。
  • LC_ALL 工作:> sort(LETTERS) [1] "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" [16] "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z" 谢谢康拉德鲁道夫。写下您的评论作为答案,我想接受它,以便对其他人更有帮助。
  • 使用stringi::stri_sort 并通过stri_opts_collator 传递您想要的任何语言环境,以便在不改变您的环境的情况下进行与语言相关的排序。

标签: r sorting non-english


【解决方案1】:

LC_TIME 控制与日期/时间相关的语言排序。出于您的目的,LC_ALL 应该可以解决问题:

Sys.setenv('LC_ALL', 'English_United States.1252')
sort(letters)

但是,请注意这些设置是特定于操作系统的。例如,上述内容不适用于典型的 Unix 系统。相反,字符串'en_US.UTF-8' 通常是一个很好的设置——但在 Windows 下,这本身可能会带来问题,因为 R 的 Unicode 支持在 Windows 上是粗略的。

【讨论】:

    【解决方案2】:

    我不熟悉 R,但它似乎与许多其他编程语言有相同的问题:标准库中缺乏原生 Unicode 支持。 “Unicode 支持”是指 Unicode 标准 (http://www.unicode.org/versions/Unicode7.0.0/ch03.pdf) 的第 3 章、Unicode 标准的附件(尤其是处理排序规则的那个 http://unicode.org/reports/tr10/)和 CLDR 的最新版本 (http://cldr.unicode.org/) .本质上,如果不选择一些“真实”的方法并忽略文化差异,就无法标准化排序的模棱两可的规则。通过允许忽略某些细节(如变音符号)的多个排序规则级别,创建大小写折叠算法(在某些情况下为 toLower(toUpper(str)) != toLower(str)),通过 CLDR 定义排序规则规则,部分缓解了这种情况数据库,但问题仍然存在。还有一些问题,如上下文相关比较 (http://unicode.org/reports/tr10/#Contextual_Sensitivity),如果您想要进行“正确”的字符串比较,则需要使用符合 Unicode 标准的成熟解决方案。

    有一个著名的库称为 ICU(Unicode 国际组件),与其他库相比,它实现了 Unicode 标准的大量功能。它在 C/C++ 和 Java 中实现(所有开源都具有类似 BSD 的许可证,但有与其他语言的 C 版本的绑定,包括 R(https://cran.r-project.org/web/packages/stringi/http://site.icu-project.org/related)。所以你可以使用'stringi ' 使用 ICU 语言环境和整理工具进行文本处理的项目。

    更新: 为了使用 ICU 整理方法,您需要获取 ICU4C(因不同操作系统而异),然后为 R 语言安装一个包:

    install.packages('stringi')

    那你应该导入它

    library(stringi)
    

    之后您可以使用这些类型的函数 (http://docs.rexamine.com/R-man/stringi/stri_compare.html)。您可以在这些函数 (http://docs.rexamine.com/R-man/stringi/stri_opts_collator.html) 的末尾将其他参数传递给正在创建的整理器,这将影响将如何执行比较。

    stri_cmp_lt("WV", "WY", locale="lt_LT")
    stri_cmp_lt("WV", "WY", locale="en_US")
    stri_compare("WV", "WV", locale="en_US", strength='1')
    

    例如,上面的 'strength' 参数设置所谓的 'collat​​ion level' (http://unicode.org/reports/tr10/#Notation)。区域设置由此处指定的语言和国家/地区代码 (http://userguide.icu-project.org/locale) 指定。您可以使用这些函数来实现自定义排序函数(例如使用这些函数进行比较的快速排序),因为内置函数似乎没有提供任何更改排序谓词的方法。

    更新 2:或者,甚至比实现自己的排序更好,只需使用 stri_sort 函数,它允许您指定自定义 ICU 整理器 (http://docs.rexamine.com/R-man/stringi/stri_order.html),如下所示:

    stri_sort(state.abb, locale="en_US")
    stri_sort(state.abb, locale="lt_LT")
    
    [1] "AK" "AL" "AR" "AZ" "CA" "CO" "CT" "DE" "FL" "GA" "HI" "IA" "ID" "IL" "IN"
    [16] "KS" "KY" "LA" "MA" "MD" "ME" "MI" "MN" "MO" "MS" "MT" "NC" "ND" "NE" "NH"
    [31] "NJ" "NM" "NV" "NY" "OH" "OK" "OR" "PA" "RI" "SC" "SD" "TN" "TX" "UT" "VA"
    [46] "VT" "WA" "WI" "WV" "WY"
     [1] "AK" "AL" "AR" "AZ" "CA" "CO" "CT" "DE" "FL" "GA" "HI" "IA" "ID" "IL" "IN"
    [16] "KY" "KS" "LA" "MA" "MD" "ME" "MI" "MN" "MO" "MS" "MT" "NC" "ND" "NE" "NH"
    [31] "NY" "NJ" "NM" "NV" "OH" "OK" "OR" "PA" "RI" "SC" "SD" "TN" "TX" "UT" "VA"
    [46] "VT" "WA" "WI" "WY" "WV"
    

    请注意,WV 和 WY 现在在不同的语言环境中处于不同的位置。

    【讨论】:

    • 这更像是一篇观点文章,而不是问题的答案;唯一直接解决问题的部分是你的最后一句话,这不是一个答案。您能否扩展最后一句话以给出一些实际示例(例如,如上面@hrbrmstr 的评论中的那样)? (我认为如果评论的其余部分伴随一个答案......)
    • @BenBolker 这更像是“如何处理”部分的指针,但我将尝试举一个与美国各州相关的示例。 Unicode 标准非常庞大,因此需要大量阅读才能真正理解为什么没有“真正”的方法来对给定的字符串序列进行排序。
    最近更新 更多