代码之家  ›  专栏  ›  技术社区  ›  DanY

涉及第一和第二大值行的矩阵转换

r
  •  1
  • DanY  · 技术社区  · 8 年前

    我有一个矩阵 mat :

    #sample data
    set.seed(123)
    mat <- t(sapply(1:5, function(x) round(sample(10:30, 6))))
    
    mat
    16   25   17   29   27   10
    21   27   20   18   26   17
    24   21   11   26   14   10
    16   29   26   22   20   25
    23   24   20   28   14   12
    

    我想用该行的最大值替换每一行(这很容易),但我也想用该行的第二大值替换最大行的值(这不太容易)。我想要的结果是:

    res
    29   29   29   27   29   29
    27   26   27   27   27   27 
    26   26   26   24   26   26
    29   26   29   29   29   29
    28   28   28   24   28   28
    

    例如,29是第1行中的最大值,它出现在位置4;第二大值是27。所以我想要一排29号,在4号位置有27号。然后当然要对所有行执行此操作。

    我的尝试:

    # the easy part
    res <- matrix(apply(mat, 1, max), nrow=nrow(mat), ncol=ncol(mat))
    
    # my attempt at the hard part
    to_replace <- apply(mat, 1, which.max)
    whos_2nd <- apply(mat, 1, function(x) which(order(x, decreasing = TRUE) == 2))
    
    res[cbind(1:nrow(mat), to_replace)] <- mat[cbind(1:nrow(mat), whos_2nd)]
    

    有点不对劲 apply 在“谁第二行”里,我好像想不通。

    我对一个更有效的解决方案也很开放,因为我处理的是更大的矩阵,还有很多矩阵。

    谢谢你的帮助!

    2 回复  |  直到 8 年前
        1
  •  2
  •   Maurits Evers    8 年前

    使用另一个基R的可能性 apply 具有 ifelse

    t(apply(mat, 1, function(x) ifelse(x == max(x), sort(unique(x), decr = T)[2], max(x))))
    #     [,1] [,2] [,3] [,4] [,5] [,6]
    #[1,]   29   29   29   27   29   29
    #[2,]   27   26   27   27   27   27
    #[3,]   26   26   26   24   26   26
    #[4,]   29   26   29   29   29   29
    #[5,]   28   28   28   24   28   28
    
        2
  •  2
  •   Weihuang Wong    8 年前

    你可以在一个电话里 apply :

    t(apply(mat, MAR = 1, function(x){
      max_index <- which.max(x)
      max_value <- max(x)
      sec_value <- sort(unique(x), decreasing = TRUE)[2]
      x <- replace(x, TRUE, max_value)
      x[max_index] <- sec_value
      x
    }))
    #      [,1] [,2] [,3] [,4] [,5] [,6]
    # [1,]   29   29   29   27   29   29
    # [2,]   27   26   27   27   27   27
    # [3,]   26   26   26   24   26   26
    # [4,]   29   26   29   29   29   29
    # [5,]   28   28   28   24   28   28