Capítulo 1


Elementos Básicos do R



“The critical requirement of an effective graphical display is that it stimulate spontaneous perceptions of structure in data.”



– S. Smith , 1990



1.1. Introdução


Desenvolvido na Universidade de Auckland, Nova Zelândia, em 1993, pelos professores Ross Ihaka e Robert Gentleman, e fazendo parte da filosofia do Projeto GNU e estando disponível como Software Livre sob os termos da “Licença Pública Geral do GNU” da Fundação do Software Livre (Free Software Foundation’s GNU General Public License), o R é ao mesmo tempo uma linguagem de programação e um ambiente para computação estatística, isto é, trata-se de uma linguagem de programação especializada em computação com dados. Além de gratuito, o R está disponível para uma gama bastante variada de sistemas operacionais como, por exemplo, UNIX, FreeBSB, Linux, Windows e MacOS.


R

1.2. Comandos do Workspace


O workspace do R constitui o ambiente de trabalho no qual se armazenam, acessam e manipulam os objetos criados ao longo de uma sessão. Esses objetos podem incluir variáveis, funções, gráficos, conjuntos de dados, entre outros elementos fundamentais à análise estatística. A Tabela 1.1 a seguir apresenta os principais comandos utilizados para gerenciar tanto os objetos quanto o próprio ambiente de trabalho, permitindo um controle eficiente das operações realizadas durante a execução do R.


Tabela 1.1. Principais comandos disponíveis na workspace do R.

Comando Descrição
ls() ou objects() Lista os nomes dos objetos atualmente armazenados no workspace.
ls.str() Exibe uma listagem detalhada dos objetos no workspace, incluindo informações estruturais.
str() Apresenta a estrutura interna de um objeto, revelando seu tipo, dimensões e conteúdo resumido.
rm() Remove um ou mais objetos do workspace.
rm(list = ls()) Remove todos os objetos do workspace, efetivamente limpando o ambiente de trabalho.
class() Retorna a classe ou tipo de um objeto, fundamental para compreender seu comportamento em operações e funções.
q() Encerra a sessão do R, com a possibilidade de salvar o workspace atual em um arquivo .RData.
setwd() Define o diretório de trabalho, que passa a ser o local padrão para leitura e gravação de arquivos.
getwd() Retorna o caminho do diretório de trabalho atualmente definido.
download.file() Efetua o download de arquivos a partir de URLs da internet para o diretório local.
$ Operador utilizado para acessar variáveis ou colunas específicas em data frames ou listas.
[] Operador genérico de indexação, utilizado para acessar elementos em vetores, matrizes, data frames e listas.
[[]] Operador de indexação utilizado principalmente em listas, para acessar elementos preservando sua estrutura original.
ctrl + L Atalho de teclado que limpa o conteúdo visível na console do R.
# Símbolo utilizado para iniciar comentários no código, que não são executados pelo interpretador.
is.na() Verifica a existência de valores ausentes (NA) em objetos.
summary() Produz um resumo estatístico de objetos, incluindo medidas descritivas relevantes.
dim() Retorna as dimensões (número de linhas e colunas) de objetos bidimensionais, como matrizes ou data frames.
length() Indica o comprimento de objetos unidimensionais, como vetores ou listas.
names() Exibe ou define os nomes dos elementos em objetos como listas, vetores nomeados ou data frames.
head() Apresenta as primeiras linhas de um objeto, facilitando uma visualização preliminar dos dados.
tail() Exibe as últimas linhas de um objeto.
save() Salva objetos específicos em arquivos .RData ou .rda para uso posterior.
load() Carrega objetos salvos previamente em arquivos .RData ou .rda para o workspace atual.
save.image() Salva todo o workspace atual em um único arquivo .RData.
gc() Solicita ao R a liberação de memória não utilizada (garbage collection).


Estes representam apenas alguns dos principais comandos disponíveis no workspace do R, os quais possibilitam gerenciar objetos de forma eficiente, incluindo operações como salvar e carregar dados entre sessões, bem como limpar o ambiente de trabalho sempre que necessário. Para além desses comandos, o R dispõe ainda de diversas funções úteis no pacote utils, empregadas na gestão de arquivos e diretórios, tais como list.files(), file.exists(), file.copy(), entre muitas outras, ampliando consideravelmente as possibilidades de organização e automação do ambiente de trabalho.


1.3. Instalando Pacotes


Um pacote (ou biblioteca) no ambiente R consiste em uma coleção organizada de funções, conjuntos de dados, classes, métodos e documentação, concebida para ampliar as funcionalidades básicas oferecidas pelo núcleo da linguagem. Cada pacote possui uma estrutura padronizada, contendo, por exemplo, descrições formais das funções, exemplos de uso, arquivos de ajuda e eventuais dados internos ou externos destinados a facilitar a execução de análises específicas. A criação e o desenvolvimento de pacotes são, em grande medida, fomentados pela comunidade de usuários e desenvolvedores do R, composta por estatísticos, cientistas de dados, pesquisadores e programadores de diversas áreas, o que contribui para a grande diversidade e riqueza de ferramentas disponíveis.


Por padrão, durante a instalação inicial do R, são incluídos apenas os chamados pacotes básicos e pacotes recomendados, que asseguram o funcionamento essencial do ambiente de programação e oferecem suporte às operações estatísticas e gráficas mais comuns. Contudo, as necessidades analíticas frequentemente demandam funcionalidades adicionais. Para atender a essas demandas, o R permite a instalação de pacotes provenientes de outras fontes, como o repositório oficial CRAN (Comprehensive R Archive Network), além de plataformas de desenvolvimento colaborativo, tais como GitHub e R-Forge. Nessas plataformas, encontram-se tanto pacotes estáveis quanto versões em desenvolvimento, possibilitando acesso a recursos experimentais ou ainda não publicados no CRAN.


1.3.1. Pacotes do CRAN



Em geral, a forma mais prática e recomendada de instalar um pacote no R é por meio da função install.packages("nome_do_pacote"), a qual realiza a instalação do pacote diretamente a partir do repositório oficial de distribuição de pacotes, CRAN (Comprehensive R Archive Network). A CRAN consiste em uma rede mundial de servidores e serviços de FTP, mantida pela comunidade de desenvolvedores e usuários do R, que assegura a disponibilidade e a integridade dos pacotes distribuídos. A coordenação da CRAN está a cargo da Fundação R (R Foundation), que estabelece diretrizes rigorosas e submete os pacotes a extensos testes automatizados, de modo a garantir que estejam em conformidade com as políticas de qualidade e compatibilidade do ecossistema R.


Como exemplo de instalação de pacotes a partir da CRAN, destaca-se o pacote remotes, que reúne um conjunto de funções específicas destinadas à instalação de pacotes hospedados em repositórios remotos, como GitHub, Bitbucket ou GitLab, entre outros. Tal funcionalidade é particularmente útil para acessar pacotes em desenvolvimento ou versões mais recentes que ainda não se encontram disponíveis no CRAN oficial. A instalação do pacote remotes pode ser realizada de modo direto por meio da função install.packages(), conforme ilustrado no Código 1.1.


Código 1.1. Instalação do pacote remotes via install.packages().

# -------------------------------
# Instalação do Pacote `remotes`
# -------------------------------

# --- 1. Função `install.packages()` ---

install.packages("remotes")

# --- 2. Função `library()` ---

library(remotes) # Carrega o pacote na workspace


1.3.2. Pacotes do GitHub e R-forge



Nem todos os pacotes desenvolvidos para o ambiente R encontram-se disponíveis na CRAN. Muitos desenvolvedores optam por disponibilizar seus pacotes em plataformas de desenvolvimento colaborativo, como GitHub ou R-Forge, onde é possível hospedar tanto versões estáveis quanto versões em desenvolvimento. Em diversos casos, um mesmo pacote pode estar simultaneamente disponível na CRAN e em repositórios como o GitHub ou o R-Forge; entretanto, a versão mais recente — frequentemente em estágio de desenvolvimento — costuma ser publicada exclusivamente nessas plataformas alternativas.


Para instalar pacotes diretamente a partir de um repositório hospedado no GitHub, utiliza-se a função install_github(), disponibilizada pelo pacote remotes. Por conseguinte, torna-se necessário que o pacote remotes esteja previamente instalado e carregado no ambiente de trabalho. Além disso, a função install_github() exige como argumento o caminho no formato usuário/repositório, identificando o nome do desenvolvedor (ou organização) e o nome do repositório onde o pacote está hospedado. Para instalar, por exemplo, o pacote ADARdata a partir do repositório mantido pelo usuário lhmet no GitHub, empregam-se os comandos demonstrados no Código 1.2.


Código 1.2. Instalação do pacote ADARdata via install_github().

# --------------------------------
# Instalação do Pacote `ADARdata`
# --------------------------------

# --- 1. Carregar o pacote `remotes` ---

library(remotes)

# --- 2. Instalar o pacote `ADARdata` usando a função `install_github()` ---

install_github("lhmet/ADARdata")


No R, é possível acessar funções específicas de pacotes já instalados sem a necessidade de carregá-los integralmente na sessão, utilizando a notação especial pacote::funcao. Esse recurso permite a chamada direta de uma função pertencente a um pacote, evitando potenciais conflitos de nomes e reduzindo o uso de memória. Dessa forma, o trecho de código apresentado anteriormente pode ser simplificado utilizando essa forma abreviada de acesso a funções, conforme exemplificado no Código 1.3.


Código 1.3. Instalação do pacote ADARdata via install_github() usando a abreviação pacote::funcao.

# --------------------------------
# Instalação do Pacote `ADARdata`
# --------------------------------

# --- 1. Instalar o pacote `ADARdata` usando a abreviação `remotes::install_github()` ---

remotes::install_github("lhmet/ADARdata")


Por outro lado, para instalar um pacote hospedado em um repositório do R-Forge, plataforma dedicada ao desenvolvimento colaborativo de projetos em R, utiliza-se uma abordagem similar àquela empregada para o GitHub, porém adaptada ao formato específico do R-Forge. Como exemplo, para instalar o pacote raster, que está disponível no repositório do R-Forge, empregam-se os comandos indicados no Código 1.4. Essa instalação requer a especificação do endereço do repositório e pode ser realizada utilizando funções padrão do R, como install.packages(), com a devida parametrização para acessar o repositório do R-Forge.


Código 1.4. Instalação do pacote raster via install.packages() com especificação do repositório dado pelo argumento repos.

# ------------------------------
# Instalação do Pacote `raster`
# ------------------------------

# --- 1. Instalar o pacote `raster` via `install.packages()` com especificação do repositório do R-Forge ---

install.packages("raster", repos = "http://R-Forge.R-project.org")


1.3.3. Arquivo Local



Outra alternativa para instalação de pacotes no R consiste no uso de arquivos locais que contêm o código-fonte ou as versões compiladas dos pacotes. Geralmente, os códigos-fonte dos pacotes são disponibilizados em arquivos compactados com extensão .tar.gz, enquanto os binários compilados são armazenados em arquivos com extensão .zip. Esses arquivos podem ser obtidos manualmente a partir do repositório oficial CRAN (por exemplo, na seção “Downloads” da página do pacote, como em https://cran.r-project.org/web/packages/remotes/index.html), bem como em plataformas como GitHub ou R-Forge.


Para instalar um pacote a partir de um arquivo local, utiliza-se a função install.packages() especificando o argumento repos = NULL, indicando que a instalação não deve buscar em repositórios remotos, e o argumento pkgs, que recebe o caminho para o arquivo local do pacote. A sintaxe correspondente é apresentada no Código 1.5.


Código 1.5. Instalação do pacote remotes via install.packages() usando arquivo local.

# -------------------------------------------------
# Instalação do Pacote `remotes` via Arquivo Local
# -------------------------------------------------

# --- 1. Instalar o pacote `remotes` via `install.packages()` com argumento `pkgs` ---

install.packages(pkgs = "remotes_2.1.1.tar.gz", repos = NULL)


1.4. Comando help


O comando help() é um comando de ajuda utilizado no R para obter informações sobre funções, pacotes, métodos e outros tópicos pertinentes à linguagem e à análise de dados. Quando utilizado em conjunto com o nome de uma função, de um pacote ou de outro objeto de interesse, o comando help() retorna uma documentação detalhada que inclui a descrição do objeto, sua sintaxe, argumentos, exemplos de uso e, frequentemente, informações adicionais sobre valores retornados ou referências bibliográficas. A utilização do comando help() pode ser realizada de forma direta, empregando a sintaxe help(nome_do_objeto), ou, de forma equivalente, por meio do operador ?, seguido do nome do objeto. Um exemplo ilustrativo de como acessar a documentação de uma função específica encontra-se no Código 1.6.


Código 1.6. Uso do comando help.

# ----------------------
# Uso do Comando `help`
# ----------------------

# --- 1. Usando help() ---

help(sqrt)

# --- 2. Usando ? ---

?sqrt


Ao executar o exemplo apresentado anteriormente, o R exibe uma interface de ajuda, geralmente no formato HTML ou texto, que apresenta o tópico referente à função sqrt. Essa função, pertencente ao conjunto de funções matemáticas básicas do R, é utilizada para calcular a raiz quadrada de um número. A documentação acessada inclui a descrição da função, sua sintaxe, a definição dos argumentos, exemplos de uso e, em muitos casos, observações relevantes ou advertências quanto ao seu emprego.


Além de consultar diretamente a documentação de funções específicas, o R disponibiliza mecanismos para realizar buscas mais amplas nos arquivos de ajuda, permitindo localizar tópicos cujo nome ou descrição contenham determinado termo. Essa funcionalidade é útil para identificar funções ou pacotes associados a determinado tema, mesmo quando não se conhece previamente o nome exato do objeto procurado. Para efetuar tais buscas, pode-se recorrer ao comando help.search(), cuja sintaxe e exemplos de utilização encontram-se ilustrados no Código 1.7.


Código 1.7. Uso do comando help.search.

# -----------------------------
# Uso do Comando `help.search`
# -----------------------------

# --- 1. Usando help.search() ---

help.search("negative binomial")

# --- 2. Usando ?? ---

??weibull


No que se refere aos pacotes, cada pacote disponível no ecossistema R possui uma página de resumo, geralmente hospedada no CRAN ou em outros repositórios, onde se encontra uma breve descrição sobre suas funcionalidades, informações sobre a versão, dependências, autorias e links diretos para a documentação completa. Após identificar um pacote relevante para determinada análise ou tarefa, o usuário pode acessar o link denominado “Manual de Referência”, que disponibiliza, em formato PDF, toda a documentação detalhada do pacote, incluindo a descrição de funções, argumentos, exemplos de uso e, por vezes, notas técnicas ou referências bibliográficas. Alternativamente, é possível acessar a mesma documentação diretamente no ambiente R, por meio do comando help(), como ilustrado no Código 1.8.


Código 1.8. Uso do comando help() para obter informações de pacotes.

# --------------------------------------------------
# Uso do Comando `help` Para Informações de Pacotes
# --------------------------------------------------

# --- 1. Usando help() com argumento `package` ---

help(package = "tseries")


1.5. Estruturas de Dados no R


Cada linguagem de programação dispõe de suas próprias abstrações para representar e manipular dados, denominadas estruturas de dados. Embora existam particularidades sintáticas e semânticas entre as linguagens, diversas estruturas são amplamente compartilhadas entre elas, dada sua relevância fundamental na computação. No nível mais elementar, por exemplo, encontram-se os tipos de dados primitivos, os quais constituem a base sobre a qual estruturas mais complexas são construídas. Dentre esses tipos primitivos destacam-se:


  • Numéricos, que englobam inteiros e números em ponto flutuante. Inteiros representam valores sem parte fracionária, podendo ser positivos ou negativos. Números em ponto flutuante, por sua vez, representam valores reais, permitindo a expressão de frações e números muito grandes ou muito pequenos mediante notação científica.
  • Caracteres, destinados à representação de símbolos individuais, tais como letras, dígitos ou caracteres especiais. Frequentemente são utilizados para composição de cadeias de texto (strings).
  • Lógicos, representados pelos valores booleanos verdadeiro ou falso, empregados em operações condicionais e expressões lógicas.
  • Complexos, destinados à representação de números complexos, compostos por parte real e parte imaginária.


Paralelamente aos tipos primitivos, as linguagens de programação oferecem tipos compostos, que possibilitam o agrupamento de múltiplos valores — sejam homogêneos ou heterogêneos — em uma única entidade lógica. Dentre os tipos compostos mais comuns, destacam-se:


  • Vetores (ou arrays), que consistem em coleções indexadas de elementos de um mesmo tipo.
  • Estruturas (structs), que agrupam elementos de tipos potencialmente distintos sob um único identificador, permitindo o acesso individual a cada campo.
  • Listas, que representam coleções ordenadas de elementos, podendo conter valores de tipos distintos, e são frequentemente utilizadas para armazenar sequências heterogêneas ou estruturas aninhadas.
  • Mapas ou dicionários (ou hash tables), estruturas que armazenam pares chave-valor, possibilitando acesso aos dados a partir de chaves únicas, sendo essenciais para tarefas de indexação, armazenamento de configurações ou implementação de tabelas de dispersão.
  • Tipos definidos pelo usuário, mediante os quais é possível criar abstrações que melhor representem entidades específicas de um problema, promovendo maior clareza e modularidade no código.


A definição precisa de tipos de dados em linguagens de programação não apenas organiza a representação e o armazenamento das informações, mas também estabelece restrições fundamentais para assegurar a segurança de tipos, prevenindo inconsistências como a atribuição de valores incompatíveis a variáveis de determinado tipo. Por exemplo, se uma variável é declarada como inteira, o ambiente de programação deve impedir a atribuição de valores em ponto flutuante, preservando, assim, a integridade semântica do programa. A forma como as linguagens implementam e operacionalizam tais restrições está diretamente relacionada às estruturas de dados que oferecem.


No ambiente de programação R, em particular, a manipulação de dados fundamenta-se em diversas estruturas específicas, destacando-se entre elas os vetores, as matrizes, os arrays, os quadros de dados e as listas, consideradas estruturas básicas Figura 1.1, bem como os fatores e as datas, que constituem estruturas mais elaboradas. Cada uma dessas estruturas apresenta características, propriedades e operações próprias, que permitem o armazenamento eficiente, o acesso estruturado e o processamento dos dados — aspectos essenciais tanto para a análise estatística quanto para o desenvolvimento de algoritmos computacionais.


Figura 1.1. Tipos de estruturas de dados em linguagem R.

capa

Fonte. Data Structures - IFCA | Instituto de Física de Cantabria. Acesso: Junho, 2025.


1.5.1. Vetores



Os vetores constituem estruturas de dados unidimensionais no ambiente R, destinadas ao armazenamento de elementos homogêneos, ou seja, todos pertencentes ao mesmo tipo de dado. Esses elementos podem ser valores numéricos, lógicos, caracteres, fatores ou outros tipos suportados pela linguagem. A criação de vetores no R é, em geral, realizada por meio da função c(), cuja denominação provém de “combine” ou “concatenate”. Essa função permite agrupar diversos valores em uma única estrutura vetorial, definindo, assim, o conteúdo do vetor.


Vale ressaltar que, caso sejam fornecidos elementos de tipos diferentes à função c(), o R realizará a coerção automática dos tipos, convertendo todos os elementos para o tipo mais abrangente capaz de representar todos os valores informados, conforme uma hierarquia interna de tipos (por exemplo, números podem ser convertidos em texto se forem combinados a cadeias de caracteres). Exemplos ilustrativos da criação de vetores utilizando a função c() encontram-se apresentados no Código 1.9.


Código 1.9. Exemplos de vetores em ambiente R criados pela função c().

# ----------------------
# Vetores em Ambiente R
# ----------------------

# --- Exemplo 1. Vetor composto apenas por números ---

x <- c(1, 4, 10.5, 54.48, 9, 10)
x
[1]  1.00  4.00 10.50 54.48  9.00 10.00
# --- Exemplo 2. Vetor composto apenas por caracteres ---

z <- c('Vetor', 'Data.Frame', 'Array', 'Matrizes', 'Listas') 
z
[1] "Vetor"      "Data.Frame" "Array"      "Matrizes"   "Listas"    


1.5.2. Matrizes



As matrizes constituem estruturas de dados bidimensionais no ambiente R, projetadas para armazenar elementos homogêneos, ou seja, todos pertencentes ao mesmo tipo de dado, tal como ocorre com os vetores. As matrizes são organizadas em linhas e colunas, o que permite a representação eficiente de dados numéricos, lógicos ou de caracteres em um formato tabular, favorecendo operações matriciais e manipulações algébricas complexas.


A criação de matrizes pode ser realizada a partir de vetores previamente definidos, utilizando funções como matrix(), na qual se especificam os valores a serem inseridos, bem como o número de linhas e colunas desejado. Além disso, parâmetros adicionais permitem controlar se o preenchimento dos elementos deve ocorrer por linhas ou por colunas, bem como atribuir nomes às dimensões da matriz, o que facilita a interpretação dos dados. Assim como ocorre com os vetores, as matrizes exigem que todos os seus elementos sejam do mesmo tipo; caso contrário, o R aplica a coerção automática, convertendo os elementos para um tipo comum que assegure a compatibilidade dos dados. Exemplos ilustrativos da criação e manipulação de matrizes encontram-se apresentados no Código 1.10.


Código 1.10. Exemplos de matrizes em ambiente R criados pela função matrix().

# -----------------------
# Matrizes em Ambiente R
# -----------------------

# --- Exemplo 1. Matriz de 2 linhas e 5 colunas com preenchimento por linha ---

A <- matrix(data = c(1:10), nrow = 2, ncol = 5, byrow = TRUE) 
A
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    2    3    4    5
[2,]    6    7    8    9   10
# --- Exemplo 2. Matriz de 2 linhas e 5 colunas com preenchimento por linha formada por sequência de números ---

B <- matrix(data = seq(from = 1, to = 10, by = 1), nrow = 2, ncol = 5, byrow = TRUE) 
B
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    2    3    4    5
[2,]    6    7    8    9   10


1.5.3. Arrays



Os arrays representam estruturas de dados multidimensionais no ambiente R, projetadas para armazenar elementos homogêneos, ou seja, todos pertencentes ao mesmo tipo de dado. Enquanto as matrizes se restringem a duas dimensões — linhas e colunas —, os arrays generalizam essa estrutura para qualquer número de dimensões, permitindo, por exemplo, organizar dados em três, quatro ou mais eixos. A criação de arrays no R é realizada geralmente por meio da função array(), na qual se especificam tanto os valores que irão compor o array quanto as dimensões desejadas. A função também possibilita atribuir nomes às dimensões, facilitando a interpretação dos dados armazenados e o acesso a elementos específicos.


Porém, assim como ocorre com vetores e matrizes, os arrays também requerem que todos os seus elementos sejam do mesmo tipo. Caso elementos de tipos distintos sejam fornecidos na criação do array, o R executa a coerção automática para o tipo mais abrangente, assegurando a homogeneidade da estrutura. Exemplos ilustrativos da criação e manipulação de arrays no R encontram-se apresentados no Código 1.11.


Código 1.11. Exemplos de arrays em ambiente R criados pela função array().

# ---------------------
# Arrays em Ambiente R
# ---------------------

# --- Exemplo 1. Array tridimensional com três linhas, quatro colunas e duas “camadas” (ou matrizes empilhadas) ---

array(1:24, dim = c(3, 4, 2))
, , 1

     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12

, , 2

     [,1] [,2] [,3] [,4]
[1,]   13   16   19   22
[2,]   14   17   20   23
[3,]   15   18   21   24
# --- Exemplo 2. Array de 4 dimensões, cada uma de tamanho 2, contendo números de 1 a 16 ---

array(1:16, dim = c(2, 2, 2, 2))
, , 1, 1

     [,1] [,2]
[1,]    1    3
[2,]    2    4

, , 2, 1

     [,1] [,2]
[1,]    5    7
[2,]    6    8

, , 1, 2

     [,1] [,2]
[1,]    9   11
[2,]   10   12

, , 2, 2

     [,1] [,2]
[1,]   13   15
[2,]   14   16


1.5.4. Quadro de Dados



Os quadro de dados (Data Frames) constituem estruturas de dados bidimensionais no ambiente R, sendo uma das ferramentas mais empregadas para o armazenamento e a manipulação de informações em formato tabular. Diferentemente de matrizes e arrays, que exigem homogeneidade de tipo em todos os seus elementos, os quadros de dados permitem que cada coluna contenha dados de tipos distintos, como valores numéricos, cadeias de caracteres, valores lógicos ou fatores. Essa flexibilidade os torna apropriados para representar conjuntos de dados provenientes de bases estatísticas, planilhas eletrônicas ou sistemas de bancos de dados relacionais.


A criação de data frames no R pode ser realizada por meio da função data.frame(), na qual se especificam as variáveis que irão compor cada coluna e, opcionalmente, os nomes das variáveis e das observações. Os quadro de dados permitem uma ampla variedade de operações, incluindo filtragem de linhas, seleção de colunas, ordenação, agregações e junção com outros quadros de dados. Além da estrutura tradicional dos quadros de dados, o R dispõe de variantes mais modernas, como o tibble, fornecido pelo pacote tibble e amplamente utilizado no ecossistema tidyverse. Os tibbles mantêm a mesma filosofia dos quadro de dados, mas apresentam vantagens adicionais, tais como impressão mais amigável no console, tratamento mais seguro de nomes de variáveis e comportamento mais consistente ao extrair subconjuntos de dados, aspectos que os tornam particularmente adequados para fluxos de trabalho envolvendo grandes volumes de dados. Exemplos ilustrativos da criação e manipulação de quadro de dados encontram-se apresentados no Código 1.12.


Código 1.12. Exemplos de quadro de dados em ambiente R criados pela função data.frame() e pela função tibble.

# ------------------------------
# Quadro de Dados em Ambiente R
# ------------------------------

# --- Exemplo 1. Quadro de dados criado usando a função data.frame() ---

df    <- data.frame(Nome = c("Ana", "Bruno", "Carlos"),
                    Idade = c(23, 35, 28),
                    Altura = c(1.65, 1.80, 1.75))
print(df)
    Nome Idade Altura
1    Ana    23   1.65
2  Bruno    35   1.80
3 Carlos    28   1.75
# --- Exemplo 2. Quadro de dados criado usando a função tibble() ---

# install.packages("tibble") # Se necessário
library(tibble)

tb    <- tibble(Nome = c("Ana", "Bruno", "Carlos"),
                Idade = c(23, 35, 28),
                Altura = c(1.65, 1.80, 1.75))
print(tb)
# A tibble: 3 × 3
  Nome   Idade Altura
  <chr>  <dbl>  <dbl>
1 Ana       23   1.65
2 Bruno     35   1.8 
3 Carlos    28   1.75


1.5.5. Listas



As listas representam estruturas de dados extremamente versáteis no ambiente R, pois, diferentemente dos vetores, matrizes, arrays ou mesmo dos quadros de dados, não exigem homogeneidade de tipo entre seus elementos. Uma lista pode conter, simultaneamente, objetos de naturezas distintas, como vetores numéricos, cadeias de caracteres, valores lógicos, fatores, matrizes, quadro de dados, funções ou até mesmo outras listas. A criação de listas no R é realizada por meio da função list(), que permite agrupar diversos objetos sob um único identificador.


O acesso aos elementos de uma lista pode ser feito de diversas maneiras: utilizando o operador $ para acessar elementos pelo nome; utilizando [[ ]] para acessar um único elemento pela sua posição ou nome; ou ainda empregando [ ] para extrair sublistas. As listas, em geral, são empregadas em R para representar objetos retornados por funções que produzem múltiplas saídas, como modelos de regressão, análises estatísticas avançadas ou funções de agrupamento, onde diferentes componentes de resultados precisam ser armazenados de forma organizada, porém heterogênea. Exemplos ilustrativos da criação e manipulação de listas encontram-se apresentados no Código 1.13.


Código 1.13. Exemplos de listas em ambiente R criadas pela função list().

# ---------------------
# Listas em Ambiente R
# ---------------------

# --- Exemplo 1. Criação de uma lista heterogênea utilizando a função list() ---

x       <- c(1, 4, 10.5, 54.48, 9, 10)      # Vetor numérico

A       <- matrix(data = 1:10,
                  nrow = 2,
                  ncol = 5,
                  byrow = TRUE)             # Matriz númerica 2 x 5

db      <- data.frame(A = 1:5,
                      B = c("ID-1", 
                            "ID-2", 
                            "ID-3", 
                            "ID-4", 
                            "ID-5"))        # Quadro de dados 5 x 2

lista   <- list(vetor = x,
                matriz = A,
                data_frame = db)            # Lista para armazenar as estruturas criadas

print(lista)                                # Impressão da lista
$vetor
[1]  1.00  4.00 10.50 54.48  9.00 10.00

$matriz
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    2    3    4    5
[2,]    6    7    8    9   10

$data_frame
  A    B
1 1 ID-1
2 2 ID-2
3 3 ID-3
4 4 ID-4
5 5 ID-5
# --- Exemplo 2. Criação de uma lista homogênea contendo apenas vetores numéricos ---

vetor1          <- c(2, 4, 6, 8)
vetor2          <- c(10, 20, 30)
vetor3          <- c(1.5, 2.5, 3.5, 4.5, 5.5)

lista_homogenea <- list(primeiro = vetor1,
                        segundo = vetor2,
                        terceiro = vetor3)

print(lista_homogenea)
$primeiro
[1] 2 4 6 8

$segundo
[1] 10 20 30

$terceiro
[1] 1.5 2.5 3.5 4.5 5.5


1.5.6. Fatores



Os fatores constituem uma estrutura de dados destinada à representação de variáveis categóricas, sejam elas nominais ou ordinais. Diferentemente de vetores de caracteres comuns, os fatores armazenam internamente valores inteiros que representam os níveis (ou categorias) possíveis da variável, juntamente com um atributo que define o conjunto completo desses níveis. A criação de fatores no R é realizada por meio da função factor(), à qual se fornecem os dados categóricos a serem transformados, podendo-se especificar explicitamente os níveis desejados e sua ordem.


Os fatores são ferramentas essenciais em procedimentos como análise de variância, regressões com variáveis qualitativas, construção de tabelas de contingência e geração de gráficos categóricos. Sua utilização assegura que as funções do R interpretem corretamente as variáveis categóricas, evitando, por exemplo, que categorias sejam tratadas como simples sequências de caracteres. Além disso, os fatores permitem uma fácil modificação da ordem dos níveis, inclusão de novos níveis ou recodificação das categorias existentes. Exemplos ilustrativos da criação e manipulação de fatores encontram-se apresentados no Código 1.14.


Código 1.14. Exemplos de fatores em ambiente R criados pela função factor().

# ----------------------
# Fatores em Ambiente R
# ----------------------

# --- Exemplo 1. Criação de um fator a partir de um vetor de caracteres ---

cores_olhos   <- c("Azul", 
                   "Verde", 
                   "Castanho", 
                   "Azul", 
                   "Azul",
                   "Castanho", 
                   "Verde", 
                   "Castanho", 
                   "Verde")           # Vetor contendo as cores dos olhos dos indivíduos


fator_cores   <- factor(cores_olhos)  # Conversão do vetor em um fator

print(fator_cores)                    # Visualização do fator e seus níveis (categorias)
[1] Azul     Verde    Castanho Azul     Azul     Castanho Verde    Castanho
[9] Verde   
Levels: Azul Castanho Verde
# --- Exemplo 2. Criação de um fator ordinal representando níveis de satisfação ---

satisfacao        <- c("Baixa", 
                       "Média", 
                       "Alta", 
                       "Média", 
                       "Alta", 
                       "Baixa", 
                       "Alta", 
                       "Média")               # Vetor de respostas de satisfação em uma pesquisa

fator_satisfacao  <- factor(satisfacao,
                           levels = c("Baixa", "Média", "Alta"),
                           ordered = TRUE)    # Criação de um fator ordinal

print(fator_satisfacao)                       # Visualização do fator e seus níveis (categorias)
[1] Baixa Média Alta  Média Alta  Baixa Alta  Média
Levels: Baixa < Média < Alta


1.5.7. Datas



As datas constituem uma categoria especial de dados no ambiente R, projetada para representar informações temporais de forma estruturada e precisa. O R disponibiliza classes específicas para manipulação de datas e horários, tais como Date para datas calendáricas e POSIXct e POSIXlt para dados temporais que incluem horas, minutos e segundos. A criação de objetos de data pode ser realizada por meio de funções como as.Date(), que converte cadeias de caracteres em objetos da classe Date, sendo possível especificar o formato da data original para garantir a interpretação correta. Para manipulações mais complexas, que envolvam horas e fusos horários, utilizam-se as classes POSIXct e POSIXlt, com funções como as.POSIXct() e strptime().


O manuseio adequado de datas é essencial para séries temporais, análise de tendências, agregações por períodos e modelagens preditivas que envolvem variáveis temporais. O R também oferece pacotes especializados, como lubridate, que proporcionam uma sintaxe simplificada e poderosa para a manipulação, extração e transformação de componentes temporais (ano, mês, dia, hora, minuto, segundo). Exemplos ilustrativos da criação e manipulação de objetos de data no R encontram-se apresentados no Código 1.15.


Código 1.15. Manipulando datas no ambiente R usando as funções as.Date() e as.POSIXct().

# --------------------
# Datas em Ambiente R
# --------------------

# --- Exemplo 1. Criação e operações básicas com objetos do tipo `Date` ---


# --- (a) Criação de uma variável do tipo `Date` a partir de uma string ---

data_inicial    <- as.Date("2022-09-15")
print(data_inicial)                         # Exibição da data inicial
[1] "2022-09-15"
# --- (b) Adição de 7 dias a data inicial ---

data_mais_sete  <- data_inicial + 7
print(data_mais_sete)                       # Exibição da nova data
[1] "2022-09-22"
# --- (c) Cálculo da diferença em dias ---

data_final      <- as.Date("2022-10-01")
diferenca       <- data_final - data_inicial
print(diferenca)                            # Classe difftime, número de dias
Time difference of 16 days
# --- (d) Formatação da data para outro padrão de visualização ---

format(data_inicial, format = "%A, %d de %B") # "quinta-feira, 15 de setembro" (local em inglês)
[1] "Thursday, 15 de September"
# --- Exemplo 2. Criação e operações básicas com objetos do tipo `POSIXct` ---


# --- (a) Criação de datas com hora usando POSIXct ---

data_hora       <- as.POSIXct("2022-09-15 14:30:00")
print(data_hora)
[1] "2022-09-15 14:30:00 -03"
# --- (b) Adição de 90 minutos (1.5 horas) a `data_hora` ---

data_hora_mais <- data_hora + 90 * 60
print(data_hora_mais)
[1] "2022-09-15 16:00:00 -03"


1.6. Atribuição de Valores


Como ocorre em qualquer paradigma de programação, inclusive na programação funcional, é frequente a necessidade de atribuir valores a variáveis antes de utilizá-las. Esse procedimento denomina-se inicialização de variáveis, sendo essencial para que estruturas ou algoritmos operem corretamente. No ambiente R, realizar uma atribuição implica criar um objeto capaz de armazenar determinado valor, que pode ser um escalar (número), um vetor, uma matriz, um quadro de dados, uma lista ou qualquer outra estrutura de dados suportada pela linguagem. Existem três formas principais de efetuar atribuições, cada qual com implicações distintas quanto ao escopo (local ou global) e ao estilo de programação adotado (encadeada).


1.6.1. Atribuição Local



A atribuição local refere-se ao processo de criação de objetos cujo escopo está restrito a um determinado ambiente, como o interior de uma função ou de uma estrutura de controle. No ambiente R, esse tipo de atribuição é feito, em geral, por meio do operador <-, que é o mais recomendado pela documentação oficial da linguagem, embora o operador = também possa ser empregado em certos contextos, especialmente na definição de argumentos em funções. Além desses operadores, a função assign() constitui outra forma de atribuição, permitindo criar variáveis cujos nomes podem ser definidos dinamicamente como strings. Alguns exemplos das formas de atribuição local no ambiente R são ilustrados no Código 1.16.


Código 1.16. Exemplos de atribuição local no ambiente R, utilizando os operadores <-, =, e a função assign().

# -----------------
# Atribuição Local 
# -----------------

# --- Exemplo 1. Atribuição do tipo `variavel <- valor` ---

x     <- 10
y     <- x + 1

# --- Exemplo 2. Atribuição do tipo `valor -> variavel` ---

0.56  -> x 
x + 1 -> w

# --- Exemplo 3. Atribuição do tipo `variavel = valor` ---

x     = -8
w     = c(1,3,4)

# --- Exemplo 4. Atribuição do tipo `assign('variavel', valor)` ---

assign("x", 2)
assign("y", matrix(c(2,2), ncol = 2))


Quando uma variável é atribuída localmente no interior de uma função, ela permanece existente apenas durante a execução dessa função, sendo automaticamente descartada ao seu término, salvo se for explicitamente retornada ou transferida para um ambiente superior. Tal comportamento assegura o isolamento dos objetos criados, prevenindo efeitos colaterais no ambiente global. Essa dinâmica está ilustrada no Código 1.17.


Código 1.17. Exemplos de atribuição local no interior de funções no ambiente R.

# ----------------------------------------
# Atribuição Local no Interior de Funções 
# ----------------------------------------

# --- Exemplo. Criação da função `minha_funcao()` com atribuição local em seu interior ---

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


Neste exemplo, o objeto x é criado localmente no interior do corpo da função minha_funcao(). Sua existência restringe-se ao período de execução da função, e seu valor é disponibilizado apenas porque foi explicitamente retornado pela instrução return(). Fora do escopo da função, o objeto x não está definido, o que evidencia o caráter temporário das variáveis locais. Tal comportamento está exemplificado no Código 1.18.


Código 1.18. Ilustração do funcionamento da atribuição local no interior de funções no ambiente R.

# ------------------------------------------------
# Atribuição Local no Interior de Funções (Cont.) 
# ------------------------------------------------

# --- 0. Limpar todas as variáveis do console para evitar confrontos de nomes ---

rm(list = ls())    

# --- 1. Criação da função `minha_funcao()` com atribuição local em seu interior ---

minha_funcao <- function() 
{
  x   <- 42
  return(x)
}
# --- 2. Execução da função `minha_funcao()` ---

minha_funcao()  
[1] 42
# --- 3. Execução da variável `x` que foi definida no interior da função `minha_funcao()` ---

x
# [1] Error: object 'x' not found


1.6.2. Atribuição Global



A atribuição global refere-se ao processo de criação ou modificação de objetos no ambiente global, mesmo quando realizada a partir do interior de funções ou blocos locais. No ambiente R, esse tipo de atribuição é realizada pelo operador <<-, o qual busca o objeto nos ambientes superiores até localizá-lo; caso não exista, o objeto é criado diretamente no ambiente global. Essa forma de atribuição possibilita que variáveis definidas dentro de funções permaneçam acessíveis fora delas, persistindo após o término da execução. Embora útil em circunstâncias específicas, a atribuição global deve ser utilizada com cautela, pois pode gerar efeitos colaterais indesejados, comprometendo a previsibilidade e a manutenção do código. Um exemplo ilustrativo desse tipo de atribuição é ilustrado no Código 1.19.


Código 1.19. Exemplo de atribuição global no ambiente R, utilizando o operador <<-.

# ------------------
# Atribuição Global 
# ------------------

# --- 0. Limpar todas as variáveis do console para evitar confrontos de nomes ---

rm(list = ls())    

# --- 1. Criação da função `minha_funcao()` com atribuição global em seu interior ---

minha_funcao <- function() 
{
  x <<- 42
}
# --- 2. Verificação da existência do objeto `x` antes da execução da função ---

exists("x")   
[1] FALSE
# --- 3. Execução da função `minha_funcao()` ---

minha_funcao()
# --- 4. Verificação do valor e existência do objeto `x` após a execução ---

x
[1] 42


1.6.3. Atribuição Encadeada



A atribuição encadeada em R refere-se à prática de combinar operações sequenciais por meio do operador pipe, que permite encadear chamadas de funções de forma legível e funcional. A linguagem R dispõe de dois principais operadores pipe: o pipe nativo |> (introduzido na versão 4.1.0) e o pipe %>% do pacote magrittr (nome em homenagem ao pintor surrealista René Magritte e sua obra Ceci n’est pas une pipe), utilizado no ecossistema tidyverse. Em ambos os casos, a sintaxe é escrita como objeto |> (ou %>%) função1() |> (ou %>%) função2() |> (ou %>%) ... |> (ou %>%) funçãoN(). O Código 1.20 o uso do pipe nativo (|>) no R para processar o conjunto de dados mtcars. Inicialmente, filtra-se o banco para veículos com consumo (mpg) acima de 20. Em seguida, cria-se a variável hp_ratio, que representa a razão entre potência (hp) e peso (wt) do carro. Por fim, calcula-se a média dessa razão, agrupada pelo número de cilindros (cyl). Esse encadeamento, em particular, facilita a leitura e evita o uso de variáveis intermediárias.


Código 1.20. Exemplo de atribuição encadeada utilizando o pipe nativo |> no ambiente R.

# ---------------------------------
# Atribuição Encadeada Usando `|>` 
# ---------------------------------

# --- 0. Limpar todas as variáveis do console para evitar confrontos de nomes ---

rm(list = ls())    

# --- 1. Manipulação de dados usando (|>) ---

pipe_native <- mtcars |>
                 subset(mpg > 20) |>
                   transform(hp_ratio = hp / wt) |>
                     aggregate(hp_ratio ~ cyl, data = _, FUN = mean)

# --- 2. Visualização do resultado ---

pipe_native
  cyl hp_ratio
1   4 37.92533
2   6 38.15341


Já o Código 1.21 exemplifica o uso do operador pipe do ecossistema tidyverse (%>% - pacotes magrittr e dplyr) para processar o conjunto de dados mtcars. Primeiramente, filtra os veículos cujo consumo (mpg) é superior a 20. Em seguida, ordena as observações em ordem decrescente de potência (hp). Por fim, calcula duas estatísticas: a média do consumo (media_mpg) e o total de veículos selecionados (total).


Código 1.21. Exemplo de atribuição encadeada utilizando o pipe dos pacotes magrittr e dplyr no ambiente R.

# ----------------------------------
# Atribuição Encadeada Usando `%>%`
# ----------------------------------

# --- 0. Limpar todas as variáveis do console para evitar confrontos de nomes ---

rm(list = ls())    

# --- 1. Instalar e carregar o pacote magrittr e dplyr---

# install.packages('magrittr')
# install.packages('dplyr')
library(magrittr)
library(dplyr)

# --- 2. Manipulação de dados usando (%>%) ---

pipe_magrittr   <- mtcars %>%
                    filter(mpg > 20) %>%
                      arrange(desc(hp)) %>%
                        summarize(media_mpg = mean(mpg), total = n())

# --- 2. Visualização do resultado ---

pipe_magrittr
  media_mpg total
1  25.47857    14


1.7. Tipos de Operadores


No ambiente R, os operadores consistem em símbolos especiais ou funções pré-definidas que permitem a realização de operações sobre variáveis, objetos ou valores, desempenhando um papel importante na manipulação e transformação de dados. Esses operadores podem ser classificados em diferentes categorias, de acordo com a natureza das operações que executam, tais como: operadores aritméticos (por exemplo, soma, subtração, multiplicação e divisão), operadores relacionais (que comparam valores), operadores lógicos (que realizam operações booleanas), operadores de atribuição (que vinculam valores a variáveis - apresentados na Seção 1.6), entre outros.


1.7.1. Operadores Aritméticos



Na análise de dados, a aplicação correta de operações matemáticas é essencial para a elaboração de algoritmos, o processamento de dados e a construção de modelos estatísticos. No ambiente R, essas operações básicas são executadas por meio de operadores convencionais, que obedecem às regras de precedência e associatividade comuns às linguagens de programação. Conhecer essas regras é importante para assegurar que as expressões sejam avaliadas de forma correta e para evitar ambiguidades nos cálculos. A Tabela 1.2, apresenta uma descrição dos principais operadores matemáticos disponíveis em R, e o Código 1.22 ilustra alguns exemplos de uso desses operadores.


Tabela 1.2. Principais operadores aritméticos no ambiente R.

Operador Descrição
^ Realiza a operação de potenciação
/ Realiza a operação de divisão
%/% Realiza a operação de divisão inteira
* Realiza a operação de multiplicação
+ Realiza a operação de adição
- Realiza a operação de subtração
%% Realiza a operação de congruência modular
%*% Realiza a operação de multiplicação de matrizes


Código 1.22. Exemplos de uso dos operadores aritméticos no ambiente R.

# -------------------------------------------
# Exemplos de Uso dos Operadores Aritméticos 
# -------------------------------------------

# --- Exemplo 1. Adição ---

soma <- 10 + 5
soma            # Saída: 15
[1] 15
# --- Exemplo 2. Subtração ---

subtracao <- 10 - 5
subtracao       # Saída: 5
[1] 5
# --- Exemplo 3. Multiplicação ---

multiplicacao <- 10 * 5
multiplicacao   # Saída: 50
[1] 50
# --- Exemplo 4. Divisão ---

divisao <- 10 / 5
divisao         # Saída: 2
[1] 2
# --- Exemplo 5. Potenciação ---

potencia <- 10^2
potencia        # Saída: 100
[1] 100
# --- Exemplo 6. Congruência modular ---

congr_mod <- 10 %% 3
congr_mod       # Saída: 1
[1] 1
# --- Exemplo 7. Divisão inteira ---

div_inteira <- 10 %/% 3
div_inteira     # Saída: 3
[1] 3
# --- Exemplo 8. Multiplicação de matrizes ---

A <- matrix(c(1, 2, 3, 4), nrow = 2, byrow = TRUE)  # Matriz A: ordem 2 x 2
B <- matrix(c(5, 6, 7, 8), nrow = 2, byrow = TRUE)  # Matriz B: ordem 2 x 2

C <- A %*% B    # Multiplicação de A por B

print(C)        # Saída: Matriz C - ordem 2 x 2
     [,1] [,2]
[1,]   19   22
[2,]   43   50


1.7.2. Operadores Relacionais



Os operadores relacionais em R são utilizados para comparar valores ou objetos, produzindo resultados lógicos (TRUE ou FALSE) a partir de relações de igualdade, diferença ou ordem entre elementos. Estes operadores permitem, por exemplo, identificar valores maiores, menores, iguais ou diferentes entre variáveis, sendo empregados, em geral, na filtragem de dados e na análise condicional. A Tabela 1.3 apresenta os principais operadores relacionais disponíveis no ambiente R, e o Código 1.23 ilustra alguns exemplos de uso desses operadores.


Tabela 1.3. Principais operadores relacionais no ambiente R.

Operador Descrição
== Testa se dois valores são iguais
!= Testa se dois valores são diferentes
> Testa se o valor à esquerda é estritamente maior que o da direita
< Testa se o valor à esquerda é estritamente menor que o da direita
>= Testa se o valor à esquerda é maior ou igual ao da direita
<= Testa se o valor à esquerda é menor ou igual ao da direita


Código 1.23. Exemplos de uso dos operadores relacionais no ambiente R.

# -------------------------------------------
# Exemplos de Uso dos Operadores Relacionais 
# -------------------------------------------

# --- Exemplo 1. Comparação de vetores numéricos ---

vetor1    <- c(10, 25, 30, 40)
vetor2    <- c(15, 20, 35, 45)

resultado <- vetor1 > vetor2

print(resultado)  # Saída: FALSE TRUE FALSE FALSE
[1] FALSE  TRUE FALSE FALSE
# --- Exemplo 2. Comparação de vetores de caracteres ---

nomes         <- c("João", "Maria", "Pedro", "Ana")
nomes_com_p   <- c("João", "Paulo", "Pedro", "Ana")

resultado     <- nomes == nomes_com_p

print(resultado)  # Saída: TRUE FALSE TRUE TRUE
[1]  TRUE FALSE  TRUE  TRUE


1.7.3. Operadores Lógicos



Os operadores lógicos em R são úteis para a criação de condições, filtragem de dados e controle de fluxo em algoritmos e análises estatísticas. São utilizados para combinar ou inverter resultados lógicos (TRUE ou FALSE) e podem operar tanto elemento a elemento (em vetores) quanto apenas sobre o primeiro elemento de uma expressão lógica, dependendo do operador escolhido. Além das operações clássicas de negação, conjunção e disjunção, o R também disponibiliza o operador xor(), que retorna TRUE somente quando exatamente uma das condições comparadas é verdadeira. Essa diversidade de operadores oferece flexibilidade na construção de expressões condicionais, especialmente em contextos que envolvem processamento vetorial. A Tabela 1.4 apresenta os principais operadores lógicos disponíveis no ambiente R, e o Código 1.24 ilustra alguns exemplos de uso desses operadores.


Tabela 1.4. Principais operadores lógicos no ambiente R.

Operador Descrição
! Realiza a negação lógica
& Realiza a conjunção lógica elemento a elemento (vetorial)
&& Realiza a conjunção lógica avaliando apenas o primeiro elemento
| Realiza a disjunção lógica elemento a elemento (vetorial)
|| Realiza a disjunção lógica avaliando apenas o primeiro elemento
xor() Realiza a disjunção exclusiva (XOR), retornando TRUE apenas se exatamente uma das condições for verdadeira


Código 1.24. Exemplos de uso dos operadores lógicos no ambiente R.

# ---------------------------------------
# Exemplos de Uso dos Operadores Lógicos
# ---------------------------------------

# --- Exemplo 1. Operador lógico E (&&) ---

x           <- TRUE
y           <- FALSE

resultado1  <- x && y  # Verificando se ambos x e y são verdadeiros

print(resultado1)      # Saída: FALSE
[1] FALSE
# --- Exemplo 2. Operador lógico OU (||) ---

x           <- TRUE
y           <- FALSE

resultado2  <- x || y  # Verificando se pelo menos um entre x ou y é verdadeiro

print(resultado2)      # Saída: TRUE
[1] TRUE
# --- Exemplo 3. Operador lógico NÃO (!) ---

d           <- TRUE

resultado3  <- !d      # Invertendo o valor lógico de d

print(resultado3)      # Saída: FALSE
[1] FALSE
# --- Exemplo 4. Verificação de condições compostas em vetores ---

idades          <- c(25, 16, 30, 18, 22)
sexo            <- c("Masculino", "Feminino", "Feminino", "Masculino", "Masculino")
possui_cartao   <- c(TRUE, FALSE, TRUE, TRUE, FALSE)

elegiveis       <- idades >= 18 & sexo == "Feminino" & possui_cartao # Indivíduos elegíveis
elegiveis
[1] FALSE FALSE  TRUE FALSE FALSE
# --- (a) Idade dos elegíveis para o desconto ---

print(paste("Idades:", idades[elegiveis]))
[1] "Idades: 30"
# --- (b) Sexo dos elegíveis para o desconto ---

print(paste("Sexo:", sexo[elegiveis]))
[1] "Sexo: Feminino"


1.8. Estruturas Condicionais


As estruturas condicionais constituem mecanismos essenciais para o controle do fluxo de execução de um programa. Mediante a avaliação de expressões lógicas, permitem decidir quais blocos de código devem ser executados ou ignorados, dependendo das condições definidas. Dessa forma, o comportamento do script torna-se dinâmico e adaptável, possibilitando que diferentes cenários sejam tratados de maneira flexível e eficiente conforme as regras estabelecidas. No ambiente R, as principais estruturas condicionais incluem as instruções if, if...else e ifelse(), além da estrutura switch(), cada uma adequada a contextos específicos, como decisões simples, bifurcações lógicas ou seleção entre múltiplas alternativas.


1.8.1. if



A estrutura if permite executar um bloco de código apenas se uma condição lógica for avaliada como TRUE. Caso contrário, o bloco é ignorado, e nenhuma outra ação é tomada. É utilizada em decisões simples, nas quais interessa executar ou não um único trecho de código. Um exemplo de uso dessa estrutura é apresentado no Código 1.25.


Código 1.25. Exemplo de uso da estrutura condicional if no ambiente R.

# ---------------------------------
# Exemplo de Uso da Estrutura `if`
# ---------------------------------

# --- 1. Definir, por exemplo, um vetor x (de tamanho 1) com valor 10 ---

x     <- 10

# --- 2. Aplicação da estrutura `if` ---

if (x > 5)
{
  print("O valor é maior que 5.")
}
[1] "O valor é maior que 5."


1.8.2. if...else



A estrutura if...else amplia a lógica do if, permitindo especificar um bloco alternativo a ser executado quando a condição não for satisfeita. Assim, garante-se que sempre haverá um caminho a ser percorrido, independentemente do resultado lógico da condição. Exemplos de uso dessa estrutura são apresentados no Código 1.26.


Código 1.26. Exemplos de uso da estrutura condicional if...else no ambiente R.

# -----------------------------------------
# Exemplos de Uso da Estrutura `if...else`
# -----------------------------------------

# --- Exemplo 1. Verificação de maioridade ---

idade         <- 22

if (idade >= 18) {
  print("Você é maior de idade.")
} else {
  print("Você é menor de idade.")
}
[1] "Você é maior de idade."
# --- Exemplo 2. Verificação de paridade ---

numero        <- 15

if (numero %% 2 == 0) {
  print("O número é par.")
} else {
  print("O número é ímpar.")
}
[1] "O número é ímpar."
# --- Exemplo 3. Verificação de dia da semana ---

dia_semana    <- "segunda"

if (dia_semana == "sábado" | dia_semana == "domingo") {
  print("É final de semana.")
} else {
  print("É dia útil.")
}
[1] "É dia útil."
# --- Exemplo 4. Classificação de temperatura ---

temperatura   <- 28

if (temperatura < 0) {
  print("Muito frio")
  } else if (temperatura >= 0 & temperatura < 10) {
    print("Frio")
    } else if (temperatura >= 10 & temperatura < 20) {
      print("Agradável")
      } else if (temperatura >= 20 & temperatura < 30) {
        print("Quente")
        } else {
          print("Muito quente")
          }
[1] "Quente"
# Exemplo 5. Avaliação de condições combinadas

idade         <- 25
renda_anual   <- 50000
estado_civil  <- "solteiro"

if (idade >= 18 & idade <= 35 & renda_anual > 30000 & estado_civil == "solteiro") {
  print("Elegível para empréstimo especial")
  } else if (idade >= 25 & idade <= 45 & renda_anual > 40000) {
    print("Elegível para crédito adicional")
    } else if (idade > 60 & renda_anual > 25000) {
      print("Elegível para desconto sênior")
      } else {
        print("Condições não atendidas para benefícios especiais")
        }
[1] "Elegível para empréstimo especial"


1.8.3. ifelse



A estrutura ifelse é uma forma vetorizada de avaliação condicional em R, particularmente útil quando se deseja aplicar condições a cada elemento de um vetor (ou lista). Ela avalia a condição para cada elemento individualmente, retornando um vetor de respostas com o mesmo comprimento do vetor (ou lista) de entrada. A sintaxe geral dessa estrutura é descrita como ifelse(teste, sim, nao) em que:


  • teste: é a condição a ser avaliada. Pode ser uma expressão lógica (que retorna TRUE ou FALSE) ou um vetor de expressões lógicas.
  • sim: valor a ser retornado se teste for verdadeiro (TRUE). Pode ser um valor único ou um vetor do mesmo comprimento de teste.
  • nao: valor a ser retornado se teste for falso (FALSE). Pode ser um valor único ou um vetor do mesmo comprimento de teste.


O Código 1.27 ilustra alguns exemplos de uso dessa estrutura.


Código 1.27. Exemplos de uso da estrutura condicional ifelse no ambiente R.

# -------------------------------------
# Exemplo de Uso da Estrutura `ifelse`
# -------------------------------------

# --- Exemplo 1. Verificação de maioridade ---

dados         <- data.frame(Nome = c("Ana", "João", "Maria", "Pedro"),
                            Idade = c(25, 17, 30, 16))

dados$Status  <- ifelse(dados$Idade >= 18, "Maior de idade", "Menor de idade")
dados
   Nome Idade         Status
1   Ana    25 Maior de idade
2  João    17 Menor de idade
3 Maria    30 Maior de idade
4 Pedro    16 Menor de idade
# --- Exemplo 2. Classificação de notas em conceitos ---

notas         <- c(78, 85, 60, 92, 45)
conceitos     <- ifelse(notas >= 90, "A",
                        ifelse(notas >= 80, "B",
                               ifelse(notas >= 70, "C",
                                      ifelse(notas >= 60, "D", "F"))))
conceitos
[1] "C" "B" "D" "A" "F"
# --- Exemplo 3. Cálculo de descontos progressivos

valor_compra  <- c(50, 100, 150, 200, 250)
desconto      <- ifelse(valor_compra < 100, valor_compra * 0.05,
                        ifelse(valor_compra >= 100 & valor_compra < 150, valor_compra * 0.1,
                               ifelse(valor_compra >= 150 & valor_compra < 200, valor_compra * 0.15,
                                      ifelse(valor_compra >= 200, valor_compra * 0.2, 0))))
valor_final   <- valor_compra - desconto

resultado     <- data.frame('Valor_Compra' = valor_compra, 
                            'Desconto' = desconto, 
                            'Valor_Final' = valor_final)
resultado
  Valor_Compra Desconto Valor_Final
1           50      2.5        47.5
2          100     10.0        90.0
3          150     22.5       127.5
4          200     40.0       160.0
5          250     50.0       200.0


1.8.4. switch



A estrutura switch é utilizada quando há múltiplas alternativas possíveis, funcionando como uma alternativa eficiente a várias instruções if...else encadeadas. Dependendo do valor fornecido, o switch() seleciona e executa o bloco de código correspondente. Pode receber tanto argumentos numéricos quanto caracteres, sendo particularmente útil para simplificar decisões com múltiplas ramificações. O Código 1.28 ilustra alguns exemplos de uso dessa estrutura


Código 1.28. Exemplos de uso da estrutura condicional switch no ambiente R.

# -------------------------------------
# Exemplo de Uso da Estrutura `switch`
# -------------------------------------

# --- Exemplo 1. Dias da semana ---

dia_semana  <- "segunda"

switch(dia_semana,
       "segunda" = "Primeiro dia útil da semana",
       "quarta" = "Meio da semana",
       "sexta" = "Último dia útil da semana",
       "Outro dia da semana")
[1] "Primeiro dia útil da semana"
# --- Exemplo 2. Conversão de códigos de status HTTP para mensagens ---

codigo_status <- '404'

mensagem      <- switch(codigo_status,
                        '200' = "OK",
                        '404' = "Página não encontrada",
                        '500' = "Erro interno do servidor",
                        "Código não reconhecido")
print(mensagem)
[1] "Página não encontrada"
# --- Exemplo 3. Seleção de operações matemáticas ---

operacao      <- "*"

resultado     <- switch(operacao,
                        "+" = 10 + 5,
                        "-" = 10 - 5,
                        "*" = 10 * 5,
                        "/" = 10 / 5,
                        "Operação inválida")
print(resultado)
[1] 50


1.9. Funções


No ambiente R, as funções constituem blocos de código destinados a executar tarefas específicas, promovendo modularidade, reutilização e clareza no desenvolvimento de algoritmos. A definição de uma função inicia-se com a palavra-chave function, precedida pelo nome atribuído à função e por uma lista de argumentos entre parênteses, os quais permitem parametrizar o seu comportamento. No interior do corpo da função, delimitado por chaves {}, são especificadas as operações que devem ser realizadas. O valor resultante pode ser explicitamente retornado através da instrução return(), embora, por convenção, o R retorne implicitamente o valor da última expressão avaliada, mesmo sem o uso do return(). Em termos de sintaxe, a estrutura básica de uma função no R é ilustrada no Código 1.29.


Código 1.29. Estrutura básica de uma função no ambiente R.

# ---------------------------------------------
# Estrutura Básica de uma Função no Ambiente R
#----------------------------------------------

nome            <- function(argumento_1, ..., argumento_n) 
{
    # Corpo da função:
    
    # Aqui vão as instruções que serão executadas pela função.
    
    return(operacao_final)
}


em que:


  • nome: refere-se ao identificador atribuído à função. É essencial escolher nomes claros e descritivos, respeitando as convenções de nomenclatura do R (como evitar espaços, acentos ou nomes reservados).

  • argumento_1, ..., argumento_n: representam os parâmetros formais da função, ou seja, as entradas que ela receberá para realizar as operações pretendidas. São definidos dentro dos parênteses da expressão function(), separados por vírgulas.

  • corpo da função: é o bloco de código entre chaves {} que contém as instruções a serem executadas quando a função é chamada. O corpo pode incluir operações aritméticas, chamadas a outras funções, estruturas condicionais (if, if...else), laços de repetição (for, while), entre outros. A estrutura lógica desse bloco deve ser bem delimitada para garantir o correto funcionamento da função.

  • return(): é a instrução que define explicitamente qual objeto deve ser devolvido como resultado da execução da função. Embora o uso de return() não seja obrigatório (uma vez que o R retorna automaticamente o valor da última expressão avaliada), seu uso é recomendado por razões de clareza, especialmente em funções mais longas ou com múltiplos caminhos de execução.


Alguns exemplos de funções são exibidas no Código 1.30.


Código 1.30. Exemplo de funções no ambiente R.

# ----------------------------------
# Exemplos de Funções no Ambiente R
#-----------------------------------

# --- Exemplo 1. Função que realiza a soma de dois números ---

soma        <- function(a, b) 
{
  resultado <- a + b
  return(resultado)
}

soma(2,3) # Saida: 5
[1] 5
# --- Exemplo 2. Função para calcular a média aritmética de um vetor ---

media       <- function(valores) 
{
  soma      <- sum(valores)
  tamanho   <- length(valores)
  media     <- soma / tamanho
  return(media)
}

vetor       <- c(2, 4, 6, 8, 10)
resultado   <- media(vetor)

cat("A média do vetor é:", resultado, "\n")
A média do vetor é: 6 
# --- Exemplo 3. Função para calcular o Índice de Massa Corporal (IMC) ---

calcular_imc    <- function(peso, altura) 
{
  # Verificar se os argumentos são válidos

  if (peso <= 0 || altura <= 0) 
  {
    stop("O peso e a altura devem ser valores positivos.")
  }
  
  # Calcular o IMC (com duas casas decimais)
    
  imc <- round(peso / (altura ^ 2), 2)
  
  return(imc)
}

peso            <- 102   # Peso em quilogramas
altura          <- 1.80  # Altura em metros

imc_calculado   <- calcular_imc(peso, altura)

cat("O IMC calculado é:", imc_calculado, "\n")
O IMC calculado é: 31.48 


1.9.1. Funções Mínimas



As funções podem ser definidas de forma minimalista, originando o que se denomina funções mínimas. TEssas funções caracterizam-se por conter apenas uma única expressão em seu corpo, dispensando tanto o uso das chaves {} para delimitar o bloco de código quanto a necessidade explícita da instrução return(). Nessa forma de declaração, o valor produzido pela expressão é automaticamente devolvido como resultado da função, conferindo concisão e simplicidade ao código. Esse recurso é útil em situações que exigem operações rápidas e diretas, sem a necessidade de estruturação mais elaborada. Alguns exemplos destes tipos de funções são exibidos no Código 1.31.


Código 1.31. Exemplo de funções mínimas no ambiente R.

# ------------------------------------------
# Exemplos de Funções Mínimas no Ambiente R
#-------------------------------------------

# --- Exemplo 1. Função mínima que realiza a soma de dois números ---

soma <- function(a, b) a + b
soma(2, 3)  # Saída: 5
[1] 5
# --- Exemplo 2. Função mínima que calcula o quadrado de um número ---

quadrado <- function(x) x^2
quadrado(4)  # Saída: 16
[1] 16
# --- Exemplo 3. Função mínima que converte graus Celsius em Fahrenheit ---

celsius_para_fahrenheit <- function(temp) (9/5) * temp + 32
celsius_para_fahrenheit(25)  # Saída: 77
[1] 77
# --- Exemplo 4. Função mínima que verifica se um número é par ---

paridade <- function(x) x %% 2 == 0
paridade(10)  # Saída: TRUE
[1] TRUE


1.10. Laços de Repetição


Os conceitos de “looping”, “cycling”, “iterating” ou simplesmente replicação de instruções têm raízes muito anteriores à era dos computadores, remontando a práticas humanas de sistematização e repetição de tarefas. Na programação, esses termos referem-se ao ato de automatizar processos compostos por múltiplas etapas, organizando sequências de operações de forma eficiente e estruturada. Trata-se, em essência, de agrupar e repetir blocos de código sempre que padrões semelhantes de execução são necessários. Todas as linguagens modernas de programação, incluindo o R, oferecem mecanismos específicos para essa finalidade, conhecidos como laços de repetição ou estruturas de iteração. De modo geral, distinguem-se dois grandes grupos dessas construções:


  • Laços controlados por contagem, representados principalmente pela estrutura for, em que se determina previamente o número de repetições, usualmente por meio de um índice ou contador que é atualizado a cada ciclo de execução. São apropriados quando se conhece, de antemão, o número exato de iterações desejadas.


  • Laços controlados por condição, representados pelas estruturas while e repeat, nos quais a repetição está vinculada à avaliação de uma expressão lógica. No caso do while, a condição é testada antes de cada iteração, de modo que o laço poderá nunca ser executado, caso a condição inicial seja falsa. Já o repeat executa indefinidamente o bloco de instruções, sem testar qualquer condição no início ou no fim do ciclo. A repetição prossegue até que, dentro do corpo do laço, seja avaliada uma condição que acione a instrução break, encerrando a iteração.


1.10.1. for



O laço de repetição for é empregado em situações nas quais o número de iterações é conhecido de antemão. Essa estrutura permite percorrer sequências de forma sistemática, sendo particularmente útil na automação de tarefas que envolvem processamento de vetores, listas ou estruturas indexadas. Considere, por exemplo, um cenário em que se deseja calcular e exibir o quadrado dos números inteiros de 1 a 10. Embora seja possível realizar esse cálculo manualmente para cada valor, essa abordagem torna-se rapidamente inviável à medida que o intervalo se amplia. Com o uso de um laço for, é possível percorrer a sequência de forma eficiente e aplicar a operação desejada a cada elemento. Alguns exemplos de uso do laço de repetição for são ilustrados no Código 1.32.


Código 1.32. Exemplos de uso do laço de repetição for no ambiente R.

# ------------------------------------------
# Exemplo de Uso do Laço de Repetição `for`
# ------------------------------------------

# --- Exemplo 1. Calcular e exibir o quadrado dos números de 1 a 10 ---

for (i in 1:10) 
{
  resultado <- i^2
  print(paste("O quadrado de", i, "é", resultado))
}
[1] "O quadrado de 1 é 1"
[1] "O quadrado de 2 é 4"
[1] "O quadrado de 3 é 9"
[1] "O quadrado de 4 é 16"
[1] "O quadrado de 5 é 25"
[1] "O quadrado de 6 é 36"
[1] "O quadrado de 7 é 49"
[1] "O quadrado de 8 é 64"
[1] "O quadrado de 9 é 81"
[1] "O quadrado de 10 é 100"
# --- Exemplo 2. Iteração sobre uma matriz ---

matriz    <- matrix(1:12, nrow = 3, ncol = 4)

for (i in 1:nrow(matriz)) 
{
  # Inicializando soma para cada linha
  
  soma    <- 0
  
  # Iteração sobre as colunas da matriz
  
  for (j in 1:ncol(matriz)) 
  {
    soma  <- soma + matriz[i, j]
  }
  print(paste("Soma da linha", i, ":", soma))
}
[1] "Soma da linha 1 : 22"
[1] "Soma da linha 2 : 26"
[1] "Soma da linha 3 : 30"
# Exemplo 3. Utilizando 'break' e 'next' dentro de um laço de repetição do tipo 'for'

numeros   <- c(2, 5, 7, 10, 3, 8)

for (num in numeros) 
{
  if (num %% 2 == 0) {
    
    cat(num, "é par.\n")
  
    } else if (num %% 5 == 0) {
    
      cat(num, "é múltiplo de 5. Avançando para o próximo número.\n")
    
      next  # Pula para a próxima iteração sem executar o restante do código
  
      } else {
    
        cat(num, "não é par nem múltiplo de 5.\n")
  
        }
  
  if (num > 7) {
    
    cat("Número maior que 7 encontrado. Interrompendo o laço de repetição.\n")
    
    break  # Interrompe o laço de repetição
  }
}
2 é par.
5 é múltiplo de 5. Avançando para o próximo número.
7 não é par nem múltiplo de 5.
10 é par.
Número maior que 7 encontrado. Interrompendo o laço de repetição.


1.10.2. while



O laço de repetição while é empregado em situações nas quais não se conhece previamente o número exato de iterações a serem executadas. Sua execução está condicionada à verificação de uma expressão lógica antes de cada ciclo, garantindo que o bloco de código seja repetido enquanto a condição especificada permanecer verdadeira. Caso a condição seja inicialmente falsa, o laço poderá não ser executado nenhuma vez. Essa estrutura é particularmente útil quando o critério de parada está associado a valores que podem variar durante a execução do código, como resultados de cálculos, leituras de dados ou ocorrências de eventos. Alguns exemplos do uso do laço de repetição while são apresentados no Código 1.33.


Código 1.33. Exemplos de uso do laço de repetição while no ambiente R.

# --------------------------------------------
# Exemplo de Uso do Laço de Repetição `while`
# --------------------------------------------

# --- Exemplo 1. Somar números consecutivos até que a soma atinja ou ultrapasse 50 ---

soma        <- 0   # Variável que acumulará a soma dos números
contador    <- 1   # Variável que controla qual número será somado a seguir

while (soma < 50) 
{
  soma      <- soma + contador
  contador  <- contador + 1
  
  print(paste("Soma parcial:", soma))
}
[1] "Soma parcial: 1"
[1] "Soma parcial: 3"
[1] "Soma parcial: 6"
[1] "Soma parcial: 10"
[1] "Soma parcial: 15"
[1] "Soma parcial: 21"
[1] "Soma parcial: 28"
[1] "Soma parcial: 36"
[1] "Soma parcial: 45"
[1] "Soma parcial: 55"
# --- Exemplo 2. Crescimento populacional ---

populacao_inicial <- 100
populacao_atual   <- populacao_inicial
ano               <- 0

while (populacao_atual < 1000)
{
  ano             <- ano + 1
  populacao_atual <- populacao_atual + (populacao_atual * 2)  
}

rbind("A população atingiu 1000 indivíduos no ano:" = ano,
      "População atual:" = populacao_atual)
                                            [,1]
A população atingiu 1000 indivíduos no ano:    3
População atual:                            2700
# --- Exemplo 3. Cálculo do tempo para alcançar um objetivo financeiro ---

investimento_inicial    <- 10000  # Investimento inicial (em R$)
taxa_juros_anual        <- 0.06   # Taxa de juros anual (6% ao ano)
objetivo                <- 20000  # Objetivo de investimento (em R$)
saldo                   <- investimento_inicial
anos                    <- 0

while (saldo < objetivo) 
{
  saldo     <- saldo * (1 + taxa_juros_anual)  # Atualização do saldo com juros compostos
  anos      <- anos + 1                        # Contagem dos anos
}

cat("Para atingir ou exceder R$", objetivo, "serão necessários", anos, "anos.\n")
Para atingir ou exceder R$ 20000 serão necessários 12 anos.


1.10.3. repeat



O laço de repetição repeat no R é utilizado para criar ciclos indefinidos, isto é, laços que executam continuamente o bloco de código até que uma condição específica seja satisfeita e interrompa sua execução. Diferentemente do while, o laço repeat não possui uma condição de parada declarada na própria estrutura; a interrupção ocorre apenas quando se emprega a instrução break dentro do corpo do laço. Por esse motivo, deve-se ter cautela no uso do repeat, pois a ausência de um critério de saída pode levar à criação de loops infinitos. Alguns exemplos do uso do laço de repetição while são apresentados no Código 1.34.


Código 1.34. Exemplos de uso do laço de repetição repeat no ambiente R.

# ---------------------------------------------
# Exemplo de Uso do Laço de Repetição `repeat`
# ---------------------------------------------

# --- Exemplo 1. Gerar números aleatórios até obter um número maior que 0.9 ---

contador    <- 0 # Inicialização da variável

repeat 
{
  numero    <- runif(1) # Geração de um número aleatório entre 0 e 1
  contador  <- contador + 1
  
  print(paste("Número gerado:", numero))
  
  if (numero > 0.9) 
  {
    print(paste("Número maior que 0.9 encontrado após", contador, "tentativas."))
    break
  }
}
[1] "Número gerado: 0.700726005947217"
[1] "Número gerado: 0.0316534009762108"
[1] "Número gerado: 0.0135354322846979"
[1] "Número gerado: 0.826122378697619"
[1] "Número gerado: 0.134138161316514"
[1] "Número gerado: 0.0169732880312949"
[1] "Número gerado: 0.974496003938839"
[1] "Número maior que 0.9 encontrado após 7 tentativas."
# Exemplo 2. Simulação do comportamento de um sistema de produção em lotes ---


tamanho_lote        <- 10
num_lotes           <- 5
tempo_processamento <- matrix(runif(num_lotes * tamanho_lote, 5, 10), 
                              ncol = tamanho_lote)
tempo_total         <- 0
lote_atual          <- 0

repeat 
{
  lote_atual        <- lote_atual + 1
  
  # Verificar se todos os lotes foram processados
  
  if (lote_atual > num_lotes) 
  {
    break  # Sai do laço quando todos os lotes foram processados
  }
  
  # Tempo de processamento do lote atual
  
  tempo_lote        <- sum(tempo_processamento[lote_atual, ])
  cat("Processando lote", lote_atual, "- Tempo total de", tempo_lote, "horas.\n")
}
Processando lote 1 - Tempo total de 69.65277 horas.
Processando lote 2 - Tempo total de 69.96812 horas.
Processando lote 3 - Tempo total de 69.80551 horas.
Processando lote 4 - Tempo total de 75.39155 horas.
Processando lote 5 - Tempo total de 72.28639 horas.


1.11. Família apply


A família apply no ambiente R compreende um conjunto de funções vetorizadas projetadas para aplicar operações de forma eficiente sobre estruturas de dados como vetores, matrizes, listas e quadros de dados (Data Frames). Essas funções permitem processar e cruzar dados de múltiplas formas, evitando a necessidade do uso explícito de laços de repetição, concentrando-se diretamente na operação desejada sobre os dados. Entre os membros mais utilizados dessa família destacam-se:


  • apply(): aplica funções ao longo das margens (linhas ou colunas) de matrizes ou quadros de dados;
  • lapply(): aplica uma função a cada elemento de uma lista, retornando sempre uma lista como resultado;
  • sapply(): variação de lapply() que tenta simplificar o resultado para um vetor ou matriz, quando possível;
  • tapply(): aplica uma função a subconjuntos de um vetor, definidos por fatores.


Para ilustrar a utilização prática das funções da família apply, será considerado o clássico conjunto de dados iris, disponível nativamente no R. Esse conjunto reúne medições de comprimento e largura das sépalas e pétalas de três espécies de íris (setosa, versicolor e virginica), conforme ilustrado na Figura 1.2.


Figura 1.2. Espécies de planta íris: setosa, versicolor e virginica.


capa


Fonte. Iris Flower Dataset | Kaggle. Acesso: Julho, 2025.


Cada linha desse conjunto de dados representa uma observação individual de uma flor de íris e inclui as seguintes variáveis:


  • Sepal.Length: comprimento da sépala, em centímetros;
  • Sepal.Width: largura da sépala, em centímetros;
  • Petal.Length: comprimento da pétala, em centímetros;
  • Petal.Width: largura da pétala, em centímetros;
  • Species: espécie da íris, indicada por um dos três nomes: setosa, versicolor ou virginica.


1.11.1. apply



A função apply é utilizada para aplicar funções às margens de matrizes/quadro de dados. Para especificar em qual margem (ou margens) a função deve operar, utiliza-se o parâmetro MARGIN: ao definir MARGIN = 1, a função é aplicada nas linhas; com MARGIN = 2, nas colunas; e com MARGIN = c(1, 2), tanto nas linhas quanto nas colunas simultaneamente. Além disso, é necessário indicar a função a ser aplicada usando o argumento FUN, e quaisquer outros argumentos dessa função devem ser fornecidos através do argumento .... Um exemplo de uso do apply encontra-se no Código 1.35, no qual se calcula a média das quatro variáveis numéricas do conjunto de dados iris. Para tanto, seleciona-se apenas as primeiras quatro colunas (as variáveis numéricas) e aplica-se a função mean sobre as colunas, estabelecendo MARGIN = 2.


Código 1.35. Uso da função apply no ambiente R.

# ---------------------------------
# Exemplo de Uso da Função `apply`
# ---------------------------------

# --- Média das variáveis numéricas do conjunto iris

medias_iris   <- apply(X      = iris[, 1:4],   # Seleção apenas das variáveis numéricas
                       MARGIN = 2,             # Aplicação ao longo das colunas
                       FUN    = mean)          # Função desejada
print(medias_iris)
Sepal.Length  Sepal.Width Petal.Length  Petal.Width 
    5.843333     3.057333     3.758000     1.199333 


1.11.2. tapply



A função tapply é empregada no ambiente R para aplicar uma função específica a subconjuntos de um vetor, definidos a partir dos níveis de uma ou mais variáveis categóricas indicadas pelo argumento INDEX. Em termos conceituais, tapply se assemelha às funções aggregate e by, pois todas visam sumarizar ou manipular dados por grupos. Contudo, tapply destaca-se pela simplicidade de sintaxe e pela flexibilidade no tratamento direto de vetores numéricos ou de interesse. Um exemplo encontra-se no Código 1.36, no qual se calcula a média do comprimento das pétalas (Petal.Length) para cada espécie de íris no conjunto de dados iris.


Código 1.36. Uso da função tapply no ambiente R.

# ----------------------------------
# Exemplo de Uso da Função `tapply`
# ----------------------------------

# --- Calcular a média do comprimento das pétalas por espécie ---

medias_petalas <- tapply(X     = iris$Petal.Length,   # Vetor cujos valores serão agregados
                         INDEX = iris$Species,        # Fator que define os grupos (as espécies)
                         FUN   = mean)                # Função desejada (média)
                         
print(medias_petalas)
    setosa versicolor  virginica 
     1.462      4.260      5.552 


1.11.3. lapply



A função lapply é projetada para aplicar uma função específica a cada elemento de uma lista, vetor ou quadro de dados, devolvendo sempre uma lista como resultado, independentemente da forma ou tamanho dos objetos produzidos pela função aplicada. Para exemplificar o uso da função lapply, considere novamente o conjunto de dados iris. Suponhamos que desejamos obter a soma de todos os valores das variáveis numéricas, desconsiderando a espécie das flores. Esse procedimento encontra-se apresentado no Código 1.37.


Código 1.37. Uso da função lapply no ambiente R.

# ----------------------------------
# Exemplo de Uso da Função `lapply`
# ----------------------------------

# --- Calcular a soma das variáveis numéricas do iris ---

somas_iris  <- lapply(X   = iris[, 1:4],   # Seleção apenas das variáveis numéricas
                      FUN = sum)           # Função desejada (soma)
print(somas_iris)
$Sepal.Length
[1] 876.5

$Sepal.Width
[1] 458.6

$Petal.Length
[1] 563.7

$Petal.Width
[1] 179.9


1.11.4. sapply



A função sapply é uma função que permite aplicar uma determinada operação a cada elemento de uma estrutura de dados, como listas, vetores ou quadros de dados, retornando um resultado simplificado sempre que possível. Diferentemente de lapply, que retorna invariavelmente uma lista, sapply tenta reduzir automaticamente a estrutura de saída para um vetor, matriz ou array, caso a coerência dos resultados permita tal simplificação. O argumento simplify controla esse comportamento: quando definido como FALSE, a função se comporta como lapply, retornando uma lista; quando definido como TRUE (padrão), a função tenta simplificar a estrutura do resultado. Para ilustrar o funcionamento de sapply, considere o conjunto iris. Suponhamos que desejamos obter o mínimo de cada variável numérica (as primeiras quatro colunas), desconsiderando a espécie das flores. Esse procedimento encontra-se apresentado no Código 1.38.


Código 1.38. Uso da função sapply no ambiente R.

# ----------------------------------
# Exemplo de Uso da Função `sapply`
# ----------------------------------

# --- Calcular o valor mínimo das variáveis numéricas do iris ---

minimos_iris <- sapply(X   = iris[, 1:4],   # Seleção apenas das variáveis numéricas
                       FUN = min)           # Função desejada (mínimo)
print(minimos_iris)
Sepal.Length  Sepal.Width Petal.Length  Petal.Width 
         4.3          2.0          1.0          0.1