123 lines
3.1 KiB
R
Executable File
123 lines
3.1 KiB
R
Executable File
#' ---
|
|
#' title: "Criar uma coluna com caracteres indicando qual célula em três colunas da tabela apresenta maior valor"
|
|
#' date: "2021-11-13"
|
|
#' author: "José https://ajuda.multifarm.top"
|
|
#' output:
|
|
#' html_document:
|
|
#' code_folding: show
|
|
#' toc: yes
|
|
#' toc_float:
|
|
#' smooth_scroll: true
|
|
#' df_print: paged
|
|
#' highlight: zenburn
|
|
#' ---
|
|
|
|
#' 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
|
|
#'
|
|
df <- data.frame(a = runif(10),
|
|
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"...
|
|
|
|
a_maior <- with(df, a > b & a > c)
|
|
|
|
b_maior <- with(df, b > a & b > c)
|
|
|
|
c_maior <- with(df, c > a & c > b)
|
|
|
|
#' ### Criar uma coluna na tabela com valores de cero em todas as linhas
|
|
|
|
df$maior <- 0
|
|
|
|
#' ### 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"
|
|
|
|
df$maior[a_maior] <- "a"
|
|
|
|
df$maior[b_maior] <- "b"
|
|
|
|
df$maior[c_maior] <- "c"
|
|
|
|
#' ### Criar uma função simples para executar a tarefa
|
|
|
|
maior_valor <- function (df, a, b, c, ...) {
|
|
|
|
a_maior <- with(df, a > b & a > c)
|
|
b_maior <- with(df, b > a & b > c)
|
|
c_maior <- with(df, c > a & c > b)
|
|
|
|
linhas <- nrow(df)
|
|
coluna <- rep(0, times = linhas)
|
|
|
|
coluna[a_maior] <- names(df)[[1]]
|
|
coluna[b_maior] <- names(df)[[2]]
|
|
coluna[c_maior] <- names(df)[[3]]
|
|
|
|
df$V1 <- coluna
|
|
|
|
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)
|
|
|
|
dfd <- tibble(p_col = runif(10),
|
|
s_col = runif(10),
|
|
t_col = runif(10))
|
|
|
|
#' A função *rowwise* aplica a função *which.max* em todas as linhas. *case_when* é usada 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(
|
|
m == 1 ~ names(.)[1],
|
|
m == 2 ~ names(.)[2],
|
|
m == 3 ~ names(.)[3],
|
|
TRUE ~ as.character(m)
|
|
))
|
|
|
|
#' ## Usando o pacote "datatable"
|
|
|
|
library(data.table)
|
|
|
|
class(df)
|
|
|
|
dt <- setDT(df)
|
|
|
|
#' Using "apply" to know the greatest value by each row ("1") across
|
|
#' columns
|
|
|
|
dt[, great := apply(df, 1, which.max)
|
|
][, great := as.character(great)
|
|
][, great := c("1" = "a",
|
|
"2" = "b",
|
|
"3" = "c")[great]]
|