使用`sort`函数的`index.return = TRUE`参数,与使用`order`函数相比,有何优势?

5

sort 函数有一个默认为 FALSE 的参数 index.return。如果你将其设置为 TRUE,你将得到排序后的索引... 与使用 order 函数基本相同。

我的问题
是否存在使用 sort 函数并设置 index.return = TRUE 而不是使用 order 函数的情况?


3
对于非整数输入,sort函数调用x[order(x, na.last = na.last, decreasing = decreasing)]。FWIW即“仅供参考”。 - hrbrmstr
2个回答

6

order 只返回索引,而 sort 也返回值(如果加上 index.return=T 则返回一个列表):

x <- runif(10, 0, 100)
order(x)
# [1]  2  7  1  9  6  5  8 10  4  3
sort(x, index.return=T)
# $`x`
# [1] 0.08140348 0.18272011 0.23575252 0.51493537 0.64281259 0.92121388 0.93759670 0.96221375 0.97646916 0.97863369
# 
# $ix
# [1]  2  7  1  9  6  5  8 10  4  3

看起来,order在处理大数字(较长的向量大小)时速度略快:

x <- runif(10000000, 0, 100)

microbenchmark::microbenchmark(
  sort = {sort(x, index.return=T)},
  order = {x[order(x)]},
  times = 100
)
# Unit: milliseconds
# expr      min       lq     mean   median       uq      max neval
# sort 63.48221 67.79530 78.33724 70.74215 74.10109 173.1129   100
# order 56.46055 57.18649 60.88239 58.29462 62.13086 155.5481   100

所以,如果你需要返回一个list对象,可能只有在index.return = TRUE的情况下选择sort才是最好的选择。我找不到sort比其他方法更好的例子。

1
请澄清一下,您所说的“大数字”是指使用排序向量时order速度更快的大量数字,而不是指数字本身大小对速度的影响,是这样吗? - camille
是的,我指的是更长的向量大小。我检查了一下,似乎即使使用更大的数字,速度仍然会稍微快一些。如果您使用runif(10000000, 0, 100)runif(10000000, 0, 10000),它并不会有太大变化。 - RLave
有时候 sort(x, method-"quick", ...) 更快,所以你也可以尝试使用这些参数进行测试。不错的答案。 - Manos Papadakis

1
我的建议基于RLave的答案。
你可以使用参数methodsort(x,method="quick",index.return=TRUE),这个函数可能比默认的快一点。另外,如果你想要一个更快(对于大向量)的替代方法,你可以使用这个函数:
sort_order <- function(x){
    indices <- order(x) #you can choose a method also but leave default.
    list("x"=x[indices],"ix"=indices)
}

这里是一些基准测试。
microbenchmark::microbenchmark(
     sort=s<-sort(x,index.return=T),
     "quick sort"=sq<-sort(x,method="quick",index.return=T),
     "order sort"=so<-sort_order(x),times = 10
     times=10
)

Unit: seconds
         expr      min       lq     mean   median       uq      max neval
         sort 1.493714 1.662791 1.737854 1.708502 1.887993 1.960912    10
   quick sort 1.366938 1.374874 1.451778 1.444342 1.480122 1.668693    10
   order sort 1.181974 1.344398 1.359209 1.369108 1.424569 1.461862    10

all.equal(so,sq)
[1] TRUE
all.equal(s,so)
[1] TRUE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接