dat[cbind(FALSE, t(apply(dat[,-1], 1, function(z) duplicated(z) & z >= max(z))))] <- NA
dat
# id t1 t2 t3 t4 t5
# 1 1 5 10 11 NA NA
# 2 2 6 7 12 13 16
# 3 3 1 2 NA NA NA
# 4 4 3 3 4 NA NA
细分:
-
由于我们需要按行工作,我们将使用apply(dat, 1, .)。
-
在每一行上,我们需要那些大于或等于最大值的那些 并且 重复,因此使用 anon-func
function(z) duplicated(z) & z >= max(z)
这本身会产生一个转置矩阵(因为 R 的 apply 是如何运作的),然后我们将其 transpose 转换为一个形状正确的逻辑矩阵:
t(apply(dat[,-1], 1, function(z) duplicated(z) & z >= max(z)))
# t1 t2 t3 t4 t5
# [1,] FALSE FALSE FALSE TRUE TRUE
# [2,] FALSE FALSE FALSE FALSE FALSE
# [3,] FALSE FALSE TRUE TRUE TRUE
# [4,] FALSE FALSE FALSE TRUE TRUE
-
我们用dat[,-1] 省略了id 列,但是为了重新分配NA,我们需要cbind(FALSE, .) 以便保留id 列。
-
最后,我们使用 dat[.] <- NA 重新分配给这些字段。
PS:其他答案中使用的替代函数在这里也同样有效:
# equivalent with this sample data
function(z) duplicated(z) & z >= max(z)
function(z) seq_along(z) > which.max(z)
答案的最大差异(到目前为止)是偏爱 R 方言,无论是基本方言还是 dplyr+purrr。
数据
dat <- structure(list(id = 1:4, t1 = c(5L, 6L, 1L, 3L), t2 = c(10L, 7L, 2L, 3L), t3 = c(11L, 12L, NA, 4L), t4 = c(NA, 13L, NA, NA), t5 = c(NA, 16L, NA, NA)), row.names = c(NA, -4L), class = "data.frame")