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

时间:2018-08-27 00:38:17

标签: r

我有一个矩阵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)]

“ whos_2nd”行中的apply出了问题,我似乎无法弄清楚。

我也愿意接受更有效的解决方案,因为我正在处理更大的矩阵,其中很多都是这样。

感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

您可以一次致电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

答案 1 :(得分:2)

applyifelse一起使用的另一种基本R可能性

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