Criar uma coluna com caracteres indicando qual célula em três colunas da tabela apresenta maior valor
José
2021-11-13
Remover objetos
rm(list = ls())
Pergunta
Pergunta do grupo R-brasil no Telegram
Quero criar a coluna “maior” com o nome da coluna que tem o maior valor na linha
Solução usando R base
Criar uma tabela com três colunas de tipo numérico com valores entre 0 a 1
A função runif cria 10 valores entre 0 a 1 se os valores máximo e mínimo não são definidos dentro do parêntese
<- data.frame(a = runif(10),
df b = runif(10),
c = runif(10))
Criar vectores definindo a condição lógica esperada em cada caso
Se a coluna “a” apresentar o maior valor, então o vector “a_maior” terá um elemento “TRUE”, do contrário, o elemento será “FALSE”…
<- with(df, a > b & a > c)
a_maior
<- with(df, b > a & b > c)
b_maior
<- with(df, c > a & c > b) c_maior
Criar uma coluna na tabela com valores de cero em todas as linhas
$maior <- 0 df
Indexar um caractere dentro da coluna “maior” indicando a coluna que apresentou o maior valor em cada linha da tabela
Inserir “a” na posição em que a coluna “a” apresentou o maior valor; ou seja: quando a condição lógica foi igual a “TRUE”
$maior[a_maior] <- "a"
df
$maior[b_maior] <- "b"
df
$maior[c_maior] <- "c" df
Criar uma função simples para executar a tarefa
<- function (df, a, b, c, ...) {
maior_valor
<- with(df, a > b & a > c)
a_maior <- with(df, b > a & b > c)
b_maior <- with(df, c > a & c > b)
c_maior
<- nrow(df)
linhas <- rep(0, times = linhas)
coluna
<- "a"
coluna[a_maior] <- "b"
coluna[b_maior] <- "c"
coluna[c_maior]
$V1 <- coluna
df
return(df)
}
A coluna “maior” é o resultado de indexar com a primeira parte do’ código e a coluna “V1” resulta de aplicar a função na tabela
maior_valor(df, a, b, c)
Usando o pacote dplyr
library(dplyr)
<- tibble(p_col = runif(10),
dfd s_col = runif(10),
t_col = runif(10))
A função rowwise aplica a função which.max em todas as linhas. case_when é usado para substituir o número da coluna pelo nome
%>%
dfd rowwise() %>%
mutate(m = which.max(c(p_col, s_col, t_col)),
m = case_when(
== 1 ~ names(.)[1],
m == 2 ~ names(.)[2],
m == 3 ~ names(.)[3],
m TRUE ~ as.character(m)
))