EAR: R Básico

Aula 17 - Como criar funções

Encarte

Filosofia de publicação (Selo DC)

Apoio CEAC e UFSJ

Livro de Apoio

Usaremos Batista e Oliveira (2022):

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…)

  • Aninhada
> # Calculo do desvio padrao (aninhado)
> sqrt(aux3(aux2(aux1(x))))
[1] 0.9412359
  • Intermediária
> # 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

Objeto reticências

# Funcao que plota um grafico
grafico <- function(x, y, ...) {
  plot(x = x, y = y, ...)
}
# Vetores
x <- 1:10; y <- rnorm(10)
# Chamada 1, com os argumentos definidos
grafico(x = x, y = y, main = "Meu gráfico")

Escopo léxico

  • Ambiente envolvente
  • 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

Ambiente de execução

> # 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

Obrigado

Sugestões, perguntas, críticas…

Referências

BATISTA, B. D. O.; OLIVEIRA, D. A. B. J. R básico. Ouro Branco, MG, Brasil: [s.n.], 2022.