Bom dia pessoal,
Tenho um data.frame com várias colunas e gostaria de ordenar os valores de cada uma delas de forma decrescente e recuperar apenas os maiores valores de cada. Como são muitas colunas, resolvi fazer através de um for, mas o arrange não está funcionando. Para ordenar eu utilizo o iterador (que no caso é o nome das minhas colunas) e acredito que aí que está o problema. Quando rodo fora do for, fornecendo o nome da coluna (sem as aspas " ") ele ordena de forma correta. O que posso fazer para conseguir fazer funcionar dentro do for?
Segue um exemplo reprodutível:
library(tidyverse)
df <- data.frame (tc_i_br_a4 = c(0.00501, 0.00458, 0.16035, 0.37084),
tc_ii_yc6 = c(0.00343, 0.00699, 0.01166, 0.24595),
tc_vi_clb = c(0.00316, 0.00780, 0.27390, 0.00152))
list <- vector(mode = "list")
i = 1
for (i in 1:ncol(df)) {
temp <- df %>% select(i) %>% arrange(desc(i)) %>% head(3)
list <- c(list, temp)
}
#> Note: Using an external vector in selections is ambiguous.
#> i Use `all_of(i)` instead of `i` to silence this message.
#> i See <https://tidyselect.r-lib.org/reference/faq-external-vector.html>.
#> This message is displayed once per session.
#> Note: Using an external vector in selections is ambiguous.
#> i Use `all_of(i)` instead of `i` to silence this message.
#> i See <https://tidyselect.r-lib.org/reference/faq-external-vector.html>.
#> This message is displayed once per session.
list
#> $tc_i_br_a4
#> [1] 0.00501 0.00458 0.16035
#>
#> $tc_ii_yc6
#> [1] 0.00343 0.00699 0.01166
#>
#> $tc_vi_clb
#> [1] 0.00316 0.00780 0.27390
#> $tc_i_br_a4
#> [1] 0.00501 0.00458 0.16035
#>
#> $tc_ii_yc6
#> [1] 0.00343 0.00699 0.01166
#>
#> $tc_vi_clb
#> [1] 0.00316 0.00780 0.27390
O @hal-delaserna já deu uma resposta que parece resolver o problema, mas, como você está usando o tidyverse, vou deixar aqui uma alternativa só por completude.
O seu código na verdade tem 2 problemas:
No geral, o tidyverse não funciona bem com números de colunas. Basta ver o quanto o select() está reclamando por você ter usado um número de coluna dentro dele… O tidyverse foi criado pensando em nomes e por isso precisamos avisar quando estivermos indexando de outra forma. No select() precisaríamos escrever select(all_of(i)) (como sugerido pelo alerta), mas no arrange() seria arrange(desc(across(i))). Para saber mais sobre o across(), dê uma olhada no nosso livro: 7.2 O pacote dplyr | Ciência de Dados em R.
Como você começa o seu loop selecionando a i-ésima coluna, não faz sentido você ordenar a própria i-ésima; você precisa ordenar a primeira coluna (a única coluna, no caso).
Abaixo segue minha versão do código com o mínimo possível de alterações:
Acho que o programa abaixo fica até mais fácil de entender! O map(), neste caso, vai aplicar uma função em cada coluna (primeiro sort(decreasing = TRUE) e depois head(3)), retornando sempre uma lista com os resultados.