data.table在设置键时如何对字符串进行排序

jem*_*bfp 10 r data.table

昨天我不得不花一些时间试图在我的代码中找到一个错误,我发现data.table包以一种与base有点不同的方式对字符串进行排序.这是一种正常行为吗?data.table用基order函数重现结果的最有效方法(有哪些好处)是什么?这是一个玩具可重复的例子:

library(data.table)
options(stringsAsFactors = FALSE)

d <- data.frame(cn=c("USA","Ubuntu","Uzbekistan"))
d[order(d$cn),,drop=F]

#          cn
#2     Ubuntu
#1        USA
#3 Uzbekistan

dt <- data.table(d)
setkey(dt, cn)
dt

#           cn
#1:        USA
#2:     Ubuntu
#3: Uzbekistan

options(stringsAsFactors = default.stringsAsFactors())
Run Code Online (Sandbox Code Playgroud)

操作系统Windows 7

Aru*_*run 10

2014年3月更新

对此有一些争论.从v1.9.2开始,我们现在已经解决了setkey使用C语言环境进行排序的问题; 例如,所有大写字母都在所有小写字母之前,而不管用户的语言环境如何.这是在v1.8.8中做出的改变,我们原本打算改变,但现在仍然坚持.

考虑save()在您的语言环境中使用键控表和同事 - load()在不同的语言环境中使用它.当他们加入该表时,如果它是区域设置排序顺序,它可能不再正常工作.我们必须更仔细地思考是否setkey允许再次进行区域设置排序,可能是通过将区域设置名称与"sorted"属性一起保存,因此data.table至少可以比较和检测当前区域设置是否与运行的区域设置不同setkey.

这也是出于速度原因,因为根据区域设置进行排序比C语言环境慢得多.虽然,我们可以尽可能高效地完成它,并允许它可选地是理想的.

因此,现在这是一个功能请求,非常欢迎进一步的评论.

FR#4842 setkey使用会话的语言环境而不是C语言环境进行排序



好抓!该调用setkey依次调用setkeyv并调用fastorder"命令"依次调用的列/条目chorder.

chorder反过来调用C函数Ccountingcharacter.c.现在,我想这个问题是由于"语言环境"造成的.

让我们看看我的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"
Run Code Online (Sandbox Code Playgroud)

现在让我们看看order它是如何排序的:

x <- c("USA", "Ubuntu", "Uzbekistan")
order(x)
# [1] 2 1 3
Run Code Online (Sandbox Code Playgroud)

现在,让我们将"语言环境"更改为"C".

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

order(x)
# [1] 1 2 3
Run Code Online (Sandbox Code Playgroud)

来自?order:

字符向量的排序顺序取决于正在使用的语言环境的整理顺序:请参阅Comparison.

来自?Comparison:

字符向量中字符串的比较是使用正在使用的语言环境的整理顺序在字符串中进行词典编写:请参阅语言环境.诸如en_US的语言环境的整理顺序通常不同于C(应该使用ASCII)并且可能令人惊讶.谨防对整理顺序做出任何假设:例如,在爱沙尼亚语Z中介于S和T之间,并且整理不一定是逐个字符 - 在丹麦语中作为单个字母排序,在z之后....

所以,基本上,order在"C"语言环境下,给出与data.tables 相同的顺序setkey.我的猜测是调用的C函数chorder自动在C语言环境中运行,它将比较"S"在"b"之前的ascii值.

把这个带到@ MatthewDowle的注意力可能很重要(如果他还没有意识到的话).所以,我建议您在此处将此文件作为错误提交(只是为了确定).