查找行方式最小值和返回值及其对应的列名称

Ste*_*pré 4 r

考虑以下矩阵m:

    ca bsa rd zaa
ada  3   4  3   2
aca  1   4  5   2
ara  3   4  3   2
ava  3   4  5   2
Run Code Online (Sandbox Code Playgroud)

我试图为每一行找到最小值并以下列形式返回data.frame:

    q   s d
1 ada zaa 2
2 aca  ca 1
3 ara zaa 2
4 ava zaa 2
Run Code Online (Sandbox Code Playgroud)

现在我正在做:

res <- t(sapply(seq(nrow(m)), function(i) {
  j <- which.min(m[i,])
  c(q = rownames(m)[i],
    s = colnames(m)[j],
    d = m[i,j])}))

res <- data.frame(res)
res$d <- as.numeric(res$d)
Run Code Online (Sandbox Code Playgroud)

我正在寻找一种更好的方法来构建它.

构建res使用c()(将所有组件强制转换为相同类型)然后将其转换为data.frame并最终更改d为数字以获得以下结构感觉效率相当低:

'data.frame':   4 obs. of  3 variables:
 $ q: Factor w/ 4 levels "aca","ada","ara",..: 2 1 3 4
 $ s: Factor w/ 2 levels "ca","zaa": 2 1 2 2
 $ d: num  2 1 2 2 
Run Code Online (Sandbox Code Playgroud)

我还需要处理可能存在多个最小值的情况


数据

m <- structure(c(3, 1, 3, 3, 4, 4, 4, 4, 3, 5, 3, 5, 2, 2, 2, 2), .Dim = c(4L, 
4L), .Dimnames = list(c("ada", "aca", "ara", "ava"), c("ca", "bsa", "rd", "zaa")))
Run Code Online (Sandbox Code Playgroud)

Hen*_*rik 5

您可以通过使用max.col矩阵的否定版本找到每行的最小值的列索引.

col_id <- max.col(-m)
data.frame(q = rownames(m), s = colnames(m)[col_id],
           d = m[cbind(1:length(col_id), col_id)])
#     q   s d
# 1 ada zaa 2
# 2 aca  ca 1
# 3 ara zaa 2
# 4 ava zaa 2
Run Code Online (Sandbox Code Playgroud)

  • 和往常一样,请注意`max.col`默认情况下有`ties.method ="random"`,所以如果你有多个最小值,结果每次都会改变.考虑一下`ties.method ="first"`这类似于`which.max`的逻辑. (3认同)