提问人:Hack-R 提问时间:6/3/2014 最后编辑:Paulo E. CardosoHack-R 更新时间:6/3/2014 访问量:6004
在 R 中对未正确排序的数字进行排序
Sort not sorting numbers correctly in R
问:
我有如下所示的数据:
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” 作为选项,但顺序仍然没有意义。
答:
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.df
temp
temp[, 1]
temp
temp.df
temp
temp
temp.df
2赞
Greg Snow
6/3/2014
#2
有几个问题,其中一些已经在评论中讨论过,但我还没有看到提到的一个大问题是该函数在矩阵上工作,因此在执行任何其他操作之前将数据帧转换为矩阵。由于数据同时具有因子和数值变量,因此数字将转换为字符串,并且排序是在字符串表示形式上完成的,而不是在数值上完成的。使用直接处理数据框(和列表)的工具将防止这种情况,以及使用和完全避免这种情况。apply
order
apply
此外,如果您只想要 $n$ 最大值或最小值,那么您可以通过使用而不是顺序和指定参数来加快速度。sort.list
partial
评论
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:4
sort.list
sort
评论
sort
对向量进行排序。因为你想按另一个向量对一个向量进行排序,所以你想要 .而且您不必求助于:在该链接上还有其他方法可以做到这一点。order
plyr