Capítulo 7 Funções

Em R, uma função é um bloco de código que realiza uma tarefa específica e é executado somente quando chamada. Funções são fundamentais na programação, pois permitem a modularização do código, facilitando a manutenção, reutilização e compreensão.

Características de uma Função

  • Reutilizável: Uma vez definida, uma função pode ser chamada repetidamente em diferentes partes de um script.
  • Modularização: Funções ajudam a dividir o código em partes menores e mais gerenciáveis, o que torna o código mais organizado e legível.
  • Parâmetros (Argumentos): Dados podem ser passados para uma função na forma de parâmetros ou argumentos, permitindo que a função opere sobre entradas específicas.

A estrutura básica de uma função em R é a seguinte:

# Sintaxe
nome_da_funcao <- function(argumentos) {
  # Corpo da função: código que realiza operações
  resultado <- ... # Cálculos ou operações
  return(resultado) # Retorna o valor final
}
  • Nome da Função: Um identificador único que você escolhe para a função.
  • Argumentos: Valores de entrada que a função recebe quando chamada. Podem ser opcionais ou obrigatórios.
  • Corpo da Função: O bloco de código que executa as operações definidas.
  • Return (Retorno): O valor que a função devolve após a execução.

O principal objetivo das funções é promover a reutilização de código e reduzir a redundância, facilitando a manutenção e o desenvolvimento eficiente de scripts em R.

Exemplo: Cálculo de Área Retangular

Vamos criar uma função para calcular a área de um retângulo, dada a sua largura e altura:

calcula_area <- function(largura, altura) {
  area <- largura * altura
  return(area)
}

largura_obj <- as.numeric(readline("Insira a largura (em cm): "))
altura_obj <- as.numeric(readline("Insira a altura (em cm): "))

# Chamada da função para calcular a área
area_obj <- calcula_area(largura_obj, altura_obj) 

print(paste("A área do retângulo é:", area_obj, "cm²"))
  • Variáveis Locais: Dentro da função calcula_area, as variáveis largura e altura são locais. Elas existem apenas durante a execução da função e são destruídas após a conclusão.
  • Variáveis Globais: As variáveis largura_obj e altura_obj são globais dentro do script, ou seja, são acessíveis em todo o script, fora da função.
  • Importância da Nomenclatura: É uma boa prática usar nomes diferentes para variáveis locais e globais para evitar confusão e melhorar a legibilidade do código.

Passagem de Argumentos com Valores Padrão

Funções em R podem ser definidas com valores padrão para seus argumentos, o que permite chamadas de função sem a necessidade de especificar todos os argumentos.

calcula_area <- function(largura, altura=2) { 
  area <- largura * altura  
  return(area)
}

# Chamada da função com um argumento omitido
area_obj <- calcula_area(4) 

print(area_obj)
## [1] 8
  • Argumentos com Valores Padrão: Se a altura não for especificada na chamada da função, seu valor padrão será 2. Assim, a função calcula a área usando largura 4 e altura 2.

Passagem de Argumentos por Palavra-chave

Em R, ao chamar uma função, os argumentos podem ser passados por nome (palavra-chave), permitindo maior flexibilidade na ordem dos argumentos.

calcula_area <- function(largura, altura=2) { 
        area <- largura * altura  
        return(area)
}

# Chamada da função com argumentos nomeados
area_obj <- calcula_area(altura=4,largura=3) 
    
print(area_obj)
## [1] 12
  • Flexibilidade na Ordem dos Argumentos: Ao usar argumentos nomeados, a ordem em que os argumentos são passados não importa. O R associa os valores aos nomes corretos.

Uso da Função stop() para Controle de Erro

A função stop() em R é usada para interromper a execução de uma função ou script, exibindo uma mensagem de erro personalizada. É útil para tratar casos em que certas condições pré-definidas não são atendidas.

f <- function(x) {
  if (x < 0) {
    stop("Erro: x não pode ser negativo")  # Interrompe a função com uma mensagem de erro
  }
  return(sqrt(x))
}

f(-2)
## Error in f(-2): Erro: x não pode ser negativo
  • Uso de stop(): Quando a condição x < 0 é verdadeira, a função stop() é chamada, o que interrompe a execução e gera uma mensagem de erro. Isso é útil para prevenir operações inválidas ou resultados inesperados.

Exercício 1: Qual será o output do script abaixo?

x <- 10  

minha_funcao <- function() {
    x <- 5  
    return(x)
}

print(minha_funcao()) 
print(x) 

Exercício 2: Qual é o resultado da chamada da função dados_estudante?

dados_estudante <- function(nome, altura=167){
  print(paste("O(A) estudante",nome,"tem",altura,"centímetros de altura."))
}

dados_estudante("Joana",160)

Exercício 3: Qual é a sintaxe correta para definir uma função em R que soma dois números?

  1. sum <- function(x, y) {return(x + y)}

  2. function sum(x, y) {return(x + y)}

  3. def sum(x, y) {return(x + y)}

  4. sum(x, y) = function {return(x + y)}

Exercício 4: Qual das seguintes chamadas à função estão corretas?

dados_estudante <- function(nome, altura=167) {
  print(paste("O(A) estudante",nome,"tem",altura,"centímetros de altura."))
}

dados_estudante("Joana",160)
dados_estudante(altura=160, nome="Joana")
dados_estudante(nome = "Joana", 160)
dados_estudante(altura=160, "Joana")
dados_estudante(160)

dados_estudante(160) - Esta chamada está errada porque 160 será interpretado como nome, e altura usará seu valor padrão, 167. Isso resultará na impressão: "O(A) estudante 160 tem 167 centímetros de altura." A chamada está tecnicamente correta no sentido de sintaxe, mas o resultado não faz sentido lógico, já que 160 não é um nome válido para um estudante.

Exercício 5: Qual o resultado do seguinte programa?

adi <- function(a,b) {  
  return(c(a+5, b+5))
}

resultado <- adi(3,2)

7.1 Exercícios

1. Crie uma função chamada quadrado() que recebe um único argumento numérico x e devolva o quadrado de x. Teste a função com os valores 3, 5 e 7.

2. Implemente uma função chamada hipotenusa(a,b) que calcule a hipotenusa de um triângulo retângulo dados os comprimentos dos dois catetos, a e b. A função deve devolver o comprimento da hipotenusa utilizando o Teorema de Pitágoras.

3. Escreva uma função chamada divisao_segura(numerador, denominador) que devolva o resultado da divisão ou uma mensagem de erro apropriada se o denominador for zero.

4. Escreva uma função que receba dois inteiros e devolva o maior deles. Teste a função escrevendo um programa que recebe dois números inteiros do utilizador e imprime o resultado da chamada à função. Depois, escreva uma segunda função que devolva o menor deles, aproveitando a primeira função.

5. Escreva uma função que devolva o maior de três números inteiros, utilizando a função maior() do exercício anterior.

6. Crie uma função chamada analise_vetor() que receba um vetor numérico e devolva outro vetor contendo a soma, a média, o desvio padrão e o valor máximo do vetor. Use a função para analisar o vetor c(4, 8, 15, 16, 23, 42). Funções auxiliares sum(), mean(), sd(), max().

7. Implemente uma função chamada classificar_numero() que classifique um número inteiro como “positivo”, “negativo”, ou “zero”.

8. Escreva uma função que calcule o IMC (Índice de Massa Corporal) com base no peso (kg) e altura (m) fornecidos como argumentos e classifique o resultado com base na tabela:

IMC (kg/m^2) Classificação
Menor que 18.5 Baixo peso
De 18.5 a 24.9 Peso normal
De 25 a 29.9 Sobrepeso
De 30 a 34.9 Obesidade grau I
De 35 a 39.9 Obesidade grau II
Igual ou maior que 40 Obesidade grau III

Lembre-se de que IMC = \(\frac{\text{Peso}}{\text{Altura}^2}\).

9. Crie funções em R para converter valores entre diferentes moedas com base nas taxas de câmbio. Implemente e teste as funções, e escreva um programa que solicite ao utilizador um valor em euros e imprima a conversão desse valor para algumas das principais moedas, como dólar, libra, iene e real.

10. Crie uma função que calcule o intervalo de confiança a \((1-\alpha)\times 100\%\) para o valor médio (nota: amostras grandes, dimensão \(\geq 30\).).

  • \(s =\) desvio padrão amostral.

  • \(z_{1-\frac{\alpha}{2}} =\) quantil de probabilidade \(1-\alpha/2\). Use a função qnorm().

\[\left(\bar{x}-z_{1-\frac{\alpha}{2}}\frac{s}{\sqrt{n}},\bar{x}+z_{1-\frac{\alpha}{2}}\frac{s}{\sqrt{n}} \right)\]

IC <- function(amostra, alpha){
  # Coloque seu código aqui
  
}

11. Criar uma função que calcule o intervalo de confiança para o valor médio para \(\alpha\) igual a 0.001, 0.01, 0.05 e 0.10.

ICs <- function(amostra, alphas){
  # Coloque seu código aqui
  
}

12. Crie uma função chamada calcula_moda que receba um vetor numérico ou de caracteres e devolva a moda, ou seja, o valor que mais vezes aparece no vetor.

  • Caso haja mais do que uma moda (valores que aparecem com a mesma frequência), a função deverá retornar todos os valores modais.

  • Utilize a função table() para contar as ocorrências de cada valor no vetor.

  • Aplique a função ao vetor c(1, 2, 2, 3, 3, 4, 4).

  • Teste também com um vetor de caracteres c("A", "B", "A", "C", "C", "C", "B").

13. A distância euclidiana entre dois pontos \(A(x_1, y_1)\) e \(B(x_2, y_2)\) é dada pela fórmula: \[d(A, B) = \sqrt{(x_2 - x_1)^2 + (y_2 - y_1)^2}\]

Crie uma função chamada distancia_euclidiana que aceite como parâmetros as coordenadas dos dois pontos e devolva a distância entre eles.

Teste a função com dois pontos arbitrários, por exemplo, \(A(2, 3)\) e \(B(6, 9)\).

Generalize a função para trabalhar em qualquer dimensão, ou seja, para pontos com coordenadas n-dimensionais.

Teste a função para dois vetores de coordenadas de três dimensões, como \(A(1, 2, 3)\) e \(B(4, 5, 6)\) , garantindo que o código funcione para múltiplas dimensões.

14. Crie uma função chamada cria_matriz_aleatoria que aceite dois parâmetros: o número de linhas e o número de colunas, e devolva uma matriz com números aleatórios uniformes entre 0 e 1.

Adicione uma segunda função analisa_matriz que aceite uma matriz como entrada e devolva as seguintes informações:

  • Soma de todos os elementos;
  • Média de todos os elementos;
  • Traço da matriz (a soma dos elementos da diagonal principal, se a matriz for quadrada).

Teste as funções criando uma matriz \(5 \times 5\) e analisando-a com a função analisa_matriz.

Generalize a função analisa_matriz para devolver a determinante da matriz, apenas se for quadrada. Se não for quadrada, deve informar que não é possível calcular a determinante.