按顺序查找向量中前n个元素的索引[R]

3

我有一个数值类型的矩阵,大小为10000 * 50。现在我想找出每行前五个元素的索引,按其值的顺序排列。例如,样本可能如下:

set.seed(2)
v1 <- matrix(runif(20 , 0 ,20 ) , 2 ,10)
v1
#          [,1]      [,2]     [,3]     [,4]     [,5]      [,6]      [,7]      [,8]      [,9]    [,10]
#[1,]  3.697645 11.466527 18.87679  2.58318  9.36037 11.053481 15.210266  8.105644 19.527970 8.896185
#[2,] 14.047481  3.361038 18.86950 16.66898 10.99967  4.777895  3.616402 17.070969  4.516509 1.499588

然后我希望输出的结果看起来像这样:

#[1,]    9    3    7    2    6
#[2,]    3    8    4    1    5

我只找到了这个问题,它解释了如何找到前n个元素,但并不按值的顺序排列。
2个回答

4

apply()非常适合于矩阵的逐行操作。你可以这样做:

t(apply(v1, 1, function(x) order(-x)[1:5]))
#      [,1] [,2] [,3] [,4] [,5]
# [1,]    9    3    7    2    6
# [2,]    3    8    4    1    5

这段代码按行运行order()函数,针对矩阵v1,然后对每个行取前五个值,并将结果转置,因为你指定的是行而不是列。


2

在将数据融合成“长格式”之后,也可以使用 data.table 进行操作。通过按照 'Var1' 进行分组,我们可以得到 'value' 的 order

library(reshape2)
library(data.table)
setDT(melt(v1))[, head(order(-value),5), Var1]
#    Var1 V1
#1:    1  9
#2:    1  3
#3:    1  7
#4:    1  2
#5:    1  6
#6:    2  3
#7:    2  8
#8:    2  4
#9:    2  1
#10:   2  5

或者使用基本R

ave(-v1, row(v1), FUN = order)[,1:5]
#     [,1] [,2] [,3] [,4] [,5]
#[1,]    9    3    7    2    6
#[2,]    3    8    4    1    5

两种方法都可以,但是它们比 Richard Scriven 建议的答案慢。基本 R 解决方案需要大约多20%的时间,而 data.table 需要多80%的时间。感谢建议。 - Virag Swami
@ViragSwami 感谢您的留言。我本以为 data.table 会很快,但可能是 melt(来自 reshape2)增加了时间。 - akrun

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