Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the astra-sites domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /home/statplace/public_html/site/wp-includes/functions.php on line 6114

Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the jetpack domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /home/statplace/public_html/site/wp-includes/functions.php on line 6114

Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the wpforms-lite domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /home/statplace/public_html/site/wp-includes/functions.php on line 6114

Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the wordpress-seo domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /home/statplace/public_html/site/wp-includes/functions.php on line 6114

Notice: A função _load_textdomain_just_in_time foi chamada incorretamente. O carregamento da tradução para o domínio astra foi ativado muito cedo. Isso geralmente é um indicador de que algum código no plugin ou tema está sendo executado muito cedo. As traduções devem ser carregadas na ação init ou mais tarde. Leia como Depurar o WordPress para mais informações. (Esta mensagem foi adicionada na versão 6.7.0.) in /home/statplace/public_html/site/wp-includes/functions.php on line 6114
Bang bang operator no R - Statplace
bangbang-13

Bang bang operator no R

Esse bang bang não tem nada a ver com os filmes do velho oeste! No artigo de hoje explicamos melhor e com exemplos como usar esse operador do R.
Artigo escrito com a colaboração de Larisse Annie Saldanha

O bang bang operator (!!) no R é um operador de quase-citação (quasi-quotation) dentro do tidy evaluation, permitindo avaliar seletivamente partes de uma expressão citada. Isso é especialmente útil ao escrever funções que combinam código fixo com argumentos dinâmicos, garantindo flexibilidade na manipulação de dados em pacotes como o dplyr. Neste artigo, exploramos como esse operador funciona, sua relação com os conceitos de citação (quote(), expr()) e não citação (!!, !!!), e como utilizá-lo para tornar seu código mais eficiente.

No tidy evaluation, todas as funções de citação são, na verdade, funções de quase-citação, porque também oferecem suporte à citação. Onde a quotation é o ato de capturar uma expressão não avaliada, unquotation é a capacidade de avaliar seletivamente partes de uma expressão citada.

Juntos, isso é chamado quase-quotação. A quase-quotação facilita a criação de funções que combinam o código escrito pelo autor da função com o código escrito pelo usuário da função. Isso ajuda a resolver uma grande variedade de problemas desafiadores.

Um argumento citado é capturado pela função e é processado de algum jeito personalizado. Se você não tiver certeza se um argumento é citado ou avaliado, tente executar o código fora da função. Se não funcionar ou fizer algo diferente, esse argumento precisa ser citado.

Unquoting

Unquoting é a habilidade de avaliar seletivamente partes de uma expressão citada de outra forma. Use bang bang `!!` para citar um único argumento numa dada função. Por exemplo:

 ```{r}
 x <- expr(-1)
 expr(f(!!x,y)) ```
 <!-- ![](img/Diagrama1.PNG) --> 

A função `quote()` é equivalente à função `expr()`. Ela simplesmente retorna o argumento. Veja:

 ```{r echo=TRUE}
 quote(x+y) ``` 

Assim como chamamos objetos, `!!` também funciona para símbolos e constantes:

 ```{r echo=TRUE}
 a <- sym("y")
 b <- 1
 expr(f(!!a, !!b)) ``` 

Formalmente, `quo()` e `expr()` são funções de quase-citação, bang bang `!!` é um operador de citação, e `!!!` é um operador de divisão de citação. Estes termos tem um rico histórico em linguagens Lisp, e em linguagens modernas como Julia e Racket.

O operador `!!!` toma uma lista de expressões e insere ela no local do operador. Por exemplo:

 ```{r echo=TRUE}
 xs <- exprs(1,a,-b)
 expr(f(!!!xs,y)) ``` 
 ```{r echo=TRUE}
 ys <- set_names(xs, c("a","b","c"))
 expr(f(!!!ys,d=4)) ```  

Exemplo 1

Os exemplos que serão mostrados, serão do banco de dados `iris` do R.

 ```{r echo=TRUE}
 head(iris)
 ``` 

Suponha que todas as plantas deste banco de dados pertencem à novas espécias, **pallida** e queremos atualizar os valores da coluna que correspondem às espécies. Usamos então `mutate()`:

 ```{r echo=TRUE}
 mutate(iris, Species = "Pallida") %>% head() ```  

Por definição, o `dplyr` cita o nome e avalia o valor. Por isso, podemos facilmente trocar o lado do valor do par por um objeto e, novamente, ele é avaliado e obtemos um resultado idêntico.

 ```{r echo=TRUE}
 targetValue = "Pallida"
 mutate(iris, Species = targetValue) %>% head() ```  

Quando tentamos especificar o valor por um nome, não funciona. Ele somente cria uma coluna.

 ```{r echo=TRUE}
 targetColumn = "Species"
 mutate(iris, targetColumn = "Pallida") %>% head() ``` 

Uso do Operador bang bang `!!`

Como dito anteriormente, o propósito deste operador é citar o argumento. Então, se antes citarmos o nome e avaliar o valor, a citação do nome resolveria nosso problema? Infelizmente não completamente. Mas com o uso do operador `:= (definição)` resolvemos completamente o problema.

 ```{r echo=TRUE}
 targetColumn = "Species"
 mutate(iris, !!targetColumn := "Pallida") %>% head() ```  

E mais:

 ```{r echo=TRUE}
 targetColumn = "Species"
 mutate(iris, !!targetColumn := targetValue) %>% head() ``` 

Uso em Outras Funções do `dplyr`

 ```{r echo=TRUE}
 a <-"Species" 
 filter(iris, !!a == "versicolor") %>% head() ```  

Não funciona, já que `a` é um símbolo e queremos que ele seja avaliado em `Species`. Para funcionar, criamos um símbolo. Precisamos transformar o caracter string `”Species”` em símbolo.

 ```{r echo=TRUE}
 a <-"Species"
 filter(iris, !!rlang :: sym(a) == "versicolor") %>% head() ``` 

Exemplo 2

Banco de Dados `Starwars` do R, onde:

  • Mass: Peso (kg)
  • Height: Altura (cm)
  • BMI: Body Mass Index
 ```{r echo= TRUE}
 head(starwars)
 starwars <- mutate(starwars, height = height / 100)
 transmute(starwars, bmi = mass / height^2) ``` 
 ```{r eval=FALSE, include=FALSE}
 x <- "height"
 transmute(starwars, bmi = mass / (!!x)^2) ``` 
 ```{r echo=TRUE}
 x <- sym("height")
 transmute(starwars, bmi = mass / (!!x)^2) ``` 
 ```{r echo=TRUE}
 starwars %>%  
 group_by(species) %>%  
 summarise(avg = mean(height)) ``` 
 ```{r}
 mean_by <- function(data, var, group) {  
 data %>% 
 group_by(group) %>% 
 summarise(avg = mean(var))
 }
 # mean_by(starwars, "species", "height")
 #> Erro: Column `group` is unknown
 ``` 

Logo, os argumentos `group` e `var` precisam ser citados:

 ```{r} mean_by <- function(data, var, group) { 
 var <- sym(var) 
 group <- sym(group) 
 data %>% 
 group_by(!! group) %>% 
 summarise(avg = mean(!! var))
 }
 mean_by(starwars,"height","species") ``` 

Uso Típico do operador

 `calcula_percentual_linha <- function(data, linha, coluna, indicador){` \
 `var1 <- sym(linha)` \
 `var2 <- sym(coluna)` \ 
 `indicador <- sym(indicador)` \   
 \   
 `tab <-  data %>% ` \     
 `group_by(!!var1,!!var2) %>%`  \     
 `summarise(Total=sum(!!indicador,na.rm = T)) %>%` \     
 `mutate(` \      
  `%` `= (Total/sum(Total))` \    
  `) %>% `  \    
  `dplyr::select(-Total) %>%` \     
 `arrange(!!var2,!!var1) %>%` \     
 `pivot_wider(names_from = DescLinha, values_from = `%`, values_fill = list(`%` = 0))` \    
 \   
 `tab` \   
 \ 
 `}` 

Curtiu nosso conteúdo? Você encontra muito mais no canal do Statplace no YouTube.

Siga-nos nas redes sociais! Estamos no Facebook, Instagram e LinkedIn.

Share the Post:
Compartilhar no facebook
Compartilhar no twitter
Compartilhar no linkedin

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Related Posts