在 R 中对未正确排序的数字进行排序

Sort not sorting numbers correctly in R

提问人:Hack-R 提问时间:6/3/2014 最后编辑:Paulo E. CardosoHack-R 更新时间:6/3/2014 访问量:6004

问:

我有如下所示的数据:

    score        temp
1 a.score  0.05502011
2 b.score  0.02484594
3 c.score -0.07183767
4 d.score -0.06932274
5 e.score -0.15512460

我想根据从最消极到最积极的值对相同值进行排序,取前 4 名。我尝试:

> topfour.values <- apply(temp.df, 2, function(xx)head(sort(xx), 4, na.rm = TRUE, decreasing = FALSE))
> topfour.names  <- apply(temp.df, 2, function(xx)head(names(sort(xx)), 4, na.rm = TRUE))
> topfour        <- rbind(topfour.names, topfour.values)

我得到

> topfour.values
                        temp[, 1]                           
    d.score              "-0.06932274"            
    c.score              "-0.0718376680"          
    e.score              "-0.1551246"             
    b.score              " 0.02484594"   

这是什么顺序?我做错了什么,我该如何正确分类?

我尝试了 method == “Quick” 和 method == “Shell” 作为选项,但顺序仍然没有意义。

R 排序

评论

1赞 Ari B. Friedman 6/3/2014
stackoverflow.com/questions/1296646/......
0赞 Hack-R 6/3/2014
谢谢,阿里。不过我只是按一列排序,我真的必须求助于 plyr 吗?排序实际上并没有按任何特定顺序排列吗?
1赞 Ari B. Friedman 6/3/2014
sort对向量进行排序。因为你想按另一个向量对一个向量进行排序,所以你想要 .而且您不必求助于:在该链接上还有其他方法可以做到这一点。orderplyr
0赞 Hack-R 6/3/2014
好的,谢谢。那么在矩阵和数据帧上,排序只是随机行为还是其他什么?感谢您的链接/信息。

答:

3赞 Paulo E. Cardoso 6/3/2014 #1

我相信您获取的数据类型错误。了解如何将数据导入 R 会很有用。在上面的示例中,您处理的是字符向量,而不是数字向量。

head(with(df, df[order(temp), ]), 4)
    score        temp
5 e.score -0.15512460
3 c.score -0.07183767
4 d.score -0.06932274
2 b.score  0.02484594

采用 Greg Snow 提出的方法,并考虑到您只对顶级值的向量感兴趣,并且在这种情况下不可能使用该参数,对比较 order 和 sorl.list 的简单速度测试表明,即使对于 1e7 大小的向量,差异也可能无关紧要。partial

df1 <- data.frame(temp = rnorm(1e+7),
                  score = sample(letters, 1e+7, rep = T))

library(microbenchmark)
microbenchmark(
  head(with(df1, df1[order(temp), 1]), 4),
  head(with(df1, df1[sort.list(temp), 1]), 4),
  head(df1[order(df1$temp), 1], 4),
  head(df1[sort.list(df1$temp), 1], 4),
  times = 1L
  )

Unit: seconds
                                        expr      min       lq   median       uq      max neval
     head(with(df1, df1[order(temp), 1]), 4) 13.42581 13.42581 13.42581 13.42581 13.42581     1
 head(with(df1, df1[sort.list(temp), 1]), 4) 13.80256 13.80256 13.80256 13.80256 13.80256     1
            head(df1[order(df1$temp), 1], 4) 13.88580 13.88580 13.88580 13.88580 13.88580     1
        head(df1[sort.list(df1$temp), 1], 4) 13.13579 13.13579 13.13579 13.13579 13.13579     1

评论

0赞 Hack-R 6/3/2014
谢谢。这太完美了。如果没有人发布更好的答案,我会将其标记为答案(现在标记为答案还为时过早)。顺便问一下,你能澄清一下 df 和 temp 之间的区别吗?在我的示例中,数据帧的名称是 temp.df,它显示的列名是 temp[,1],因为 temp.df 是我命名为 temp 的对象的第一列。
0赞 Hack-R 6/3/2014
在我第一次尝试时,Temp 是一个矩阵,然后我把它变成了一个数据框,得到了相同的结果
0赞 Hack-R 6/3/2014
数据通过 sqlQuery 来自 SQL Server。> 类(temp.df) [1] “data.frame”
0赞 Gregor Thomas 6/3/2014
@NerdLife 你对名字很草率。在上面的评论中,您说您的数据是 ,并且您的帖子显示了一个名为 .同样在您的评论中,您说是一列,这是真的,它是某个可能更大的对象的第一列,但它不能在里面......然后你说是一个矩阵。Ari 指的是我们在你的帖子中看到的那个,它是 data.frame() 中的一列,问题是关于该列的类。temp.dftemptemp[, 1]temptemp.dftemptemptemp.df
2赞 Greg Snow 6/3/2014 #2

有几个问题,其中一些已经在评论中讨论过,但我还没有看到提到的一个大问题是该函数在矩阵上工作,因此在执行任何其他操作之前将数据帧转换为矩阵。由于数据同时具有因子和数值变量,因此数字将转换为字符串,并且排序是在字符串表示形式上完成的,而不是在数值上完成的。使用直接处理数据框(和列表)的工具将防止这种情况,以及使用和完全避免这种情况。applyorderapply

此外,如果您只想要 $n$ 最大值或最小值,那么您可以通过使用而不是顺序和指定参数来加快速度。sort.listpartial

评论

0赞 Paulo E. Cardoso 6/3/2014
sort.list 加速的任何效果对于非常非常大的向量都是明智的,对吧?
0赞 Greg Snow 6/3/2014
@PauloCardoso,在大向量上比在小向量上加速要明显得多。
0赞 Paulo E. Cardoso 6/3/2014
在这种特殊情况下,通过选择 sort.list,部分参数是什么?
1赞 Greg Snow 6/3/2014
@PauloCardoso,要获得前 4 个值(最低值),请使用 .但是我只是尝试了一下,部分参数还没有实现,所以在实现之前,真的没有速度优势。partial 参数适用于 ,但它只对单个向量进行排序,而不是对数据帧等进行排序。partial=1:4sort.listsort