order() 的结果应用于 data.frame 与 data.table 时有所不同

Bob*_*Bob 4 sorting r radix-sort dataframe data.table

order()如果我使用indata.frame和,我会得到不同的结果data.table。例如:

A <- data.frame(one = c("k"), two = c("3_28","31_60","48_68"))
B <- as.data.table(A)

A[order(A$one,A$two), ]
#   one   two
# 1   k  3_28
# 2   k 31_60
# 3   k 48_68


B[order(B$one, B$two), ]
#    one   two
# 1:   k 31_60
# 2:   k  3_28
# 3:   k 48_68
Run Code Online (Sandbox Code Playgroud)

我必须承认这有点令人震惊,因为多年来我一直假设order()结果data.frame相同data.table。我想我需要检查很多代码!

有什么方法可以确保和order()给出相同的结果吗?data.framedata.table

如果这种行为差异已经众所周知,并且这只是我无知的一个例子,我深表歉意。

r2e*_*ans 7

当在操作内部使用时data.tableorder(..)使用data.table:::forder. 根据data.table 简介

\n
\n

order()是内部优化的

\n
    \n
  • character我们可以在a 框架内的列上使用“-”data.table来按降序排序。

    \n
  • \n
  • 另外,order(...)a的框架内data.table使用data.table内部快速基数阶forder()。这种排序对 R 的改进非常引人注目base::order,以至于 R 项目data.table在 2016 年 R 3.3.0 中采用了该算法作为其默认排序,请参阅?sort和 R 发布新闻。

    \n
  • \n
\n
\n

来自R News,R 3.3.0 的变化,新功能:

\n
\n

data.table\n( ) 中的基数排序算法和实现forder取代了之前的基数(计数)排序,并为 增加了\n新方法order()。新算法由 Matt Dowle 和 Arun\nSrinivasan 贡献,支持逻辑向量、整数(甚至\n大值)、实数和字符向量。它的性能优于\n所有其他方法,但也有一些注意事项(请参阅 参考资料?sort)。

\n
\n

看到差异的关键是data.table:::forder使用“快速基数顺序”。但如果你看一下?base::order,它有一个论点method=

\n
\n

使用的方法:允许部分匹配。默认值 ( "auto") 表示"radix"数值向量、整数向量、逻辑向量和元素少于 2^31 的因子。否则,就意味着"shell". 有关方法"shell""quick"和的详细信息"radix",请参阅 的帮助sort

\n
\n

由于您的第二列data.table不是numericintegerlogical或 之一factor,因此base::order使用"shell"排序方法,会产生不同的结果。

\n

但是,如果我们强制base::order使用method="radix",我们会得到相同的结果。

\n
order(A$two)\n# [1] 1 2 3\norder(A$two, method="radix")\n# [1] 2 1 3\n\nA[order(A$one, A$two, method = "radix"),]\n#   one   two\n# 2   k 31_60\n# 1   k  3_28\n# 3   k 48_68\n
Run Code Online (Sandbox Code Playgroud)\n

您可以使用以下命令影响相同的排序base::order

\n
B[base::order(B$one,B$two),]\n#       one    two\n#    <char> <char>\n# 1:      k   3_28\n# 2:      k  31_60\n# 3:      k  48_68\n
Run Code Online (Sandbox Code Playgroud)\n

添加注释:除 之外的所有method=选项都base::order取决于区域设置method="radix",然后它会data.table::order更接近地模仿。从?base::order

\n
\n

除了方法 \xe2\x80\x98"radix"\xe2\x80\x99 之外,字符向量的排序顺序\n将取决于所使用的语言环境的整理顺序...

\n
\n