1 Estatística como ferramenta de apoio à decisão

1.1 Exercício

Considerando a conjuntura atual de grande volume de dados, qual a importância fundamental de se dominar a Estatística (incluindo suas vertentes Descritiva e Inferencial) em conjunto com ferramentas computacionais, como o R, para que pesquisadores e analistas possam tomar decisões mais eficazes e aprimorar suas competências?

1.1.1 Resposta

A importância fundamental de dominar a Estatística, em conjunto com ferramentas computacionais como o R, na atual conjuntura de grande volume de dados, reside na capacidade de: Transformar Dados em Conhecimento. A Estatística é um ramo da Matemática Aplicada que permite compreender, analisar e modelar dados, investigando como eles variam. Com a Estatística Descritiva, é possível organizar, resumir e apresentar grandes volumes de informações de forma clara, facilitando o entendimento de fenômenos. Já a Estatística Inferencial e a Modelagem contribuem para ir além da descrição, permitindo fazer previsões, testar hipóteses e extrair conclusões válidas sobre populações a partir de amostras. Extrair Evidências para Decisões. A competência de utilizar ferramentas computacionais (como o R) para trabalhar com dados, inclusive em grandes quantidades, torna pesquisadores e analistas diferenciados. Isso porque eles conseguem extrair evidências sólidas dos dados que apoiam e justificam suas decisões, em vez de depender de intuições. Aprimorar a Competência e os Resultados. A combinação do conhecimento estatístico com a proficiência em ferramentas de análise de dados oferece um conjunto de habilidades que permite explorar mais profundamente as informações disponíveis. Isso leva a uma melhor compreensão da utilização das ferramentas, à obtenção de resultados mais precisos e, consequentemente, ao aprimoramento contínuo da competência do profissional na tomada de decisões. Em resumo, a sinergia entre a Estatística e as ferramentas computacionais é crucial para transformar a abundância de dados em uma vantagem estratégica, capacitando profissionais a realizar descobertas, validar insights e fundamentar decisões de maneira mais robusta e eficaz.

1.1.2 Exercício

Por que decisões baseadas em dados tendem a ter maior probabilidade de sucesso em comparação com decisões baseadas apenas na intuição ou experiência?

1.1.3 Resposta

Porque proporcionam maior precisão, agilidade, adaptabilidade, redução de riscos e favorecem a inovação, desde que as informações sejam aplicadas de maneira estratégica e eficaz.

1.2 Exercício

Quais são os desafios da digitalização da sociedade?

1.2.1 Resposta

Informações compartilhadas, mas tecnologia não (concentração de poder); necessidade de segurança das informações das pessoas, corporações e Estados; utilização ética dos dados.
Uma questão importante para reflexão é se essa digitalização irá ser utilizada como instrumento da dominação das pessoas ou como empoderamento do cidadão.

1.3 Exercício

Apresente alguns aspectos que caracterizam o momento atual (2026) da digitalização da sociedade.

1.3.1 Resposta

Incremento das decisões baseadas em dados - BI
Incremento de bases de dados de toda ordem
Incremento da IA
Deficiência na capacidade de organização, análise e interpretação dos dados
Explosão de demanda por ciência da computação
Cursos de análise de dados – Ciência de Dados
Reversão da aversão à matemática – Estatística é Matemática

1.4 Exercício

Por que estatísticos frequentemente trabalham com uma amostra em vez de uma população inteira?

####Resposta Estatísticos frequentemente trabalham com uma amostra (um subconjunto da população) em vez da população inteira porque, na maioria das vezes, é impraticável, demorado ou caro observar ou medir cada elemento da população (especialmente se ela for muito grande ou infinita). O objetivo é usar a amostra para fazer inferências sobre as características da população.

1.5 Exercício

Qual é a característica mais crucial que uma amostra deve possuir para garantir que as conclusões tiradas dela sejam válidas para a população?

1.5.1 Resposta

A característica mais crucial que uma amostra deve possuir para que as conclusões sejam válidas é a representatividade. Isso significa que a amostra deve ser selecionada de forma a refletir fielmente as características da população da qual foi extraída, garantindo que as informações observadas no subconjunto (amostra) possam ser generalizadas com confiança para o “todo” (população).

1.6 Exercício

Qual é a diferença fundamental entre um Parâmetro e um Estimador em estatística, em termos de o que cada um descreve e sua natureza (fixo ou variável)?

1.6.1 Resposta

A diferença fundamental é a seguinte:
Um Parâmetro é uma medida numérica que descreve uma característica de toda a população. Ele é um valor fixo (embora geralmente desconhecido, pois é impossível medir todos os indivíduos de uma população imensa) e é representado por letras gregas (ex: μ para média populacional, σ para desvio padrão populacional).
Um Estimador é uma regra ou fórmula matemática que utilizamos em uma amostra para tentar avaliar o valor desse parâmetro populacional. Ele é uma variável aleatória, pois seu resultado depende diretamente da amostra específica que foi coletada, e é representado por letras latinas com um “chapéu” ou barra (ex: X̄ para média amostral, p̂ para proporção amostral).

1.7 Exercício

Na prática estatística, por que os Parâmetros são frequentemente desconhecidos, e como os conceitos de Estimador e Estimativa se relacionam para nos ajudar a contornar essa dificuldade?

1.7.1 Resposta

Os Parâmetros são frequentemente desconhecidos porque representam características de toda a população, e na maioria dos casos é inviável, impossível ou economicamente proibitivo medir todos os elementos dessa população (como no exemplo da altura de todos os brasileiros em tempo real).
Para contornar essa dificuldade, utilizamos um Estimador, que nos fornece o método ou a fórmula para calcular uma aproximação do parâmetro. Quando aplicamos essa regra ou fórmula aos dados de uma amostra específica, obtemos um valor numérico concreto, que é a Estimativa.
Em resumo, o Estimador é a “receita” (a regra ou fórmula) e a Estimativa é o “bolo” (o valor numérico resultante) que usamos para inferir sobre o Parâmetro desconhecido da população.

1.8 Exercício

Preencha o quadro abaixo

Escalas de Medida segundo Hair et al.
Escala Tipo de Dado Propriedade Principal Exemplo Prático
Nominal Não Métrico Identificação / Categoria
Ordinal Ordem / Ranking
Intervalar Distância Constante
Razão Zero Absoluto

1.8.1 Resposta

Escalas de Medida segundo Hair et al. (2009)
Escala Tipo de Dado Propriedade Principal Exemplo Prático
Nominal Não Métrico Identificação / Categoria Tipo de Sangue
Ordinal Não Métrico Ordem / Ranking Nível de Satisfação
Intervalar Métrico Distância Constante Temperatura (°C)
Razão Métrico Zero Absoluto Renda Mensal ($)

1.9 Exercício

No contexto dos “Erros de Medida”, como os conceitos de Validade e Confiabilidade se relacionam e por que são cruciais para um pesquisador ao garantir a qualidade dos dados coletados?

1.9.0.1 Resposta

Validade e Confiabilidade são duas características cruciais que os pesquisadores devem considerar para mitigar os “Erros de Medida”.
A Validade foca em garantir que a medida representa precisamente aquilo que se espera medir. Ou seja, ela pergunta: “Estamos medindo a coisa certa?”. Por exemplo, um questionário é válido se as perguntas realmente avaliam o que se propõem a avaliar (como satisfação do cliente, e não apenas o humor do dia). A garantia da validade começa com uma compreensão clara do que deve ser medido e a formulação da “pergunta correta”.
A Confiabilidade foca na consistência e precisão da medida, indicando o grau em que a variável observada mede o valor “verdadeiro” e está “livre de erro aleatório”. Ela pergunta: “Estamos medindo consistentemente e sem erro?”. Medidas confiáveis mostram maior consistência se repetidas, independentemente de estarem medindo a “coisa certa” ou não.
A relação e importância: Ambas são cruciais porque uma medida deve ser tanto válida (medindo o que se propõe a medir) quanto confiável (fazendo-o de forma consistente e precisa) para que os dados sejam de alta qualidade e representativos dos valores “verdadeiros”. Uma medida pode ser confiável, mas não válida (sempre dá o mesmo resultado, mas não mede o que deveria), e uma medida válida, mas não confiável (mede o que deveria, mas de forma inconsistente). O ideal é buscar medidas que possuam ambas as qualidades para minimizar o impacto dos erros de medida e garantir conclusões robustas.

1.10 Exercício

O que diferencia dados primários de dados secundários?

1.10.1 Resposta

Dados primários são coletados diretamente pelo pesquisador para um objetivo específico, enquanto dados secundários já foram coletados por terceiros para outros propósitos e são reutilizados na pesquisa atual.

1.11 Exercício

Cite uma vantagem e uma desvantagem da utilização dos dados primários.

1.11.1 Resposta

Vantagem: relevância e alinhamento perfeito com os objetivos da pesquisa.
Desvantagem: maior custo e tempo para coleta e processamento.

1.12 Exercício

Cite exemplos de métodos de coleta de dados primários?

1.12.1 Resposta

Pesquisas, entrevistas, experimentos, observações diretas, grupos focais e diários de campo.

1.13 Exercício

Quais são exemplos de fontes de dados secundários?

1.13.1 Resposta

Relatórios governamentais, artigos científicos, livros, bancos de dados online, registros internos de empresas, notícias e mídias sociais, censo demográfico.

1.14 Exercício

Complete a tabela comparando dados primários e secundários:

Característica Dados Primários Dados Secundários
Origem Coletados por outros para outro propósito.
Custo Geralmente alto.
Controle Nenhum controle sobre a metodologia original.
Atualidade Geralmente muito atual.

Tabela: Diferenças entre Dados Primários e Secundários (Metodologia de Pesquisa)

1.14.1 Resposta

Característica Dados Primários Dados Secundários
Origem Coletados pelo próprio pesquisador. Coletados por outros para outro propósito.
Custo Geralmente alto. Geralmente baixo ou gratuito.
Controle Alto controle sobre a metodologia. Nenhum controle sobre a metodologia original.
Atualidade Geralmente muito atual. Pode estar desatualizado.

Tabela: Diferenças entre Dados Primários e Secundários (Metodologia de Pesquisa)

1.15 Exercício

Dê um exemplo de dado nominal e um de dado ordinal.

1.15.0.1 Resposta:

Nominal: Cor dos olhos (azul, verde, castanho).
Ordinal: Classificação de alimentos do mais ao menos preferido.

1.16 Exercício

O que caracteriza a escala de razão? Dê um exemplo.

1.16.0.1 Resposta:

Possui um zero absoluto significativo, permitindo comparações de proporção como “o dobro de”. Exemplo: comprimento em centímetros.

2 Fundamentos do R

2.1 A concepção do R

Exercício 1: Considerando a evolução das linguagens de programação para análise de dados, discuta a importância da base estatística do R (inspirada no S) e como essa herança contribui para sua robustez no ambiente acadêmico e de pesquisa. Cite os criadores.

Resposta:
A concepção do R é diretamente derivada da linguagem S, desenvolvida nos Bell Labs, o que lhe confere uma base sólida e intrínseca para a computação estatística e gráfica. Essa herança significa que o R foi projetado desde o início com estatísticos e pesquisadores em mente, incorporando estruturas de dados e funções otimizadas para manipulação, análise e visualização de dados de forma nativa. Sua sintaxe facilita as operações matriciais e vetoriais, comuns em estatística. Isso o torna uma ferramenta robusta e flexível para desenvolvimento de novos métodos estatísticos, simulações e análise de dados, sendo amplamente adotado em universidades e centros de pesquisa. Os criadores do R foram Ross Ihaka e Robert Gentleman, da Universidade de Auckland, Nova Zelândia.

Exercício 2: Além de sua forte ligação com a estatística, quais outras características do R o tornaram uma linguagem tão popular para o desenvolvimento e compartilhamento de métodos analíticos em diversas áreas?

Resposta: Além de sua base estatística, a popularidade do R se deve a várias características: * Código Aberto e Gratuito: Ser um software livre e de código aberto remove barreiras de acesso e custo, incentivando sua adoção e contribuindo para uma vasta comunidade de usuários e desenvolvedores.
* Extensibilidade via Pacotes: A arquitetura de pacotes permite que a comunidade contribua com funcionalidades especializadas, tornando o R adaptável a praticamente qualquer domínio de análise (econometria, bioinformática, aprendizado de máquina, etc.).
* Capacidades Gráficas Avançadas: O R oferece ferramentas poderosas para visualização de dados, desde gráficos básicos até visualizações interativas complexas, essenciais para a comunicação de resultados.
* Portabilidade: Pode ser executado em diferentes sistemas operacionais (Windows, macOS, Linux).
* Comunidade Ativa: Uma grande e ativa comunidade oferece suporte, documentação e recursos de aprendizado abundantes.

2.2 O RStudio

Exercício 1: Qual a função primordial do RStudio para um cientista de dados ou pesquisador, e como ele otimiza o fluxo de trabalho em comparação com o uso do console R base?

Resposta: A função primordial do RStudio é servir como uma Ambiente de Desenvolvimento Integrado (IDE) para o R. Ele otimiza o fluxo de trabalho ao integrar diversas ferramentas e funcionalidades essenciais em uma única interface. Enquanto o console R base exige que o usuário execute comandos diretamente e gerencie arquivos e gráficos em programas externos, o RStudio centraliza o editor de código, console, visualizador de variáveis, histórico de comandos, gerenciador de pacotes, visualizador de gráficos e sistema de ajuda. Isso permite um desenvolvimento mais ágil, depuração mais fácil e uma organização mais eficiente dos projetos, tornando o processo de análise de dados muito mais produtivo e menos propenso a erros.


Exercício 2: Imagine que você está desenvolvendo um script complexo em R. Cite e descreva brevemente três painéis do RStudio que seriam cruciais para sua produtividade e depuração nesse cenário.

Resposta: Três painéis cruciais seriam:
* Editor de Código (Source Editor): Essencial para escrever, salvar e organizar o script R. Permite a execução de linhas ou blocos de código diretamente, facilitando a fase de desenvolvimento e teste.
* Console: Onde os comandos R são executados e os resultados são exibidos. É vital para testar comandos individualmente, interagir com o R e visualizar saídas diretas.
* Environment/History (Ambiente/Histórico):
* Environment: Mostra todas as variáveis e objetos criados na sessão atual, seus tipos e, em alguns casos, parte de seu conteúdo. É fundamental para monitorar o estado dos dados e variáveis durante a depuração.
* History: Registra todos os comandos executados, permitindo revisitar, reexecutar ou copiar comandos anteriores, o que é útil para rastrear o fluxo de trabalho e corrigir erros.
* (Opcional - Files/Plots/Packages/Help):
* Plots: Exibe os gráficos gerados pelo código, permitindo a inspeção visual dos resultados.
* Packages: Gerencia a instalação, atualização e carregamento de pacotes R, um aspecto fundamental para estender as funcionalidades do R.
* Help: Fornece acesso rápido à documentação de funções e pacotes, indispensável para entender como usar recursos específicos e resolver dúvidas.

2.3 Pacotes do R

Exercício 1: Explique o conceito de “ecossistema de pacotes” no R. Como ele contribui para a versatilidade da linguagem, e qual a diferença funcional entre install.packages() e library()?

Resposta:
O “ecossistema de pacotes” no R refere-se à vasta coleção de módulos de código, dados e documentação desenvolvidos pela comunidade, que estendem as funcionalidades do R base. Essa abordagem modular permite que o R seja extremamente versátil, pois usuários podem instalar apenas as ferramentas necessárias para suas tarefas específicas (ex: ggplot2 para visualização, dplyr para manipulação de dados, caret para aprendizado de máquina). Isso evita que o R base fique sobrecarregado e permite o desenvolvimento rápido de novas técnicas e métodos.
* install.packages("nome_do_pacote"): Esta função baixa e instala o pacote dos repositórios (como o CRAN) para o seu sistema local. É uma ação que geralmente precisa ser feita apenas uma vez por pacote (ou para atualizá-lo).
* library("nome_do_pacote") ou require("nome_do_pacote"): Esta função carrega o pacote instalado na memória da sessão R atual. As funções e dados contidos no pacote só estarão disponíveis para uso após serem carregados com library() (ou require()).

Exercício 2: Imagine que você precisa utilizar funções avançadas para manipulação de dados que não estão disponíveis no R base. Demonstre, com código, como você adicionaria e ativaria o pacote dplyr em sua sessão de R, supondo que ele ainda não esteja instalado. Qual seria o resultado se você tentasse usar uma função do dplyr sem carregá-lo?

* Resposta: Para adicionar e ativar o pacote dplyr:

# 1. Instalar o pacote (se ainda não estiver instalado)
# install.packages("dplyr")

# 2. Carregar o pacote na sessão atual
library(dplyr)
    Se você tentasse usar uma função do `dplyr` (por exemplo, `mutate()`) sem carregá-lo previamente com `library(dplyr)`, o R emitiria um erro indicando que a função não foi encontrada, geralmente algo como: `Error: 'mutate' could not be found` ou `Error: object 'mutate' not found`. Isso ocorre porque o R só sabe onde encontrar e usar as funções de um pacote depois que ele é explicitamente carregado na sessão.

2.4 Ambiente de programação - as 4 interfaces do RStudio

Exercício 1: Descreva como as quatro principais interfaces do RStudio interagem para fornecer um ambiente coeso para o desenvolvimento de projetos de análise de dados.

Resposta:
As quatro interfaces principais (Editor de Código, Console, Ambiente/Histórico e Arquivos/Gráficos/Pacotes/Ajuda) trabalham em conjunto para criar um fluxo de trabalho integrado:
* O Editor de Código é onde o script é escrito e editado. Trechos de código são enviados para o Console para execução.
* O Console exibe a saída dos comandos, mensagens de erro e permite a interação direta com o R.
* O painel Ambiente monitora os objetos criados no Console, enquanto o Histórico mantém um registro dos comandos executados.
* O painel Arquivos permite navegar e gerenciar arquivos do projeto; Plots exibe visualizações geradas pelo código; Packages facilita a gestão de pacotes; e Help oferece documentação contextual para funções e pacotes, todos acessíveis sem sair do ambiente. Essa integração centralizada minimiza a necessidade de alternar entre diferentes aplicativos, agilizando o desenvolvimento, depuração e organização do projeto.

Exercício 2: Você está analisando um conjunto de dados e precisa verificar quais variáveis estão carregadas na memória, inspecionar um gráfico que acabou de gerar e buscar ajuda sobre uma função específica. Em quais painéis do RStudio você realizaria essas tarefas?

* Resposta:
* Para verificar quais variáveis estão carregadas na memória: Painel Environment (Ambiente).
* Para inspecionar um gráfico que acabou de gerar: Painel Plots (Gráficos), geralmente localizado junto com Files, Packages e Help.
* Para buscar ajuda sobre uma função específica: Painel Help (Ajuda), onde você pode pesquisar a documentação da função.

2.5 Identificadores

Exercício 1: Em R, os identificadores devem seguir regras específicas para serem válidos. Crie dois exemplos de identificadores: um válido e descritivo para uma variável que armazena a média de idade dos participantes de um estudo, e um inválido, explicando por que ele é inválido.

Resposta:
* Identificador Válido e Descritivo: media_idade_participantes
* Explicação: Começa com letra, usa letras minúsculas, números e _ (underscore) para separar palavras, o que é uma boa prática em R (snake_case).
* Identificador Inválido: 1_media_idade
* Explicação: Identificadores em R não pod Exercício 2: Discuta a importância da escolha de bons identificadores (nomes de variáveis, funções, etc.) em projetos de R, especialmente em equipes ou para scripts que serão mantidos a longo prazo.

Resposta:
A escolha de bons identificadores é crucial para a legibilidade, manutenibilidade e colaboração em projetos de R. Nomes descritivos e consistentes tornam o código mais fácil de entender não apenas para quem o escreveu (seja semanas ou meses depois), mas também para outros membros da equipe. Identificadores claros reduzem a ambiguidade, minimizam a necessidade de comentários excessivos e diminuem a probabilidade de erros de lógica ou de refatoração. Em projetos de longo prazo, a manutenção e a expansão do código são significativamente facilitadas quando as variáveis e funções possuem nomes que refletem claramente seu propósito e conteúdo, aderindo a convenções de estilo (como snake_case ou camelCase).

2.6 Tipos de dados - numéricos

Exercício 1: Declare uma variável preco_unitario como um valor numérico decimal (19.99) e outra variável quantidade como um número inteiro (50). Calcule o valor_total e verifique o tipo de dado resultante. Qual a principal diferença entre um número inteiro (integer) e um número real (numeric/double) no R em termos de armazenamento e uso?

Resposta:

        preco_unitario <- 19.99
        quantidade <- 50L # Sufixo 'L' para indicar explicitamente um inteiro
        valor_total <- preco_unitario * quantidade

Diferença: * numeric (ou double): Armazena números de ponto flutuante de precisão dupla, que podem ter casas decimais. É o tipo numérico padrão no R. Ocupa mais memória.
* integer: Armazena números inteiros. Para declarar um inteiro explicitamente, é preciso usar o sufixo L (ex: 10L). Ocupa menos memória que double.
A principal diferença é a precisão e o uso de memória. double é usado para a maioria dos cálculos numéricos, lidando com decimais, enquanto integer é otimizado para contagens ou índices que não exigem precisão decimal. No cálculo acima, valor_total se torna double porque a operação envolve um double (preco_unitario), e o R promove o tipo de dado para o mais abrangente para evitar perda de informação.

Exercício 2: Dada a necessidade de otimização de memória em um vetor com milhões de observações que representam contagens (números inteiros positivos), explique por que seria preferível armazená-los como integer em vez de numeric e demonstre como criar um vetor de inteiros de 1 a 10.

Resposta:
Seria preferível armazenar contagens como integer em vez de numeric porque integer usa menos memória por elemento (geralmente 4 bytes) em comparação com numeric (double, que usa 8 bytes). Para milhões de observações, essa diferença se traduz em uma economia significativa de memória, o que pode melhorar o desempenho e evitar o esgotamento da memória, especialmente em conjuntos de dados grandes onde a precisão decimal não é necessária.

Para criar um vetor de inteiros de 1 a 10:

        vetor_inteiros <- 1L:10L
        print(vetor_inteiros)
##  [1]  1  2  3  4  5  6  7  8  9 10

Note o uso do sufixo L para garantir que cada número seja tratado como um inteiro.

2.7 Tipos de dados - texto

Exercício 1: Crie uma variável nome_produto com o valor "Notebook Dell XPS" e uma variável modelo com o valor "15 9500". Concatenar estas duas variáveis com a adição da palavra “Modelo:” para formar uma única string descricao_completa. Imprima descricao_completa e verifique o tipo de dado.

Resposta:

        nome_produto <- "Notebook Dell XPS"
        modelo <- "15 9500"
        descricao_completa <- paste(nome_produto, "Modelo:", modelo)

        print(descricao_completa)
## [1] "Notebook Dell XPS Modelo: 15 9500"

O tipo de dado character é a forma como o R armazena strings (textos).

Exercício 2: Em R, é possível usar aspas simples (') ou duplas (") para definir strings. Explique quando seria preferível usar um tipo de aspa em detrimento do outro, dando um exemplo prático.

Resposta:
A escolha entre aspas simples e duplas é geralmente uma questão de estilo e consistência, mas torna-se relevante quando a string que você deseja definir contém o próprio caractere de aspas.
* É preferível usar aspas duplas se a string contiver aspas simples.
* É preferível usar aspas simples se a string contiver aspas duplas.
Isso evita a necessidade de “escapar” o caractere de aspa interna com uma barra invertida (\).

Exemplo:

        # Usando aspas duplas para string com aspas simples
        frase1 <- "Ele disse: 'Olá!'"
        print(frase1)
## [1] "Ele disse: 'Olá!'"
        # Usando aspas simples para string com aspas duplas
        frase2 <- 'O livro se chama "A Arte da Programação".'
        print(frase2)
## [1] "O livro se chama \"A Arte da Programação\"."
        # Alternativa com escape, mas menos legível
        frase3 <- "Ele disse: \"Olá!\""
        print(frase3)
## [1] "Ele disse: \"Olá!\""

2.8 Tipos de dados - lógicos

Exercício 1: Considere que um sistema de controle de qualidade aprova um produto se sua temperatura estiver entre 20 e 30 graus Celsius (inclusive) E seu pH for superior a 6.5. Crie variáveis para temperatura = 25 e pH = 7.2. Utilizando operadores de comparação e lógicos, determine se o produto é aprovado.

Resposta:

        temperatura <- 25
        pH <- 7.2

        aprovado <- (temperatura >= 20 & temperatura <= 30) & (pH > 6.5)
        print(aprovado)
## [1] TRUE

O produto é TRUE, indicando que foi aprovado. O tipo de dado é logical.

2.9 Tipos de dados - booleanos

Exercício 1: Em R, os valores booleanos são representados por TRUE e FALSE. Qual é a relação desses valores com os tipos de dados logical? Demonstre como R trata esses valores em um contexto numérico (conversão implícita).

Resposta:
Em R, os valores booleanos TRUE e FALSE são a própria essência do tipo de dado logical. Ou seja, o tipo de dado logical é o que armazena esses valores booleanos. Eles não são apenas representações, mas os valores literais desse tipo.
O R tem uma capacidade de coerção implícita que permite que logical seja tratado como numérico em certas operações:
* TRUE é convertido para 1.
* FALSE é convertido para 0.

Exemplo de conversão implícita:

        verdadeiro <- TRUE
        falso <- FALSE

        print(verdadeiro) # Tipo é logical
## [1] TRUE
        print(as.numeric(verdadeiro)) # Converte para numérico
## [1] 1
        print(as.numeric(falso))   # Converte para numérico
## [1] 0
        # Exemplo prático: somar valores lógicos
        soma_logicos <- TRUE + TRUE + FALSE
        print(soma_logicos)
## [1] 2

A soma de TRUE + TRUE + FALSE resulta em 2, porque TRUE é tratado como 1 e FALSE como 0 na operação aritmética.

Exercício 2: Crie um vetor de dados lógicos que represente se um estudante “passou” (TRUE) ou “não passou” (FALSE) em uma prova: c(TRUE, FALSE, TRUE, TRUE, FALSE). Utilizando a coerção implícita de R, calcule o número total de estudantes que passaram e o percentual de aprovação.

Resposta:

        status_aprovacao <- c(TRUE, FALSE, TRUE, TRUE, FALSE)

        # Número total de estudantes que passaram (TRUEs são somados como 1)
        total_aprovados <- sum(status_aprovacao)
        print(paste("Total de aprovados:", total_aprovados))
## [1] "Total de aprovados: 3"
        # Número total de estudantes
        total_estudantes <- length(status_aprovacao)
        print(paste("Total de estudantes:", total_estudantes))
## [1] "Total de estudantes: 5"
        # Percentual de aprovação
        percentual_aprovacao <- (total_aprovados / total_estudantes) * 100
        print(paste("Percentual de aprovação:", percentual_aprovacao, "%"))
## [1] "Percentual de aprovação: 60 %"

2.10 Tipos de dados - datas

Exercício 1: Você está gerenciando um projeto e precisa calcular a duração entre duas datas. Defina data_inicio_projeto como “2023-01-15” e data_fim_prevista como “2024-03-10”. Calcule a diferença em dias entre essas duas datas.

Resposta:

        data_inicio_projeto <- as.Date("2023-01-15")
        data_fim_prevista <- as.Date("2024-03-10")

        diferenca_dias <- data_fim_prevista - data_inicio_projeto
        print(diferenca_dias)
## Time difference of 420 days

O resultado é um objeto difftime, mas seu valor numérico subjacente é double (representando os dias).

Exercício 2: Em muitas análises financeiras ou de séries temporais, é fundamental manipular datas e horas. Demonstre como você criaria um objeto que combine data e hora (por exemplo, “2023-10-26 14:30:00”) e como você extrairia o ano, o mês e a hora desse objeto. Qual pacote é amplamente utilizado para manipulação avançada de datas e horas em R?

Resposta:

        # Criar um objeto POSIXct (data e hora)
        data_hora_evento <- as.POSIXct("2023-10-26 14:30:00", tz = "UTC")
        print(data_hora_evento)
## [1] "2023-10-26 14:30:00 UTC"
        # Extrair ano, mês e hora
        ano <- format(data_hora_evento, "%Y")
        mes <- format(data_hora_evento, "%m")
        hora <- format(data_hora_evento, "%H")

        print(paste("Ano:", ano))
## [1] "Ano: 2023"
        print(paste("Mês:", mes))
## [1] "Mês: 10"
        print(paste("Hora:", hora))
## [1] "Hora: 14"

O pacote amplamente utilizado para manipulação avançada de datas e horas em R é o lubridate. Ele simplifica muito a criação, parseamento e manipulação de objetos de data e hora, oferecendo funções mais intuitivas do que as funções base do R.

2.11 Tipos de dados - factor

Exercício 1: Você está coletando dados sobre o nível de satisfação do cliente, com as categorias “Muito Insatisfeito”, “Insatisfeito”, “Neutro”, “Satisfeito”, “Muito Satisfeito”. Crie um vetor com algumas observações (c("Satisfeito", "Neutro", "Muito Insatisfeito", "Satisfeito")) e converta-o para um fator. Mostre os níveis do fator e explique a importância da ordem nos níveis para análise categórica ordinal.

Resposta:

        # Vetor com dados colhidos
        satisfacao_raw <- c("Satisfeito", "Neutro", "Muito Insatisfeito", "Satisfeito", "Neutro", "Neutro")

        # Definir os níveis em ordem
        niveis_satisfacao <- c("Muito Insatisfeito", "Insatisfeito", "Neutro", "Satisfeito", "Muito Satisfeito")

        # Converter para fator com níveis ordenados
        satisfacao_fator <- factor(satisfacao_raw, levels = niveis_satisfacao, ordered = TRUE)

        print(satisfacao_fator)
## [1] Satisfeito         Neutro             Muito Insatisfeito Satisfeito        
## [5] Neutro             Neutro            
## 5 Levels: Muito Insatisfeito < Insatisfeito < Neutro < ... < Muito Satisfeito
        print(levels(satisfacao_fator))
## [1] "Muito Insatisfeito" "Insatisfeito"       "Neutro"            
## [4] "Satisfeito"         "Muito Satisfeito"

A importância da ordem nos níveis de um fator categórico ordinal é que ela permite que o R (e as funções estatísticas) compreendam a relação hierárquica entre as categorias. Sem uma ordem definida, o R trataria as categorias como nominais (sem hierarquia), o que seria inadequado para variáveis como “satisfação” ou “grau de escolaridade”. A ordem é crucial para realizar comparações (e.g., “Satisfeito” é maior que “Neutro”), plotar gráficos com a sequência correta e aplicar modelos estatísticos que levam em conta essa ordenação.

Exercício 2: Em um estudo sobre hábitos de consumo de café, você tem um vetor de observações de “Tipo de Café Consumido”: c("Expresso", "Latte", "Cappuccino", "Expresso", "Filtro"). Converta este vetor em um fator sem ordem explícita. Por que, neste caso, a ordem dos níveis não é tão crítica quanto no exercício anterior, e qual seria um possível benefício de convertê-lo para fator?

* Resposta:

        tipos_cafe_raw <- c("Expresso", "Latte", "Cappuccino", "Expresso", "Filtro")

        # Converter para fator sem ordem explícita
        tipos_cafe_fator <- factor(tipos_cafe_raw)

        print(tipos_cafe_fator)
## [1] Expresso   Latte      Cappuccino Expresso   Filtro    
## Levels: Cappuccino Expresso Filtro Latte
        print(levels(tipos_cafe_fator))
## [1] "Cappuccino" "Expresso"   "Filtro"     "Latte"
        print(is.ordered(tipos_cafe_fator)) # Verifica se os fatores estão ordenados, no caso FALSE
## [1] FALSE

Neste caso, a ordem dos níveis não é tão crítica porque “Tipo de Café Consumido” é uma variável categórica nominal. Não há uma hierarquia natural ou uma ordem intrínseca entre “Expresso”, “Latte” e “Cappuccino”; um não é “maior” ou “melhor” que o outro por natureza, eles são apenas categorias distintas.
Um possível benefício de converter este vetor para fator é a eficiência de armazenamento e processamento, especialmente em grandes conjuntos de dados. Fatores armazenam os dados como inteiros mapeados para os níveis (strings), o que pode economizar memória. Além disso, muitas funções estatísticas e de plotagem em R (como table() ou ggplot2) trabalham de forma mais eficiente e produzem resultados mais claros e categorizados quando a variável é um fator.

2.12 Variáveis com dados numéricos

Exercício 1: Em um cenário de análise de investimentos, você tem o capital_inicial = 10000, uma taxa_juros_anual = 0.05 (5%) e um periodo_anos = 3. Calcule o valor_futuro do investimento usando a fórmula de juros compostos simples: Valor Futuro = Capital Inicial * (1 + Taxa Juros)^Periodo.

Resposta:

        capital_inicial <- 10000
        taxa_juros_anual <- 0.15
        periodo_anos <- 5

        valor_futuro <- capital_inicial * (1 + taxa_juros_anual)^periodo_anos
        print(paste("O valor futuro do investimento é:", round(valor_futuro, 2)))
## [1] "O valor futuro do investimento é: 20113.57"

Exercício 2: Crie duas variáveis numéricas, largura = 8.5 e altura = 12.0. Calcule a area (largura * altura) e o perimetro (2 * (largura + altura)) de um retângulo.

Resposta:

        largura <- 8.5
        altura <- 12.0

        area <- largura * altura
        perimetro <- 2 * (largura + altura)

        print(paste("Área do retângulo:", area))
## [1] "Área do retângulo: 102"
        print(paste("Perímetro do retângulo:", perimetro))
## [1] "Perímetro do retângulo: 41"

2.13 Variáveis com textos

Exercício 1: Crie uma variável titulo_relatorio com o texto "Relatório Anual de Vendas" e uma variável ano_relatorio com o texto "2023". Concatene esses dois textos para formar a string relatorio_completo no formato “Relatório Anual de Vendas (2023)”.

Resposta:

        titulo_relatorio <- "Relatório Anual de Vendas"
        ano_relatorio <- "2023"

        relatorio_completo <- paste0(titulo_relatorio, " (", ano_relatorio, ")")
        print(relatorio_completo)
## [1] "Relatório Anual de Vendas (2023)"
    A função `paste0()` é usada aqui porque ela concatena strings sem adicionar um espaço como separador por padrão, o que é útil quando precisamos de controle preciso sobre os espaços.\
    \

Exercício 2: Dada uma string texto_limpo = " Análise de Dados com R ", remova os espaços em branco extras do início e do final da string. Além disso, transforme a string resultante para que todas as letras fiquem em maiúsculas.

Resposta:

        texto_original <- "  Análise de Dados com R  "

        # Remover espaços em branco do início e fim
        texto_sem_espacos_extras <- trimws(texto_original)
        print(paste("Texto sem espaços extras:", texto_sem_espacos_extras))
## [1] "Texto sem espaços extras: Análise de Dados com R"
        # Transformar para maiúsculas
        texto_maiusculo <- toupper(texto_sem_espacos_extras)
        print(paste("Texto em maiúsculas:", texto_maiusculo))
## [1] "Texto em maiúsculas: ANÁLISE DE DADOS COM R"

2.14 Vetores numéricos

Exercício 1: Você coletou as pontuações de 10 estudantes em um teste: c(85, 92, 78, 65, 95, 88, 70, 80, 90, 75). Crie um vetor com essas pontuações e, em seguida, calcule a média, mediana e o desvio padrão dessas notas.

Resposta:

        # 1. Criando o vetor 'pontuacoes'
        pontuacoes <- c(85, 92, 78, 65, 95, 88, 70, 80, 90, 75)

        # 2. Realizando os cálculos estatísticos
        media_pontuacoes <- mean(pontuacoes)
        mediana_pontuacoes <- median(pontuacoes)
        desvio_padrao_pontuacoes <- sd(pontuacoes)

        3 # Imprimindo os resultados
## [1] 3
        print(paste("Média das pontuações:", media_pontuacoes))
## [1] "Média das pontuações: 81.8"
        print(paste("Mediana das pontuações:", mediana_pontuacoes))
## [1] "Mediana das pontuações: 82.5"
        print(paste("Desvio Padrão das pontuações:", round(desvio_padrao_pontuacoes, 2)))
## [1] "Desvio Padrão das pontuações: 9.89"

Exercício 2: Crie um vetor numérico temperaturas_celsius com os valores c(10, 15, 20, 25, 30). Converta essas temperaturas para Fahrenheit usando a fórmula F = C * 9/5 + 32 e armazene os resultados em um novo vetor temperaturas_fahrenheit.

Resposta:

        # 1. Criando o vetor
        temperaturas_celsius <- c(10, 15, 20, 25, 30)

        # 3. Realizando os cálculos
        temperaturas_fahrenheit <- temperaturas_celsius * 9/5 + 32
        
        3 # Imprimindo os resultados
## [1] 3
        print(temperaturas_fahrenheit)
## [1] 50 59 68 77 86

2.15 Vetores texto

Exercício 1: Você possui uma lista de nomes de cidades: c("São Paulo", "Rio de Janeiro", "Belo Horizonte", "Curitiba"). Crie este vetor. Em seguida, adicione a cidade “Porto Alegre” ao final do vetor e remova a cidade “Belo Horizonte”.

Resposta:

        # 1. Criando o vetor 'cidades'
        cidades <- c("São Paulo", "Rio de Janeiro", "Belo Horizonte", "Curitiba")
        
        2 # Imprimindo o vetor criado
## [1] 2
        print(paste("Cidades originais:", paste(cidades, collapse = ", ")))
## [1] "Cidades originais: São Paulo, Rio de Janeiro, Belo Horizonte, Curitiba"
        # 3. Adicionar "Porto Alegre"
        cidades <- c(cidades, "Porto Alegre")
        
        4 # Imprimindo
## [1] 4
        print(paste("Cidades após adicionar:", paste(cidades, collapse = ", ")))
## [1] "Cidades após adicionar: São Paulo, Rio de Janeiro, Belo Horizonte, Curitiba, Porto Alegre"
        # 5. Remover "Belo Horizonte" (selecionando as que NÃO são "Belo Horizonte")
        cidades <- cidades[cidades != "Belo Horizonte"]
        
        6 # Imprimindo
## [1] 6
        print(paste("Cidades após remover:", paste(cidades, collapse = ", ")))
## [1] "Cidades após remover: São Paulo, Rio de Janeiro, Curitiba, Porto Alegre"

Exercício 2: Dada a lista de nomes c("Ana Silva", "Bruno Costa", "Carla Dias", "Daniel Souza"), crie este vetor. Em seguida, usando uma função R, selecione apenas os nomes que contêm a letra ‘a’ (maiúscula ou minúscula).

Resposta:

        nomes <- c("Ana Laura", "Bruno Costa", "Carla Dias", "Daniel Souza")

        # Selecionar nomes que contêm 'l' ou 'L'
        # Usamos `grep` para buscar padrões e `ignore.case = TRUE` para ignorar maiúsculas/minúsculas
        nomes_com_l <- grep("l", nomes, ignore.case = TRUE, value = TRUE)
        print(nomes_com_l)
## [1] "Ana Laura"    "Carla Dias"   "Daniel Souza"

Neste caso, os nomes contêm a letra ‘l’ (em maiúscula ou minúscula).

2.16 Sequência de dados

Exercício 1: Você precisa simular uma série temporal de 12 meses. Crie uma sequência numérica de 1 a 12, representando os meses, com um passo de 1. Em seguida, crie outra sequência de datas para o ano de 2023, começando em “2023-01-01” e incrementando mensalmente por 12 meses.

Resposta:

        # 1.  Sequência numérica de meses
        meses_num <- 1:12

        2 # Imprimindo a sequência criada
## [1] 2
        print(paste("Sequência de meses numéricos:", paste(meses_num, collapse = ", ")))
## [1] "Sequência de meses numéricos: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12"
        # 3. Criando a sequência de datas mensais para 2023
        data_inicio <- as.Date("2023-01-01")
        sequencia_datas_2023 <- seq(from = data_inicio, by = "month", length.out = 12)
        
        4 # Imprimindo a sequencia criada
## [1] 4
        print(sequencia_datas_2023, collapse = ", ")
##  [1] "2023-01-01" "2023-02-01" "2023-03-01" "2023-04-01" "2023-05-01"
##  [6] "2023-06-01" "2023-07-01" "2023-08-01" "2023-09-01" "2023-10-01"
## [11] "2023-11-01" "2023-12-01"

Exercício 2: Crie um vetor que repita a string “Item X” 3 vezes e, em seguida, a string “Item Y” 2 vezes. Explique por que a função rep() é útil para a criação de dados para simulações ou preenchimento de data frames.

Resposta:

        # 1. Criando o vetor
        vetor_repetido <- rep(c("Item X", "Item Y"), times = c(3, 2))
        
        2 # Imprimindo o vetor
## [1] 2
        print(vetor_repetido)
## [1] "Item X" "Item X" "Item X" "Item Y" "Item Y"
        # 3. Alternativa para repetição sequencial (cada elemento repetido 'n' vezes)
        vetor_repetido_each <- rep(c("Item X", "Item Y"), each = 2)
        
        4 # Imprimindo o vetor
## [1] 4
        print(vetor_repetido_each)
## [1] "Item X" "Item X" "Item Y" "Item Y"

A primeira solução times = c(3, 2) é a que responde ao pedido direto. A segunda é para ilustrar each.

A função rep() é extremamente útil para a criação de dados para simulações ou preenchimento de data frames porque permite gerar rapidamente vetores com padrões repetidos. Em simulações, pode-se gerar múltiplas observações para diferentes condições (ex: rep("Tratamento A", 100)). No preenchimento de data frames, é comum ter variáveis categóricas onde os níveis se repetem um certo número de vezes, ou onde uma sequência de valores precisa ser replicada para alinhar com outras colunas. Isso evita a digitação manual e garante consistência nos dados.

2.17 Matrizes

Exercício 1: Você tem os dados de vendas de 3 produtos (linhas) em 4 trimestres (colunas): c(100, 120, 150, 110, 80, 90, 100, 130, 200, 180, 170, 190). Crie uma matriz 3x4 com esses dados, preenchendo por linha (byrow = TRUE). Atribua nomes às linhas (“Produto A”, “Produto B”, “Produto C”) e às colunas (“Q1”, “Q2”, “Q3”, “Q4”).

Resposta:

# 1. Criando o vetor, conforme enunciado do problema        
dados_vendas <- c(100, 120, 150, 110, 80, 90, 100, 130, 200, 180, 170, 190)

# 2. Criando a matriz
matriz_vendas <- matrix(dados_vendas, 
                        nrow = 3, ncol = 4, byrow = TRUE,
                        dimnames = list(
                                       c("Produto A", "Produto B", "Produto C"),
                                       c("Q1", "Q2", "Q3", "Q4")))
# O nome da linhas é o primeiro vetor da lista; e as colunas o segundo vetor da lista

3 # Imprimindo a matriz
## [1] 3
print(matriz_vendas)
##            Q1  Q2  Q3  Q4
## Produto A 100 120 150 110
## Produto B  80  90 100 130
## Produto C 200 180 170 190

Exercício 2: Dada a matriz matriz_vendas criada no exercício anterior, calcule o total de vendas para cada produto (soma das linhas) e o total de vendas para cada trimestre (soma das colunas).

Resposta:

# 1. Assumindo que matriz_vendas já foi criada no exercício anterior

# 2. Calculando 0 total de vendas por produto (soma das linhas)
total_por_produto <- rowSums(matriz_vendas)

3 # Imprimindo o total de vendas por produto
## [1] 3
print(total_por_produto)
## Produto A Produto B Produto C 
##       480       400       740
# 4. Calculando o total de vendas por trimestre (soma das colunas)
total_por_trimestre <- colSums(matriz_vendas)

5 # Imprimindo o total de vendas por trimestre
## [1] 5
print(total_por_trimestre)
##  Q1  Q2  Q3  Q4 
## 380 390 420 430

2.18 Chamadas de matrizes

Exercício 1: Dada a matriz matriz_vendas do exercício anterior, acesse o valor de vendas do “Produto B” no “Q3”. Em seguida, selecione todas as vendas do “Produto A”.

Resposta:

# 1. Assumindo que matriz_vendas já foi criada no exercício anterior

2 # Acessar valor do Produto B no Q3
## [1] 2
matriz_vendas["Produto B", "Q3"]
## [1] 100
3 # Selecionar todas as vendas do Produto A
## [1] 3
matriz_vendas["Produto A", ]
##  Q1  Q2  Q3  Q4 
## 100 120 150 110

Exercício 2: Utilizando a mesma matriz_vendas, selecione as vendas dos “Produtos A e C” para os “Q1 e Q2”. Explique a diferença entre usar um índice numérico e um índice de nome para acessar elementos em uma matriz.

Resposta:

# Assumindo que matriz já foi criada no exercício anterior

# Selecionar vendas dos Produtos A e C para Q1 e Q2
matriz_vendas[c("Produto A", "Produto C"), c("Q1", "Q2")]
##            Q1  Q2
## Produto A 100 120
## Produto C 200 180

Diferença entre índice numérico e índice de nome:
* Índice Numérico: Acessa elementos com base em sua posição (índice) na matriz, começando de 1. Ex: matriz[1, 2] acessa o elemento da primeira linha, segunda coluna. É rápido e direto.
* Índice de Nome: Acessa elementos usando os nomes atribuídos às linhas e colunas. Ex: matriz["NomeLinha", "NomeColuna"]. Torna o código mais legível e robusto a futuras alterações na ordem das linhas/colunas, pois não depende da posição.
Em contextos de produção ou colaboração, o uso de nomes é geralmente preferível, pois melhora a compreensibilidade do código e o torna menos propenso a erros quando a estrutura subjacente da matriz pode mudar (ex: se uma nova linha/coluna for inserida, os índices numéricos mudariam, mas os nomes permaneceriam válidos).

2.19 Data-frames

Exercício 1: Em um estudo sobre características de estudantes, crie um data.frame com as seguintes informações para 3 estudantes: Nome (texto), Idade (numérico), Curso (fator com níveis “Engenharia”, “Medicina”, “Direito”), e Status_Ativo (lógico). Preencha com dados fictícios.

Resposta:

# 1. Criando o data-frame
estudantes_df <- data.frame(
    Nome = c("João Silva", "Maria Santos", "Pedro Almeida"),
    Idade = c(22, 21, 23),
    Curso = factor(c("Engenharia", "Medicina", "Direito"),
                    levels = c("Engenharia", "Medicina", "Direito")),
    Status_Ativo = c(TRUE, TRUE, FALSE)
    )

2 # Imprimindo o data-frame
## [1] 2
print(estudantes_df)
##            Nome Idade      Curso Status_Ativo
## 1    João Silva    22 Engenharia         TRUE
## 2  Maria Santos    21   Medicina         TRUE
## 3 Pedro Almeida    23    Direito        FALSE

Nota: Por padrão, strings em data.frame são convertidas para factor em versões mais antigas do R, mas em versões recentes (R >= 4.0), elas permanecem character a menos que stringsAsFactors = TRUE seja especificado. O exemplo acima força factor para Curso e o resultado mostra Nome como factor por default.

Exercício 2: Qual a principal vantagem de um data.frame em relação a uma matriz em R para armazenamento de dados tabulares? Dê um exemplo onde um data.frame é mais adequado.

Resposta:
A principal vantagem de um data.frame em relação a uma matriz é que o data.frame pode armazenar colunas com diferentes tipos de dados, enquanto uma matriz exige que todos os seus elementos sejam do mesmo tipo de dado. Essa flexibilidade torna o data.frame a estrutura de dados mais fundamental e amplamente utilizada para representar conjuntos de dados tabulares no R, similar a uma tabela de banco de dados ou planilha.

Exemplo onde data.frame é mais adequado:
Imagine um conjunto de dados de clientes, onde você precisa armazenar:
* ID (numérico)
* Nome (texto)
* Idade (numérico)
* Ativo_no_sistema (lógico)
* Região (fator/texto)

Uma matriz não conseguiria armazenar todos esses tipos de dados juntos, pois tentaria coerção para um tipo comum (provavelmente texto), perdendo a natureza numérica ou lógica original dos dados. Um data.frame, por outro lado, manipula isso facilmente, mantendo a integridade dos tipos de dados de cada coluna.

2.20 Chamadas de data-frames

Exercício 1: Dado o data.frame estudantes_df criado anteriormente, acesse a coluna Idade de duas maneiras diferentes: usando a notação $ e a notação [[ ]]. Em seguida, selecione as informações do estudante “Maria Santos”.

Resposta:

# 1. Assumindo que estudantes_df já foi criado

2 # Acessar coluna Idade usando $
## [1] 2
estudantes_df$Idade
## [1] 22 21 23
# 3. Acessar coluna Idade usando [[ ]]
idades_double_bracket <- estudantes_df[["Idade"]]

4 # Imprimindo 
## [1] 4
print(idades_double_bracket)
## [1] 22 21 23
# 5. Selecionar informações da estudante "Maria Santos"
maria_santos_info <- estudantes_df[estudantes_df$Nome == "Maria Santos", ]

6. # Imprimindo
## [1] 6
print(maria_santos_info)
##           Nome Idade    Curso Status_Ativo
## 2 Maria Santos    21 Medicina         TRUE

Exercício 2: Considerando o data.frame estudantes_df, selecione apenas os nomes e os cursos dos estudantes que estão Status_Ativo == TRUE.

Resposta:

        # 1. Assumindo que estudantes_df já foi criado

        # Selecionar nomes e cursos de estudantes ativos
        estudantes_df[estudantes_df$Status_Ativo == TRUE, c("Nome", "Curso")]
##           Nome      Curso
## 1   João Silva Engenharia
## 2 Maria Santos   Medicina

2.21 Listas

Exercício 1: Crie uma lista em R que contenha os seguintes elementos:
* Um vetor numérico temperaturas com valores c(22.5, 23.1, 21.9).
* Uma string nome_estacao com o valor "Verão 2023".
* Um data.frame observacoes_diarias com duas colunas: Dia (inteiro de 1 a 3) e Chuva_mm (numérico c(5, 0, 12)).
* Nomeie os elementos da lista como “temp”, “estacao” e “dados_diarios”.

Resposta:

# 1. Criando uma lista com temp (vetor), estacao (string) e dados_diarios (data.frame)
minha_lista <- list(
   temp = c(22.5, 23.1, 21.9),
   estacao = "Verão 2023",
   dados_diarios = data.frame(Dia = 1:3, Chuva_mm = c(5, 0, 12))
   )

2 # Imprimindo a lista
## [1] 2
print(minha_lista)
## $temp
## [1] 22.5 23.1 21.9
## 
## $estacao
## [1] "Verão 2023"
## 
## $dados_diarios
##   Dia Chuva_mm
## 1   1        5
## 2   2        0
## 3   3       12
3 # Imprimindo as características a lista criada
## [1] 3
print(str(minha_lista))
## List of 3
##  $ temp         : num [1:3] 22.5 23.1 21.9
##  $ estacao      : chr "Verão 2023"
##  $ dados_diarios:'data.frame':   3 obs. of  2 variables:
##   ..$ Dia     : int [1:3] 1 2 3
##   ..$ Chuva_mm: num [1:3] 5 0 12
## NULL

2.22 Chamadas de listas

Exercício 1: Dada a minha_lista criada no exercício anterior, acesse o vetor temperaturas usando a notação $ e o valor "Verão 2023" usando a notação [[ ]] com o nome do elemento.

Resposta:

# Assumindo que minha_lista já foi criada

# Acessar o vetor temperaturas
minha_lista$temp
## [1] 22.5 23.1 21.9
# Acessar a string nome_estacao
minha_lista[["estacao"]]
## [1] "Verão 2023"
minha_lista$estacao
## [1] "Verão 2023"
minha_lista[[2]]
## [1] "Verão 2023"

Exercício 2: Na mesma minha_lista, acesse o valor de Chuva_mm para o Dia = 3 do data.frame dados_diarios que está dentro da lista. Explique por que [[ ]] é preferível para acessar elementos de uma lista quando se sabe o nome exato ou a posição.

Resposta:

# 1. Assumindo que minha_lista já foi criada

2 # Acessar Chuva_mm para o Dia 3
## [1] 2
minha_lista$dados_diarios$Chuva_mm[3]
## [1] 12
3 # Alternativa: 
## [1] 3
minha_lista[["dados_diarios"]][3, "Chuva_mm"]
## [1] 12

Por que [[ ]] é preferível para acessar elementos específicos:
* [[ ]] é usado para extrair um único elemento de uma lista pelo seu nome ou posição, e o resultado é o próprio elemento (sem a estrutura de lista). Por exemplo, minha_lista[[1]] ou minha_lista[["temp"]] retornaria o vetor c(22.5, 23.1, 21.9).
* [] (colchete simples) é usado para extrair sub-listas (uma ou mais partes da lista). O resultado é sempre outra lista. Por exemplo, minha_lista[1] retornaria uma lista contendo o vetor temperaturas.
* $ é uma forma sintática abreviada de [[ ]] para acessar elementos nomeados, mas não funciona com índices numéricos ou variáveis para o nome.

Portanto, quando se quer extrair o conteúdo real de um elemento da lista (não uma sub-lista) e você sabe o nome ou a posição, [[ ]] é o método mais explícito e robusto. Ele também permite o uso de variáveis para especificar o nome do elemento, o que $ não permite (ex: nome_elemento <- "temp"; minha_lista[[nome_elemento]]).

2.23 Limpar variáveis (rm)

Exercício 1: Crie três variáveis: dados_temporarios = 1:10, resultado_parcial = "ok", analise_final = TRUE. Em seguida, remova apenas as variáveis dados_temporarios e resultado_parcial do ambiente de trabalho do R. Verifique quais variáveis permanecem.

Resposta:

# 1. Criando variáveis para depois remover
dados_temporarios <- 1:10
resultado_parcial <- "ok"
analise_final <- TRUE

2 # Apresentando as variáveis criadas a partir do comando 'ls()'
## [1] 2
print("Variáveis antes de remover:")
## [1] "Variáveis antes de remover:"
print(ls())
## [1] "analise_final"     "dados_temporarios" "resultado_parcial"
# 3. Removendo duas variáveis com o comando 'rm()'
rm(dados_temporarios, resultado_parcial)

3 # Imprimindo as variáveis que permaneceram depois da remoção
## [1] 3
print("Variáveis depois de remover:")
## [1] "Variáveis depois de remover:"
print(ls())
## [1] "analise_final"

A saída exata de ls() dependerá de quais variáveis foram criadas nas execuções anteriores na mesma sessão).

Exercício 2: Em um cenário onde você trabalhou com vários objetos grandes e complexos que estão consumindo muita memória, como você limparia todos os objetos do ambiente global para iniciar uma nova análise de forma “limpa”? Explique por que é uma boa prática limpar o ambiente antes de iniciar um novo script ou análise.

Resposta:
Para remover todos os objetos do ambiente global, você pode usar:

rm(list = ls())
  • Explicação:
    * ls(): Retorna um vetor de strings com os nomes de todos os objetos no ambiente atual.
    * rm(list = ...): A função rm() aceita um argumento list que recebe um vetor de nomes de objetos a serem removidos. Ao passar ls() para list, você efetivamente remove todos os objetos listados.

    Por que é uma boa prática:
    Limpar o ambiente antes de iniciar um novo script ou análise é uma boa prática para garantir a reprodutibilidade, evitar conflitos de nomes e gerenciar a memória.
    * Reprodutibilidade: Garante que o script será executado exatamente da mesma forma em qualquer máquina, sem depender de objetos remanescentes de sessões anteriores que podem não ser recriados.
    * Evitar Conflitos: Previne que variáveis ou funções com o mesmo nome de sessões anteriores interfiram ou sobrescrevam resultados inesperadamente.
    * Gerenciamento de Memória: Libera a memória RAM ocupada por objetos grandes e não mais necessários, o que é crucial ao trabalhar com conjuntos de dados extensos ou em ambientes com recursos limitados.

2.24 Concatenação de texto

Exercício 1: Você tem uma série de informações sobre um experimento: protocolo = "Exp_A", data_execucao = "2023-10-26", responsavel = "Dr. Silva". Crie uma string log_experimento que combine essas informações no formato: “Experimento: Exp_A - Data: 2023-10-26 - Responsável: Dr. Silva”.

Resposta:

# 1. Criando as variáveis do enunciado
protocolo <- "Exp_A"
data_execucao <- "2023-10-26"
responsavel <- "Dr. Silva"

# 2. Concatenando essas variáveis
log_experimento <- paste("Experimento:", protocolo,
                         "- Data:", data_execucao,
                         "- Responsável:", responsavel)
        
3 # IMprimindo o resultado da variável concatenada
## [1] 3
print(log_experimento)
## [1] "Experimento: Exp_A - Data: 2023-10-26 - Responsável: Dr. Silva"

Exercício 2: Crie um vetor de strings partes_url = c("https:/", "rpubs", "com", "adlauro", "estatistica_com_r"). Concatene esses elementos para formar uma URL completa no formato “https://rpubs.com/adlauro/estatistica_com_r”. Use uma função que permita especificar o separador.

Resposta:

# 1. Criando o vetor conforme solicitado no enunciado
partes_url = c("https:/", "rpubs", "com", "adlauro", "estatistica_com_r")

# Concatenando as partes
url_completa <- paste0(partes_url[1],"/",partes_url[2],".",partes_url[3],"/",partes_url[4],"/",partes_url[5])
        
3 # Imprimindo as url
## [1] 3
print(url_completa)
## [1] "https://rpubs.com/adlauro/estatistica_com_r"

2.25 Operadores aritméticos

Exercício 1: Em um cálculo de índice de massa corporal (IMC), você tem peso_kg = 75 e altura_m = 1.75. Calcule o IMC usando a fórmula IMC = peso / (altura^2).

Resposta:

# 1. Definindo as variáveis do enunciado
peso_kg <- 75
altura_m <- 1.75

# 2. Realizando o cálculo
imc <- peso_kg / (altura_m^2)

3 # Imprimindo o resultado
## [1] 3
print(paste("O IMC é:", round(imc, 2)))
## [1] "O IMC é: 24.49"

Exercício 2: Dada uma lista de despesas mensais em reais: despesas = c(500, 200, 350, 150). Se cada despesa deve ser convertida para dólares (considerando cotacao_dolar = 5.36), calcule o valor total das despesas em dólares e o valor médio de cada despesa em dólares.

Resposta:

# 1. Definindo as variáveis do enunciado
despesas <- c(500, 200, 350, 150)
cotacao_dolar <- 5.36

# 2. Realizando os cálculos
despesas_dolar <- despesas / cotacao_dolar

3 # Imprimindo os resultados
## [1] 3
print("Despesas em dólar (individual):")
## [1] "Despesas em dólar (individual):"
print(round(despesas_dolar, 2))
## [1] 93.28 37.31 65.30 27.99
# 4. Realizando os cálculos        
total_despesas_dolar <- sum(despesas_dolar)

5 # Imprimindo os resultados
## [1] 5
print(paste("Total de despesas em dólar:", round(total_despesas_dolar, 2)))
## [1] "Total de despesas em dólar: 223.88"
# 6. Realizando os cálculos 
media_despesas_dolar <- mean(despesas_dolar)

7 # Imprimindo os resultados
## [1] 7
print(paste("Média das despesas em dólar:", round(media_despesas_dolar, 2)))
## [1] "Média das despesas em dólar: 55.97"

2.26 Operações básicas de comparação

Exercício 1: Em um sistema de pontuação, um participante ganha um bônus se sua pontuacao_final for maior que 1000. Crie uma variável pontuacao_final = 1050. Verifique se o participante é elegível ao bônus. Em seguida, verifique se a pontuacao_final é diferente de 1000.

Resposta:

pontuacao_final <- 1050

elegivel_bonus <- pontuacao_final > 1000
print(paste("É elegível ao bônus?", elegivel_bonus))
## [1] "É elegível ao bônus? TRUE"
diferente_de_mil <- pontuacao_final != 1000
print(paste("É diferente de 1000?", diferente_de_mil))
## [1] "É diferente de 1000? TRUE"

Exercício 2: Você tem um vetor de idades de usuários idades = c(18, 25, 16, 30, 22). Selecione apenas as idades que são maiores ou iguais a 18 e menores que 25.

Resposta:

idades <- c(18, 25, 16, 30, 22)

idades_selecionadas <- idades[idades >= 18 & idades < 25]
print(paste("Idades selecionadas:", paste(idades_selecionadas, collapse = ", ")))
## [1] "Idades selecionadas: 18, 22"

2.27 Operadores lógicos

Exercício 1: Você está analisando as condições para aprovação de um empréstimo. O empréstimo é aprovado se o score_credito for maior que 700 OU a renda_anual for maior que 50000. Crie as variáveis score_credito = 680 e renda_anual = 60000. Determine se o empréstimo é aprovado.

Resposta:

score_credito <- 680
renda_anual <- 60000

aprovado_emprestimo <- (score_credito > 700) | (renda_anual > 50000)
print(paste("Empréstimo aprovado?", aprovado_emprestimo))
## [1] "Empréstimo aprovado? TRUE"

Exercício 2: Considere duas condições lógicas: condicao_A = TRUE e condicao_B = FALSE. Avalie o resultado das seguintes expressões lógicas: !(condicao_A) e (condicao_A & condicao_B) | condicao_A.

Resposta:

condicao_A <- TRUE
condicao_B <- FALSE

resultado1 <- !(condicao_A)
print(paste("!(condicao_A):", resultado1))
## [1] "!(condicao_A): FALSE"
resultado2 <- (condicao_A & condicao_B) | condicao_A
print(paste("(condicao_A & condicao_B) | condicao_A:", resultado2))
## [1] "(condicao_A & condicao_B) | condicao_A: TRUE"
  • Explicação do resultado2:
    • (condicao_A & condicao_B) avalia para (TRUE & FALSE), que é FALSE.
    • (FALSE | condicao_A) avalia para (FALSE | TRUE), que é TRUE.

2.28 Arredondamentos

Exercício 1: Um cálculo resultou no valor pi_aproximado = 3.1415926535. Arredonde este valor para 3 casas decimais. Em seguida, arredonde-o para o inteiro mais próximo usando a regra padrão de arredondamento (0.5 para cima).

Resposta:

pi_aproximado <- 3.1415926535

# Arredondar para 3 casas decimais
pi_arredondado_3casas <- round(pi_aproximado, digits = 3)
print(paste("Pi arredondado para 3 casas:", pi_arredondado_3casas))
## [1] "Pi arredondado para 3 casas: 3.142"
# Arredondar para o inteiro mais próximo
pi_arredondado_inteiro <- round(pi_aproximado)
print(paste("Pi arredondado para inteiro:", pi_arredondado_inteiro))
## [1] "Pi arredondado para inteiro: 3"

Exercício 2: Você tem o preço de um item com várias casas decimais: preco_bruto = 12.5678. Utilize as funções floor() e ceiling() para obter o menor inteiro maior ou igual a preco_bruto e o maior inteiro menor ou igual a preco_bruto, respectivamente. Explique a diferença no uso de floor e ceiling em comparação com round.

Resposta:

preco_bruto <- 12.5678

# Menor inteiro maior ou igual (teto)
preco_teto <- ceiling(preco_bruto)
print(paste("Preço (teto):", preco_teto))
## [1] "Preço (teto): 13"
# Maior inteiro menor ou igual (piso)
preco_piso <- floor(preco_bruto)
print(paste("Preço (piso):", preco_piso))
## [1] "Preço (piso): 12"
  • Diferença no uso de floor, ceiling e round:
    • round(x, digits): Arredonda x para o número de casas decimais especificado em digits. O arredondamento é feito para o número mais próximo, com 0.5 sendo arredondado para o inteiro par mais próximo (regra “round half to even” no R por padrão, embora o comportamento possa parecer como “round half up” para muitos casos com números positivos).
    • floor(x): Retorna o maior inteiro que é menor ou igual a x. Ele “arredonda para baixo” em direção ao infinito negativo.
    • ceiling(x): Retorna o menor inteiro que é maior ou igual a x. Ele “arredonda para cima” em direção ao infinito positivo.

      Enquanto round visa aproximar um número, floor e ceiling visam sempre para baixo ou para cima, respectivamente, independentemente da proximidade ao inteiro. Isso é útil em contextos como cálculo de quantidades mínimas ou máximas, alocações de recursos, ou faixas de preços.

2.29 Notação científica

Exercício 1: Em cálculos científicos, números muito pequenos ou muito grandes são comuns. Crie uma variável prob_evento_raro com o valor 0.000000000123 e uma variável populacao_global com o valor 8000000000. Exiba ambos os números no console e observe como o R os representa.

Resposta:

prob_evento_raro <- 0.000000000123
populacao_global <- 8000000000

print(prob_evento_raro)
## [1] 1.23e-10
print(populacao_global)
## [1] 8e+09

O R automaticamente converte números muito pequenos ou muito grandes para notação científica (também conhecida como notação exponencial) para uma representação mais concisa e legível. e-10 significa * 10^-10 e e+09 significa * 10^9.

Exercício 2: Converta os seguintes valores em notação científica para sua forma decimal padrão: 3.45e-3 e 1.8e+5. Explique a conveniência da notação científica para a legibilidade de dados em escala muito diferente.

Resposta:

valor_pequeno_notacao <- 3.45e-3
valor_grande_notacao <- 1.8e+5

# Para exibir em formato decimal padrão, pode-se ajustar as opções de impressão
options(scipen = 999) # Desativa a notação científica para números grandes
print(valor_pequeno_notacao)
## [1] 0.00345
print(valor_grande_notacao)
## [1] 180000
options(scipen = 0) # Volta ao padrão
  • Explicação:
    • 3.45e-3 significa 3.45 * 10^-3, que é 0.00345.
    • 1.8e+5 significa 1.8 * 10^5, que é 180000.

      A conveniência da notação científica para a legibilidade de dados em escalas muito diferentes reside em sua capacidade de representar de forma compacta e padronizada números que seriam excessivamente longos ou difíceis de interpretar em sua forma decimal completa. É especialmente útil na ciência e engenharia para:
      • Evitar Erros de Leitura: É fácil perder um zero em 0.000000000123 ou 8000000000, mas 1.23e-10 e 8e+09 são inequívocos.
      • Comparação Rápida de Ordens de Grandeza: Permite comparar rapidamente a magnitude de números (ex: 1e-5 é 100 vezes maior que 1e-7) sem contar zeros.
      • Consistência: Mantém uma representação uniforme para números em uma ampla faixa de valores.