用相等的数字为DF中的每一行查找唯一的最大值



我有一个数据帧,看起来像这样:

A <- rep(1, times = 3)
B <- 1:3
C <- c(1,3,2)
DF <- data.frame(A,B,C)

哪个制造商:

> DF
A B C
1 1 1 1
2 1 2 3
3 1 3 2

我想创建一个新列,指示可以在其中找到每行最大值的列名,但前提是它们是唯一的,否则我想给它一个NA.

我尝试过各种选项,但是,例如,这个选项总是使用值所在的第一个列名作为max:

DF$max <- colnames(DF)[max.col(DF, ties.method = "first")]

重新整合:

A C B

我想要

NA C B

您可以使用rowSums计算每行中最大值的数量,如果大于1,则将输出转换为NA

col <- colnames(DF)[max.col(DF)]
col[rowSums(DF == do.call(pmax, DF)) > 1] <- NA
DF$max <- col
DF
#  A B C  max
#1 1 1 1 <NA>
#2 1 2 3    C
#3 1 3 2    B

您可以测试ties.method = "first"的结果是否等于使用ties.method = "last"时的结果。

i <- max.col(DF, ties.method = "first")
j <- max.col(DF, ties.method = "last")
DF$max <- colnames(DF)[i]
DF$max[i != j] <- NA
DF
#  A B C  max
#1 1 1 1 <NA>
#2 1 2 3    C
#3 1 3 2    B

我们也可以将pmap用于此目的:

library(dplyr)
library(purrr)
DF %>%
mutate(Max = pmap_chr(DF, ~ {
x <- c(...)
if(sum(x == max(x, na.rm = TRUE)) > 1) {
NA_character_
} else {
names(DF)[which(x == max(x, na.rm = TRUE))]
}
}
))
A B C  Max
1 1 1 1 <NA>
2 1 2 3    C
3 1 3 2    B

我们可以使用

DF$max <-  names(DF)[max.col(DF, "first")*NA^(rowSums(DF == do.call(pmax, DF)) > 1)]
DF$max
[1] NA  "C" "B"

最新更新