我有一个矩阵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
出了问题,我似乎无法弄清楚。
我也愿意接受更有效的解决方案,因为我正在处理更大的矩阵,其中很多都是这样。
感谢您的帮助!
答案 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)
将apply
与ifelse
一起使用的另一种基本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