Skip to Tutorial Content

Tutorial guiado 1 · Criando funções em R

Criar funções em R é um dos passos mais importantes para automatizar tarefas, evitar repetição de código e estruturar análises de dados de forma profissional.

Neste tutorial você vai realizar cinco exercícios práticos e graduais baseados no ecossistema e nos conceitos que foram apresentados no decorrer do módulo.

Todos os exercícios tem uma solução sugerida e comentada. Mas recomendo que só olhe a solução após tentar resolver sozinho.

1. Conversor de Temperatura com Validação Lógica

Escreva uma função chamada celsius_para_fahrenheit que receba uma temperatura em graus Celsius e a converta para Fahrenheit. A fórmula matemática é:

\[F = C \times 1.8 + 32\]

Se o usuário passar um valor que não seja numérico, a função deve interromper a execução e exibir uma mensagem amigável de erro usando a função stop().

celsius_para_fahrenheit <- function(celsius) {
  # Validação de tipo: garante que a entrada seja numérica
  if (!is.numeric(celsius)) {
    stop("Erro: A entrada fornecida deve ser um valor numérico!")
  }
  
  # Aplicação da fórmula matemática
  fahrenheit <- (celsius * 1.8) + 32
  
  # Retorno explícito do resultado
  return(fahrenheit)
}

# --- Testes da Função ---
celsius_para_fahrenheit(25)  # Retorna: 77
celsius_para_fahrenheit(0)   # Retorna: 32
# celsius_para_fahrenheit("vinte") # Descomente para ver o erro controlado pelo stop()

2. Cálculo do Índice de Massa Corporal (IMC) com Classificação

Crie uma função chamada calcular_imc que receba o peso (em kg) e a altura (em metros) de uma pessoa. A função deve calcular o IMC através da fórmula:

\[IMC = \frac{peso}{altura^2}\]

Em seguida, ela deve retornar uma string classificando o indivíduo de acordo com as regras:

  • Se IMC < 18.5: “Abaixo do peso”;
  • Se IMC >= 18.5 e IMC < 25: “Peso normal”;
  • Se IMC >= 25: “Sobrepeso”.
calcular_imc <- function(peso, altura) {
  # Cálculo do IMC utilizando potenciação
  imc <- peso / (altura^2)
  
  # Estrutura de controle condicional IF-ELSE para classificação
  if (imc < 18.5) {
    classificacao <- "Abaixo do peso"
  } else if (imc >= 18.5 & imc < 25) {
    classificacao <- "Peso normal"
  } else {
    classificacao <- "Sobrepeso"
  }
  
  # Criamos uma mensagem clara combinando os resultados
  resultado_texto <- paste0("IMC: ", round(imc, 2), " -> Classificação: ", classificacao)
  return(resultado_texto)
}

# --- Testes da Função ---
calcular_imc(peso = 70, altura = 1.75) # Retorna: "IMC: 22.86 -> Classificação: Peso normal"
calcular_imc(peso = 90, altura = 1.80) # Retorna: "IMC: 27.78 -> Classificação: Sobrepeso"

Estatísticas Resumo de Vetores Tratando NA

Desenvolva uma função chamada analisar_vetor que receba um vetor numérico. Ela deve calcular e retornar uma lista nomeada contendo três estatísticas: a Média, o Desvio Padrão e o Coeficiente de Variação (\(CV = \frac{Desvio\ Padrão}{Média}\)).

A função deve conter um argumento lógico chamado remover_na cujo valor padrão é TRUE.

Se este argumento estiver ativo, a função deve ignorar os valores NA nos cálculos

analisar_vetor <- function(vetor, remover_na = TRUE) {
  # Tratamento inicial: Se o usuário passar apenas NAs e remover_na for TRUE
  if (all(is.na(vetor))) {
    return(list(media = NA, desvio_padrao = NA, cv = NA))
  }
  
  # Cálculo das estatísticas repassando o parâmetro de remoção de NA
  v_media <- mean(vetor, na.rm = remover_na)
  v_sd    <- sd(vetor, na.rm = remover_na)
  v_cv    <- v_sd / v_media
  
  # Armazenamos os resultados em uma lista estruturada e nomeada
  resultado <- list(
    media = round(v_media, 2),
    desvio_padrao = round(v_sd, 2),
    cv = round(v_cv, 3)
  )
  
  return(resultado)
}

# --- Testes da Função ---
notas_turma <- c(7.5, 8.0, NA, 6.0, 9.5)

# Teste com remoção automática de NA (padrão)
analisar_vetor(notas_turma) 
# Retorna: $media [1] 7.75, $desvio_padrao [1] 1.44, $cv [1] 0.186

# Teste forçando a manutenção de NA
analisar_vetor(notas_turma, remover_na = FALSE)
# Retorna tudo como NA, pois o R propaga o NA nas funções matemáticas básicas

Substituição Vetorizada Condicional

Ao lidar com tabelas e vetores, o if comum falha se passarmos múltiplos valores de uma vez. Crie uma função chamada limpar_limites que receba um vetor numérico, um limite_inferior e um limite_superior. A função deve inspecionar o vetor e substituir qualquer valor menor que o limite inferior pela string “Abaixo” e qualquer valor maior que o limite superior pela string “Acima”. Os valores que estiverem dentro do intervalo devem ser mantidos como texto. Utilize a função vetorizada ifelse() para construir a solução.

limpar_limites <- function(vetor, limite_inferior, limite_superior) {
  # O uso de ifelse aninhado permite avaliar todo o vetor simultaneamente (vetorização)
  resultado_vetorial <- ifelse(vetor < limite_inferior, "Abaixo",
                               ifelse(vetor > limite_superior, "Acima", 
                                      as.character(vetor)))
  
  return(resultado_vetorial)
}

# --- Testes da Função ---
dados_sensores <- c(12, 45, 98, 5, 50, 105, 30)

# Aplicando limites de 10 a 90
limpar_limites(dados_sensores, limite_inferior = 10, limite_superior = 90)
# Retorna: "12" "45" "Acima" "Abaixo" "50" "Acima" "30"

5. Função de Manipulação Avançada de Data Frames

Escreva uma função chamada sumarizar_categoria_base que receba três argumentos: um data frame (dados), o nome da coluna de agrupamento como string (coluna_grupo) e o nome da coluna numérica de valores como string (coluna_valores).

A função deve calcular a média da coluna de valores para cada grupo e contar quantos registros existem em cada categoria. O retorno deve ser um único data.frame contendo as colunas: a categoria, a contagem e a média (ordenada da maior média para a menor).

sumarizar_categoria_base <- function(dados, coluna_grupo, coluna_valores) {
  
  # 1. Validação de segurança: garante que o objeto principal é um data.frame
  if (!is.data.frame(dados)) {
    stop("O argumento 'dados' precisa ser um data.frame válido!")
  }
  
  # 2. Extração dos vetores usando a indexação de strings padrão do R base
  vetor_grupo   <- dados[[coluna_grupo]]
  vetor_valores <- dados[[coluna_valores]]
  
  # 3. Cálculo das Médias por Grupo
  # A função aggregate() divide o vetor de valores de acordo com o grupo e aplica a função
  df_medias <- aggregate(vetor_valores ~ vetor_grupo, data = dados, FUN = mean, na.rm = TRUE)
  colnames(df_medias) <- c(coluna_grupo, "Media") # Renomeando as colunas geradas
  
  # 4. Cálculo da Contagem de Linhas por Grupo
  # Usamos a função table() para contar a frequência das categorias e convertemos em data.frame
  df_contagem <- as.data.frame(table(vetor_grupo))
  colnames(df_contagem) <- c(coluna_grupo, "Contagem")
  
  # 5. Combinação dos resultados (Junção)
  # No R base, a função merge() funciona como um join relacional automático entre tabelas
  tabela_resumo <- merge(df_contagem, df_medias, by = coluna_grupo)
  
  # 6. Ordenação Decrescente pela Média
  # Usamos a função order() com o sinal de menos (-) para ordernar do maior para o menor
  linhas_ordenadas <- order(tabela_resumo$Media, decreasing = TRUE)
  tabela_final     <- tabela_resumo[linhas_ordenadas, ]
  
  # Removemos os nomes automáticos de linhas para deixar a tabela limpa
  rownames(tabela_final) <- NULL
  
  return(tabela_final)
}

# --- Teste da Função com R Básico ---
# Vamos testar usando o conjunto de dados nativo do R chamado 'iris'
# Ele contém as colunas textuais/fatores "Species" e numéricas como "Sepal.Length"

resultado_base <- sumarizar_categoria_base(
  dados = iris, 
  coluna_grupo = "Species", 
  coluna_valores = "Sepal.Length"
)

# Imprimindo o resultado no console
print(resultado_base)

# Saída Esperada no Console:
#      Species Contagem    Media
# 1  virginica       50 6.588000
# 2 versicolor       50 5.936000
# 3     setosa       50 5.006000

Dicas para construção de funções

  • Acessando Colunas Dinamicamente: Quando o nome da coluna está guardado em uma variável de texto (ex: coluna_grupo <- “Species”), você não pode usar o cifrão (dados$coluna_grupo), pois o R procurará uma coluna literalmente chamada “coluna_grupo”. A forma correta no R base é usar os colchetes duplos: dados[[coluna_grupo]].

  • Função aggregate(): Essa função é o canivete suíço do R base para estatísticas descritivas. A sintaxe de fórmula vetor_valores ~ vetor_grupo lê-se nativamente como: “calcule a função (FUN) da variável à esquerda em função das categorias da variável à direita”.

Tutorial: Criando funções em R