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
如果这种行为差异已经众所周知,并且这只是我无知的一个例子,我深表歉意。
当在操作内部使用时data.table,order(..)使用data.table:::forder. 根据data.table 简介:
\n\n\n\n
order()是内部优化的\n
\n- \n
\n
character我们可以在a 框架内的列上使用“-”data.table来按降序排序。- \n
另外,
\norder(...)a的框架内data.table使用data.table内部快速基数阶forder()。这种排序对 R 的改进非常引人注目base::order,以至于 R 项目data.table在 2016 年 R 3.3.0 中采用了该算法作为其默认排序,请参阅?sort和 R 发布新闻。
\n\ndata.table\n( ) 中的基数排序算法和实现
\nforder取代了之前的基数(计数)排序,并为 增加了\n新方法order()。新算法由 Matt Dowle 和 Arun\nSrinivasan 贡献,支持逻辑向量、整数(甚至\n大值)、实数和字符向量。它的性能优于\n所有其他方法,但也有一些注意事项(请参阅 参考资料?sort)。
看到差异的关键是data.table:::forder使用“快速基数顺序”。但如果你看一下?base::order,它有一个论点method=:
\n\n使用的方法:允许部分匹配。默认值 (
\n"auto") 表示"radix"数值向量、整数向量、逻辑向量和元素少于 2^31 的因子。否则,就意味着"shell". 有关方法"shell"、"quick"和的详细信息"radix",请参阅 的帮助sort。
由于您的第二列data.table不是numeric、integer、logical或 之一factor,因此base::order使用"shell"排序方法,会产生不同的结果。
但是,如果我们强制base::order使用method="radix",我们会得到相同的结果。
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\nRun Code Online (Sandbox Code Playgroud)\n您可以使用以下命令影响相同的排序base::order:
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\nRun 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