使用`which()`获取匹配项的行列索引

43

假设我有一个矩阵,例如:

m = matrix(rep(c(0, 0, 1), 4), nrow = 4)
m
     [,1] [,2] [,3]
[1,]    0    0    1
[2,]    0    1    0
[3,]    1    0    0
[4,]    0    0    1

如果我运行which命令,会得到一系列常规索引:

> which(m == 1)
[1]  3  6  9 12

我想要类似于矩阵索引的东西 - 每个索引包含行和列的编号:

     [,1] [,2]
[1,]    3    1
[2,]    2    2
[3,]    1    3
[4,]    4    3

有没有简单的函数可以做到这一点? 此外,它应该以某种方式包含行名和列名:

> rownames(m) = letters[1:4]
> colnames(m) = letters[5:7]
> m
  e f g
a 0 0 1
b 0 1 0
c 1 0 0
d 0 0 1

但我不知道如何实现,也许像这样

     [,1] [,2] [,3] [,4]
[1,]    3    1    c    e
[2,]    2    2    b    f
[3,]    1    3    a    g
[4,]    4    3    d    g

或者,也可以返回两个向量(分别表示行和列),如下所示:

c b a d
3 2 1 4

e f g g
1 2 3 3

请查看我的旧问题之一:https://dev59.com/bFrUa4cB1Zd3GeqPl6r4 - Nick Sabbe
2个回答

66

对于你的第一个问题,你还需要在which函数中传递arr.ind= TRUE参数:

> which(m == 1, arr.ind = TRUE)
     row col
[1,]   3   1
[2,]   2   2
[3,]   1   3
[4,]   4   3

很酷,谢谢!我之前看了?which的帮助文档,但是它说:“arr.ind logical - should array indices be returned when x is an array?”,这很令人困惑!为什么他们在返回矩阵索引时要提到数组索引呢?(通常情况下,我指的是1D向量的数组) - Tomas
“数组”是更一般的情况,包括带有退化单例维度的“向量”,矩阵(具有2个维度)以及3D、4D等数组 - 在这种意义下没有维度的向量不是1D,并且请记住也有递归向量(列表)。 - mdsumner
@TomasT。一个数组可以有1、2或更多维。矩阵是二维数组的特殊情况。请参见?matrix?array - Andrie
我简直不敢相信我以前从未听说过 arr.ind!我一直使用一些可怕的低效 hack,依赖于对 row()col() 的调用来实现这一点。 - Peter M

7

在矩阵中,您不能混合数字和字母,但在数据框中可以:

> indices <- data.frame(ind= which(m == 1, arr.ind=TRUE))
> indices$rnm <- rownames(m)[indices$ind.row]
> indices$cnm <- colnames(m)[indices$ind.col]
> indices
  ind.row ind.col rnm cnm
c       3       1   c   e
b       2       2   b   f
a       1       3   a   g
d       4       3   d   g

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