获取矩阵最小元素的行和列名称

52

我需要获取矩阵中最小元素的行和列名

> mat = matrix(data=runif(12), nrow = 4, ncol=4)
> rownames(mat) = colnames(mat) = letters[1:4]
> 
> mat
  a         b         c         d
a 0.3167865 0.6958895 0.4233572 0.3167865
b 0.1042599 0.1552235 0.8461520 0.1552235
c 0.6286461 0.9749868 0.2390978 0.6286461
d 0.5923721 0.7823673 0.8427426 0.5923721
> min = min(mat)
> min
> 0.1042599
在这个例子中,我想要获取 "a" 和 "b"。

另外:嵌套的for循环不可行,因为我想将其应用于许多巨大的矩阵(维度 > 100)。 - Sebastian
2个回答

57
> inds = which(mat == min(mat), arr.ind=TRUE)
> inds
  row col
a   1   2
> rnames = rownames(mat)[inds[,1]]
> cnames = colnames(mat)[inds[,2]]

这将为您提供每个等于最小值的条目的行/列名称;如果您只想要第一个,您可以仅检查inds [1,1]和inds [1,2]。


24
你也可以执行inds <- arrayInd(which.min(mat), dim(mat))。这样可以避免分配==操作的结果,并且保证只有一行。 - Jonathan Chang
是的,我知道有一些东西可以在一行中完成...对我来说不清楚是否通常需要所有匹配项还是只需要第一个,所以我想最好两者都呈现出来。 - bnaul
1
如果在“矩阵”中存在缺失观测值,请记得在“min”语句中指定“, na.rm = TRUE”。 - Mark Miller

0

当存在多个最小值时,前两种选项只返回第一个最小值的行和列索引,但后两种选项则返回所有最小值的行和列索引:

set.seed(0)
m=matrix(round(runif(1e6,0,1e5)),1e3)

b=microbenchmark(times=100,
  arrayInd(which.min(m),dim(m)),
  {w=which.min(m);c((w-1)%%nrow(m),(w-1)%/%nrow(m))+1},
  which(m==min(m),arr.ind=T),
  {w=which(m==min(m));cbind((w-1)%%nrow(m),(w-1)%/%nrow(m))+1}
)

a=aggregate(b$time,list(gsub(" ","",gsub("     ",";",gsub("\\{    ","{",b$expr)))),median)
a=a[order(a[,2]),]
writeLines(paste(sprintf("%.3f",a[,2]/min(a[,2])),gsub(" ","",a[,1])))

结果:

1.000 arrayInd(which.min(m),dim(m))
1.002 {w=which.min(m);c((w-1)%%nrow(m),(w-1)%/%nrow(m))+1}
3.183 {w=which(m==min(m));cbind((w-1)%%nrow(m),(w-1)w%/%nrow(m))+1}
3.183 which(m==min(m),arr.ind=T)

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