10 março, 2021

Introdução

Até esse momento, usamos funções já desenvolvidas no R, seja dos pacotes da Base, seja via instalação dos pacotes via CRAN. Agora, iremos desenvolver as nossas próprias funções.

Como falado nas aulas anteriores, a estrutura da função criada se mantém, argumento, corpo e ambiente. Para isso, usaremos a função function. O modo desse objeto é closure. Vejamos a sua sintaxe,

Sintaxe de function()

# Forma usual
nome_funcao <- function(arg1, arg2, ...) {
   corpo: comandos..
}
# Forma simplificada
nome_funcao <- function(arg1, arg2, ...) corpo

Exemplo 1

> # Funcao
> fun1 <- function(x) {
+   res <- x + 1
+   return(res)
+ }
> # Chamada
> fun1(x = 5)
## [1] 6

Componentes de fun1()

> # Argumentos
> formals(fun1)
## $x
> # Corpo
> body(fun1)
## {
##     res <- x + 1
##     return(res)
## }
> # Ambiente
> environment(fun1)
## <environment: R_GlobalEnv>

Não é obrigatório return()

> # Funcao
> fun2 <- function(x) x + 1
> # Executando
> fun2(5)
## [1] 6

Função anônima

\[ \int^{1}_{0}x^2dx = \frac{1}{3}, \]

> integrate(f = function(x) x^2, 
+           lower = 0, 
+           upper = 1)
## 0.3333333 with absolute error < 3.7e-15

Chamada de função

> # Funcao auxiliar 1
> aux1 <- function(x) x - mean(x)
> # Funcao auxiliar 2
> aux2 <- function(x) x^2
> # Funcao auxiliar 3
> aux3 <- function(x) {
+   sum(x) / (length(x) - 1)
+ }
> # Gerando 100 numeros aleatorios de uma distribuicao normal
> set.seed(10)
> x <- rnorm(100)

Chamada de função (continuação…)

  • Aninhado
> # Calculo do desvio padrao (aninhado)
> sqrt(aux3(aux2(aux1(x))))
## [1] 0.9412359

Chamada de função (continuação…)

  • Intermediário
> # Calculo do desvio padrao (intemediario)
> dp <- aux1(x)
> dp <- aux2(dp)
> dp <- aux3(dp)
> dp <- sqrt(dp)
> dp
## [1] 0.9412359

Chamada de função (continuação…)

  • Pipe
> # Calculo do desvio padrao (pipe)
> x %>% 
+   aux1() %>%
+   aux2() %>%
+   aux3() %>%
+   sqrt() 
## [1] 0.9412359

Ordenamento de argumentos

> estdesc <- function(x, opcao) {
+   res <- switch(opcao,
+            media = round(mean(x), 4),
+            mediana = round(mean(x), 4),
+            medapar = round(mean(x, trim = 0.1), 4))
+   return(res)
+ }
> 
> # Objeto
> set.seed(15)
> x <- rnorm(1000)

Ordenamento de argumentos (continuação…)

> # Argumentos nomeados na funcao
> estdesc(x = x, opcao = "media")
## [1] 0.037
> estdesc(opcao = "media", x = x)
## [1] 0.037

Ordenamento de argumentos (continuação…)

> # Argumentos não nomeados ordenados
> estdesc(x, "media")
## [1] 0.037
> # Argumentos não ordenados (Gera erro)
> estdesc("media", x)
## Error in switch(opcao, media = round(mean(x), 4), mediana = round(mean(x), : EXPR deve ser um vetor de comprimento 1

Escopo léxico

  • Ambiente de funções
  • Ambiente de execuções

Exemplo 2

> x <- 10
> fun <- function() {
+   x <- 2
+   x
+ }
> # Chamando a funcao fun
> fun()
## [1] 2

Exemplo 3

> x <- 10
> fun <- function() {
+   x
+ }
> # Chamando a funcao fun
> fun()
## [1] 10

Caminho de busca

> search()
##  [1] ".GlobalEnv"        "package:magrittr"  "package:stats"    
##  [4] "package:graphics"  "package:grDevices" "package:utils"    
##  [7] "package:datasets"  "package:methods"   "Autoloads"        
## [10] "package:base"

Pesquisa dinâmica

> # Funcao
> fun <- function() x + 10
> # Objeto 1
> x <- 10
> # Chamada1
> fun()
## [1] 20
> # Objeto 2
> x <- 20
> # Chamada 2
> fun()
## [1] 30

Novo começo

> # Objeto
> n <- 1
> # Funcao
> fun <- function() {
+   n <- n + 1
+   n
+ }
> # Chamada 1
> fun()
## [1] 2
> # Chamada 2
> fun()
## [1] 2

Bons estudos!