Agora entendi. Ambos os código estão certos, é só que o jeito como você está usando eles faz com que o NSE seja desnecessário, por isso a f_2()
funciona. Vamos por partes:
- NSE é útil quando queremos usar o nome de um objeto que não existe no ambiente global. Por exemplo, no dplyr nós usamos os nomes das colunas como elas existissem fora da tabela. Veja o código abaixo.
# Objeto `mpg` não existe
mean(mpg)
#> Error in mean(mpg): object 'mpg' not found
# Mas aqui ele existe, por causa da NSE
dplyr::summarise(mtcars, media = mean(mpg))
#> media
#> 1 20.09062
Created on 2022-05-16 by the reprex package (v2.0.1)
- Note que o seu exemplo não usa o nome de nenhuma coluna! Você está usando um índice, que não depende do ambiente para funcionar. Para entender isso, veja os dois cenários abaixo.
# Onde NSE seria útil -----------------------------------------------
# Não existe
mpg
#> Error in eval(expr, envir, enclos): object 'mpg' not found
# Capturar a expressão (dentro de uma função usaríamos substitute())
changed <- expression(mpg)
print(changed)
#> expression(mpg)
# Dentro de mtcars, `mpg` existe e o valor dele é a coluna
eval(expr = changed, envir = mtcars)
#> [1] 21.0 21.0 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 17.8 16.4 17.3 15.2 10.4
#> [16] 10.4 14.7 32.4 30.4 33.9 21.5 15.5 15.2 13.3 19.2 27.3 26.0 30.4 15.8 19.7
#> [31] 15.0 21.4
# O que você está fazendo -------------------------------------------
# Já existe
3
#> [1] 3
# Capturar a expressão (dentro de uma função usaríamos substitute())
changed <- expression(3)
print(changed)
#> expression(3)
# Dentro de mtcars, 3 continua valendo 3. Nada muda!
eval(expr = changed, envir = mtcars)
#> [1] 3
Created on 2022-05-16 by the reprex package (v2.0.1)
- Respondendo a sua pergunta, ambas as suas funções funcionam porque, no fundo, você não precisaria estar usando NSE. Ao escolher trabalhar com índices numéricos,
eval()
simplesmente vai retornar a mesma coisa que sem o eval()
. Um cenário em que f_1()
funciona e f_2()
não funciona ocorre se replicarmos o exemplo que eu dei na resposta anterior.
f_1 <- function(dados, mudar) {
changed <- substitute(expr = mudar)
eval(expr = changed, envir = dados)
}
f_2 <- function(dados, mudar) {
dados[,mudar]
}
f_1(dados = mtcars, mpg)
#> [1] 21.0 21.0 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 17.8 16.4 17.3 15.2 10.4
#> [16] 10.4 14.7 32.4 30.4 33.9 21.5 15.5 15.2 13.3 19.2 27.3 26.0 30.4 15.8 19.7
#> [31] 15.0 21.4
f_2(dados = mtcars, mpg)
#> Error in `[.data.frame`(dados, , mudar): object 'mpg' not found
Created on 2022-05-16 by the reprex package (v2.0.1)
Fez sentido?