Selecionar variável de um dataframe baseado em valores de uma lista

Olá pessoal, boa noite.

Eu estou usando uma lista como referência para buscar os nomes das colunas de um dataframe e utilizá-lo em algumas operações, como por exemplo mudar o tipo da variável.

Vou dar um exemplo:

require(tidyverse)
#> Carregando pacotes exigidos: tidyverse

col <- c('nome1', 'nome2')

nome1 <- c(1,2,3)
nome2 <- c('a','b','c')

df = data.frame(nome1, nome2); df
#>   nome1 nome2
#> 1     1     a
#> 2     2     b
#> 3     3     c

> col[1]
[1] "nome1"

Eu gostaria de utilizar o valor dentro do col[1] para acessar a coluna “nome1” do dataframe df e mudar seu tipo, conforme abaixo:

> df %>%
+   mutate(col[1] = as.character(col[1]))
Error: unexpected '=' in:
"df %>%
  mutate(col[1] ="

Ou ainda`

> df$col[1]
NULL

Obrigado.

Euler,
use o mutate_at
Por exemplo:

library(dplyr)
col <- c('nome1', 'nome2')
nome1 <- c(1,2,3)
nome2 <- c('a','b','c')
df = data.frame(nome1, nome2)

# Transformando a columa 1 em caracteres
df = df %>% mutate_at(.vars = col[1],.funs = as.character)

Valeu.

1 curtida

Excelente, @primojr !!! Funcionou perfeitamente!! Muito obrigado.

1 curtida

@euleralencar e @primojr, estou deixando esta resposta aqui só para registrar uma alternativa à solução proposta. Apesar de ela funcionar perfeitamente, a função mutate_at() vai ser abandonada no dplyr por causa do surgimento de alternativas mais consistentes. Hoje em dia, acho que os caminhos recomendados seriam os seguintes:

library(tidyverse)

# Tabela exemplo
df <- data.frame(nome1 = c(1, 2, 3), nome2 = c("a", "b", "c"))
col <- "nome1"

# Usando tidy-eval
df %>%
  mutate({{col}} := as.character(.data[[col]]))
#>   nome1 nome2
#> 1     1     a
#> 2     2     b
#> 3     3     c

# Usando a função across
df %>%
  mutate(across(.col = all_of(col), .fns = as.character))
#>   nome1 nome2
#> 1     1     a
#> 2     2     b
#> 3     3     c

Created on 2022-02-08 by the reprex package (v2.0.1)

A primeira possibilidade usa tidy-eval, um mecanismo muito legal que eu explico em um post recente. A segunda usa a função across(), que é muito parecida com a mutate_at() e deve ser colocada dentro do mutate().

Só por completude, não se esqueçam que o R não é só o tidyverse :stuck_out_tongue:

# Usando base
df[[col]] <- as.character(df[[col]])
df
#>   nome1 nome2
#> 1     1     a
#> 2     2     b
#> 3     3     c

Created on 2022-02-08 by the reprex package (v2.0.1)

1 curtida

@clente muito obrigado. Já vi que preciso aprender um pouco mais de tidy eval!!! :smiley:

1 curtida