按行查找矩阵或数据框的最小值(排序)

Posted

技术标签:

【中文标题】按行查找矩阵或数据框的最小值(排序)【英文标题】:Rowwise finding the lowest values of a matrix or a data frame (ordering) 【发布时间】:2015-05-21 13:29:34 【问题描述】:

目标:从矩阵或数据框中找到每一行的最低 n 值。对于此示例,我们希望找到每行的 3 个最低值。我们想用

返回一个矩阵
rowname | colname_min | value_min | colname_min2 | value_min2 | colname_min3 | value_min3

出发点:我修改了这个问题的答案:R getting the minimum value for each row in a matrix, and returning the row and column name

这是我修改后的代码:

    df<-data.frame(matrix(data=round(x=rnorm(100,10,1),digits=3),nrow=10),
               row.names=c("A","B","C","D","E","F","G","H","I","J"))
    colnames(df)<-c("AD","BD","CD","DD","ED","FD","GD","HD","ID","JD")

   result <- t(sapply(seq(nrow(df)), function(i) 
  j <- apply(df, 1, function(x)order(x, decreasing=F)[1:3])
  c(rownames(df)[i], colnames(df)[j[1,i]], as.numeric(df[i,j[1,i]]),
    colnames(df)[j[2,i]], as.numeric(df[i,j[2,i]]),
    colnames(df)[j[3,i]], as.numeric(df[i,j[3,i]]))
))

这是有效的,并且对于小示例 data.frame 也可以正常工作。但是,我正在使用的 data.frame 有 200,000 行和 300 列。在我的机器上,代码现在运行了约 1 小时并且仍在工作。任何想法如何优化代码?我在想dplyr,但找不到解决方案。非常感谢您的帮助。

【问题讨论】:

【参考方案1】:

您可以使用此基本 R 解决方案,它对每一行进行排序并选择 n.min 最低值及其索引:

样本数据

N <- 5
n.min <- 2

set.seed(1)
m <- matrix(runif(N^2),N)
rownames(m) <- letters[1:N]
colnames(m) <- LETTERS[1:N]

#           A          B         C         D         E
# a 0.2655087 0.89838968 0.2059746 0.4976992 0.9347052
# b 0.3721239 0.94467527 0.1765568 0.7176185 0.2121425
# c 0.5728534 0.66079779 0.6870228 0.9919061 0.6516738
# d 0.9082078 0.62911404 0.3841037 0.3800352 0.1255551
# e 0.2016819 0.06178627 0.7698414 0.7774452 0.2672207

代码

f <- function(rw) 
  O <- order(rw)[1:n.min]
  rbind(O,rw[O])


result <- t(apply(m,1,f))

样本数据的输出

#   [,1]       [,2] [,3]      [,4]
# a    3 0.20597457    1 0.2655087
# b    3 0.17655675    5 0.2121425
# c    1 0.57285336    5 0.6516738
# d    5 0.12555510    4 0.3800352
# e    2 0.06178627    1 0.2016819

更新

如果您想用列名替换列号,您还可以这样做:

d <- as.data.frame(result)
d[,c(T,F)] <- colnames(m)[unlist(d[,c(T,F)])]

请注意,这样可以避免将数字强制转换为字符串以及随后向后转换为数字格式,这对于大型数据集来说可能代价高昂。

【讨论】:

性能非常好。我不确定是否可以使用 dplyr 对其进行改进。谢谢。

以上是关于按行查找矩阵或数据框的最小值(排序)的主要内容,如果未能解决你的问题,请参考以下文章

R:按此顺序对我的数据框的最小值进行排序

查找特定列中的最小值和矩阵中相应的行号

matlab如何不用max和min找出矩阵内的最大值和最小值

在矩阵中查找最小值的索引

二分查找4寻找旋转排序数组中的最小值 II(hard)

二分查找4寻找旋转排序数组中的最小值 II(hard)