Introduction to R Programming
Esse material é uma atualização e tradução dos materiais elaborados pelos alunos do Departamento de Genética da ESALQ/USP - Brasil. Acesse o conteúdo em portugues ministrado em outros eventos nesse site.
Sugerimos que, antes de iniciar a prática aqui descrita, siga este tutorial para instalação do R e do RStudio.
Familiarização com a interface do RStudio
Abrindo o RStudio você verá:
A interface é separada em quatro janelas com principais funções:
- Edição de código
- Ambiente de trabalho e histórico
- Console
- Arquivos, gráficos, pacotes e ajuda
Explore cada uma das janelas. São inúmeras funcionalidades para cada uma delas, veremos algumas delas no decorrer do curso.
Um primeiro script
A janela de edição de código (provavelmente localizada no canto
superior esquerdo) será utilizada para escrever o seu código. Abra um
novo script clicando no +
no canto superior esquerdo e
selecionando R script
.
Vamos então iniciar os trabalhos com o tradicional
Hello World
. Digite no seu script:
## Hello world
Agora, selecione a linha e aperte o botão Run
ou utilize
Ctrl + enter
.
Ao fazer isso o seu código será processado na janela
Console
, onde aparecerá em azul (se você estiver com as
cores padrão do R) o código escrito e, logo em seguida, o resultado
desejado. A linha somente não será processada no console se houver o
símbolo #
na frente. Agora, experimente colocar
#
na frente do código escrito. Novamente, selecione a linha
e aperte Run
.
O símbolo #
é utilizado para
comentários no código. Esta é uma ótima prática de
organização e ajuda a lembrar, posteriormente, o que você estava
pensando quando escreveu o código. Também é essencial para que outras
pessoas possam entendê-lo. Como no exemplo:
## Hello world
Importante: sempre que quiser realizar alguma alteração, edite o seu script e não diretamente no console, pois tudo o que neste é escrito, não terá como ser salvo!
Para salvar seu script, você pode utilizar a aba Files
localizada (como padrão) no canto direito inferior. Você pode procurar
uma localização de sua preferência, criar uma nova pasta com o nome
CursoR
.
Dica:
- Evite colocar espaços e pontuações no nome das pastas e arquivos,
isso pode dificultar o acesso via linha de comando no R. Por exemplo, ao
invés de
Curso R
, optamos porCursoR
.
Depois, basta clicar no disquete localizado no cabeçalho do RStudio
ou com Ctrl + s
e selecionar o diretório
CursoR
criado. Scripts em R são salvos com a extensão
.R
.
Estabelecendo diretório de trabalho
Outra boa prática no R é deixar o script no mesmo diretório onde estão seus dados brutos (arquivos de entrada no script) e os dados processados (gráficos, tabelas, etc). Para isso, vamos fazer com que o R identifique o mesmo diretório em que você salvou o script como diretório de trabalho. Assim, ele entenderá que é dali que os dados serão obtidos e é para lá que também irão os resultados.
Você pode fazer isso utilizando as facilidades do RStudio, basta
localizar o diretório CursoR
pela aba Files
,
clicar em More
e depois “Set as Working Directory”. Repare
que irá aparecer no console algo como:
Ou seja, você pode utilizar este mesmo comando para realizar esta ação. O resultado será nossa pasta de trabalho. Quando estiver perdido/a ou para ter certeza que o diretório de trabalho foi alterado utilize:
Facilitando a vida com Tab
Agora, imagine que você tem um diretório como
~/Documentos/mestrado/semestre1/disciplina_tal/aula_tal/dados_28174/analise_276182/resultados_161/
.
Não é fácil lembrar todo este caminho para escrever num comando
setwd()
.
Além da facilidade da janela do RStudio, você também pode utilizar a
tecla Tab
para completar o caminho para você. Experimente
buscando alguma pasta no seu computador. Basta começar a digitar o
caminho e apertar Tab
, ele irá completar o nome para você!
Se você tiver mais do que um arquivo com aquele início de nome, aperte
duas vezes o Tab
, ele mostrará todas as opções.
O Tab
funciona não só para indicar caminhos, mas também
para comandos e nomes de objetos. É muito comum cometermos erros de
digitação no código. Utilizar o Tab
reduzirá
significativamente esses erros.
O Tab
pode ser ainda mais poderoso se você tiver acesso
à ferramenta GitHub
Copilot. Com ela, você pode utilizar o Tab
para
completar o código que você está escrevendo. É uma ferramenta baseada em
inteligência artificial que sugere o código que você está escrevendo. É
uma ferramenta paga, mas você pode utilizar gratuitamente por 60
dias.
Operações básicas
Vamos então à linguagem!
O R pode funcionar como uma simples calculadora, que utiliza a mesma sintaxe que outros programas (como o excel):
1+1.3 #Decimal definido com "."
2*3
2^3
4/2
sqrt(4) #raíz quadrada
log(100, base = 10) #Logaritmo na base 10
log(100) #Logaritmo com base neperiana
Agora, utilize as operações básicas para solucionar expressão abaixo.
Lembre-se de utilizar parênteses ()
para estabelecer
prioridades nas operações.
\((\frac{13+2+1.5}{3})+ log_{4}96\)
Resultado esperado:
## [1] 8.792481
Repare que, se posicionar o parênteses de forma incorreta, o código não resultará em nenhuma mensagem de erro, pois este é um erro que chamamos de erro lógico ou erro silencioso, ou seja, o código roda, mas não faz o que você gostaria que ele fizesse. Esse é o tipo de erro mais perigoso e difícil de ser consertado. Veja um exemplo:
## [1] 18.79248
Os erros que produzem uma mensagem, seja um aviso (warning) ou um erro (error) são chamados de erros de sintaxe. Nesses casos, o R retornará uma mensagem para te ajudar a corrigí-los. Os warnings não comprometem o funcionamento do código, mas chamam a atenção para algum ponto; já os errors precisam necessariamente ser corrigidos para que o código rode.
Exemplo de error:
Você pode também esquecer de fechar algum parênteses, ou aspas, ou
colchetes, ou chaves, nesses casos, o R ficará aguardando o comando para
fechar o bloco de código sinalizando com um +
:
Se acontecer, vá até o console e aperte ESC, que o bloco será finalizado para que você possa corrigí-lo.
Os comandos log
e sqrt
são duas de muitas
outras funções básicas que o R possui. Funções são conjuntos de
instruções organizadas para realizar uma tarefa. Para todas elas, o R
possui uma descrição para auxiliar no seu uso. Para acessar essa ajuda
use:
E será aberta a descrição da função na janela Help
do
RStudio.
Se a descrição do próprio R não for suficiente para você entender como funciona a função, busque no google (de preferência em inglês). Existem diversos sites e fóruns com informações didáticas das funções do R.
Operações com vetores
Os vetores são as estruturas mais simples trabalhadas no R. Construímos um vetor com uma sequencia numérica usando:
## [1] 1 3 2 5 2
MUITA ATENÇÃO: O c é a função do R (Combine Values into a Vector or List) com a qual construímos um vetor!
Utilizamos o simbolo :
para criar sequências de números
inteiros, como:
## [1] 1 2 3 4 5 6 7 8 9 10
Podemos utilizar outras funções para gerar sequências, como:
## [1] 0 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90
## [20] 95 100
## [1] 0 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90
## [20] 95 100
- Crie uma sequencia utilizando a função
seq
que varie de 4 a 30, com intervalos de 3 em 3.
## [1] 4 7 10 13 16 19 22 25 28
A função rep
gera sequências com números repetidos:
## [1] 3 4 5 3 4 5
Podemos realizar operações utilizando esses vetores:
Repare que já esta ficando cansativo digitar os mesmos números repetidamente, vamos resolver isso criando objetos para armazenar nossos vetores e muito mais.
Criando objetos
O armazenamento de informações em objetos e a possível manipulação desses faz do R uma linguagem orientada por objetos. Para criar um objeto basta atribuir valores para as variáveis, como a seguir:
x = c(30.1,30.4,40,30.2,30.6,40.1)
# ou
x <- c(30.1,30.4,40,30.2,30.6,40.1)
y = c(0.26,0.3,0.36,0.24,0.27,0.35)
Os mais antigos costumam usar o sinal <-
, mas tem a
mesma função de =
. Há quem prefira usar o
<-
como atribuição em objetos e =
apenas
para definir os argumentos dentro de funções. Organize-se da forma como
preferir.
Para acessar os valores dentro do objeto basta:
## [1] 30.1 30.4 40.0 30.2 30.6 40.1
A linguagem é sensível à letras maiúsculas e minúsculas. Logo,
x
é diferente de X
:
O objeto X
não foi criado.
O nome dos objetos é uma escolha pessoal, a sugestão é tentar manter um padrão para melhor organização. Aqui estão alguma dicas:
- Usar nomes descritivos
- Evitar começar com números
- Não usar espaços (usar _ ou camelCase)
- Não usar caracteres especiais
- Manter consistência no padrão escolhido
- Evitar nomes muito longos
- Não usar acentos ou caracteres não-ASCII
Alguns nomes não podem ser usados por estabelecerem papéis fixos no R, são eles:
- TRUE - Verdadeiro, valor lógico
- FALSE - Falso, valor lógico
- if, else, for, while, break, next - Palavras reservadas para estruturas condicionais e de repetição
- for, while, repeat - Palavras reservadas para estruturas de repetição
- function - Palavra reservada para definição de funções
- in, NA, NaN, NULL - Palavras reservadas para valores especiais
- NA_integer_, NA_real, NA_character_, NA_complex_ - Valores especiais para representar dados ausentes
Podemos então realizar as operações com o objeto criado:
## [1] 32.1 32.4 42.0 32.2 32.6 42.1
## [1] 60.2 60.8 80.0 60.4 61.2 80.2
Para realizar a operação o R alinha os dois vetores e realiza a operação elemento à elemento. Observe:
## [1] 30.36 30.70 40.36 30.44 30.87 40.45
## [1] 7.826 9.120 14.400 7.248 8.262 14.035
Se os vetores tiverem tamanhos diferentes, ele irá repetir o menor para realizar a operação elemento a elemento com todos do maior.
Se caso o menor vetor não for múltiplo do maior, obteremos um aviso:
## Warning in x * c(1, 2, 3, 4): longer object length is not a multiple of shorter
## object length
## [1] 30.1 60.8 120.0 120.8 30.6 80.2
Repare que o warning não compromente o funcionamento do código, ele só dá uma dica de que algo pode não estar da forma como você gostaria.
Podemos também armazenar a operação em outro objeto:
Podemos também aplicar algumas funções, como exemplo:
## [1] 101.59
## [1] 16.93167
## [1] 6.427507
Indexação
Acessamos somente o 3º valor do vetor criado com []
:
Também podemos acessar o número da posição 2 a 4 com:
## [1] 15.35 20.18 15.22
Para obter informações do vetor criado utilize:
## num [1:6] 15.2 15.3 20.2 15.2 15.4 ...
A função str
nos diz sobre a estrutura do vetor, que se
trata de um vetor numérico com 6 elementos.
Os vetores também podem receber outras categorias como caracteres:
Outra classe são os fatores, esses podem ser um pouco complexos de lidar.
De forma geral, fatores são valores categorizados por
levels
, como exemplo, se transformarmos nosso vetor de
caracteres clone
em fator, serão atribuidos níveis para
cada uma das palavras:
## Factor w/ 4 levels "GRA01","GRA02",..: 2 3 4 2 1 3
## [1] "GRA01" "GRA02" "URO01" "URO03"
Dessa forma, teremos apenas 4 níveis para um vetor com 6 elementos, já que as palavras “GRA02” e “URO01” se repetem. Podemos obter o número de elementos do vetor ou o seu comprimento com:
## [1] 6
Também há vetores lógicos, que recebem valores de verdadeiro ou falso:
## [1] FALSE FALSE FALSE FALSE FALSE TRUE
Com ele podemos, por exemplo, identificar quais são as posições dos elementos maiores que 40:
## [1] 6
## [1] 40.1
## [1] 40.1
Também podemos localizar elementos específicos com:
## [1] TRUE FALSE TRUE TRUE FALSE FALSE
Também podem ser úteis as funções any
e
all
. Pesquise sobre elas.
Encontre mais sobre outros operadores lógicos, como o
>
utilizado, neste link.
Warning1
Faça uma sequência numérica, contendo 10 valores inteiros, e salve em um objeto chamado “a”.
## [1] 1 2 3 4 5 6 7 8 9 10
Crie outra sequência, utilizando números decimais e qualquer operação matemática, de tal forma que seus valores sejam idênticos ao objeto “a”.
## [1] 1 2 3 4 5 6 7 8 9 10
Os dois vetores parecem iguais, não?
Então, utilizando um operador lógico, vamos verificar o objeto “b” é igual ao objeto “a”.
## [1] TRUE TRUE FALSE TRUE TRUE TRUE FALSE TRUE TRUE TRUE
Alguns valores não são iguais. Como isso é possivel?
## [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
Warning2
Não é possível misturar diferentes classes dentro de um mesmo vetor. Ao tentar fazer isso, repare que o R irá tentar igualar para uma única classe:
## [1] "TRUE" "vish" "1"
No caso, todos os elementos foram transformados em caracteres.
Algumas Dicas:
- Cuidado com a prioridade das operações, na dúvida, sempre acrescente parenteses conforme seu interesse de prioridade.
- Lembre-se que, se esquecer de fechar algum
(
ou[
ou"
, o console do R ficará esperando você fechar indicando um+
. Nada será processado até que você digite diretamente no console um)
ou aperte ESC. - Cuidado para não sobrepor objetos já criados criando outros com o mesmo nome. Use, por exemplo: altura1, altura2.
- Mantenha no seu script .R somente os comandos que funcionaram e, de preferência, adicione comentários. Você pode, por exemplo, comentar dificuldades encontradas, para que você não cometa os mesmos erros mais tarde.
Se estiver adiantada/o em relação aos colegas, você já pode fazer os exercícios da Sessão 1, se não, faça-os em outro momento e nos envie dúvidas.
Matrizes
As matrizes são outra classe de objetos muito utilizadas no R, com elas podemos realizar operações de maior escala de forma automatizada.
Por serem usadas em operações, normalmente armazenamos nelas elementos numéricos. Para criar uma matriz, determinamos uma sequência de números e indicamos o número de linhas e colunas da matriz:
## [,1] [,2]
## [1,] 1 7
## [2,] 2 8
## [3,] 3 9
## [4,] 4 10
## [5,] 5 11
## [6,] 6 12
Podemos também utilizar sequências já armazenadas em vetores para gerar uma matriz, desde que eles sejam numéricos:
## [,1] [,2]
## [1,] 30.1 0.26
## [2,] 30.4 0.30
## [3,] 40.0 0.36
## [4,] 30.2 0.24
## [5,] 30.6 0.27
## [6,] 40.1 0.35
Com elas podemos realizar operações matriciais:
## [,1] [,2]
## [1,] 2 14
## [2,] 4 16
## [3,] 6 18
## [4,] 8 20
## [5,] 10 22
## [6,] 12 24
## [,1] [,2]
## [1,] 1 49
## [2,] 4 64
## [3,] 9 81
## [4,] 16 100
## [5,] 25 121
## [6,] 36 144
## [,1] [,2] [,3] [,4] [,5] [,6]
## [1,] 50 58 66 74 82 90
## [2,] 58 68 78 88 98 108
## [3,] 66 78 90 102 114 126
## [4,] 74 88 102 116 130 144
## [5,] 82 98 114 130 146 162
## [6,] 90 108 126 144 162 180
Utilizar essas operações exige conhecimento de álgebra de matrizes, se quiser se aprofundar a respeito, o livro Linear Models in Statistics, Rencher (2008) possui um boa revisão à respeito. Você também pode explorar a sintaxe do R para essas operações neste link.
Acessamos os números internos à matriz dando as coordenadas [linha,coluna], como no exemplo:
## [1] 0.24
As vezes pode ser informativo dar nomes às colunas e às linhas da matriz, fazemos isso com:
## altura diametro
## GRA02 30.1 0.26
## URO01 30.4 0.30
## URO03 40.0 0.36
## GRA02 30.2 0.24
## GRA01 30.6 0.27
## URO01 40.1 0.35
Essas funções colnames
e rownames
também
funcionam nos data.frames.
Data.frames
Diferente das matrizes, não realizamos operações com os data.frames, mas eles permitem a união de vetores com classes diferentes. Os data frames são semelhantes a tabelas geradas em outros programas, como o excel.
Os data frames são combinações de vetores de mesmo comprimento. Todos os que criamos até agora tem tamanho 6, verifique.
Podemos assim combiná-los em colunas de um único data.frame:
campo1 <- data.frame("clone" = clone, # Antes do sinal de "="
"altura" = x, # estabelecemos os nomes
"diametro" = y, # das colunas
"idade" = rep(3:5, 2),
"corte"= logico)
campo1
## clone altura diametro idade corte
## 1 GRA02 30.1 0.26 3 FALSE
## 2 URO01 30.4 0.30 4 FALSE
## 3 URO03 40.0 0.36 5 FALSE
## 4 GRA02 30.2 0.24 3 FALSE
## 5 GRA01 30.6 0.27 4 FALSE
## 6 URO01 40.1 0.35 5 TRUE
Podemos acessar cada uma das colunas com:
## [1] 3 4 5 3 4 5
Ou também com:
## [1] 3 4 5 3 4 5
Aqui, o número dentro dos colchetes se refere à coluna, por ser o segundo elemento (separado por vírgula). O primeiro elemento se refere à linha. Como deixamos o primeiro elemento vazio, estaremos nos referindo a todas as linhas para aquela coluna.
Dessa forma, se quisermos obter um conteúdo específico podemos dar as coordenadas com [linha,coluna]:
## [1] 30.1
- Obtenha o diâmetro do clone “URO03”.
## [1] 0.36
Mesmo se tratando de um data frame, podemos realizar operações com os vetores numéricos que a compõe.
- Com o diâmetro e a altura das árvores, calcule o volume conforme a
fórmula a seguir e armazene em um objeto
volume
:
\(3.14*(diametro/2)^2*altura\)
## [1] 1.597287 2.147760 4.069440 1.365523 1.751131 3.856116
Agora, vamos adicionar o vetor calculado com o volume ao nosso
data frame. Para isso use a função cbind
.
## clone altura diametro idade corte volume
## 1 GRA02 30.1 0.26 3 FALSE 1.597287
## 2 URO01 30.4 0.30 4 FALSE 2.147760
## 3 URO03 40.0 0.36 5 FALSE 4.069440
## 4 GRA02 30.2 0.24 3 FALSE 1.365523
## 5 GRA01 30.6 0.27 4 FALSE 1.751131
## 6 URO01 40.1 0.35 5 TRUE 3.856116
## 'data.frame': 6 obs. of 6 variables:
## $ clone : chr "GRA02" "URO01" "URO03" "GRA02" ...
## $ altura : num 30.1 30.4 40 30.2 30.6 40.1
## $ diametro: num 0.26 0.3 0.36 0.24 0.27 0.35
## $ idade : int 3 4 5 3 4 5
## $ corte : logi FALSE FALSE FALSE FALSE FALSE TRUE
## $ volume : num 1.6 2.15 4.07 1.37 1.75 ...
Algumas dicas:
Lembre-se que, para construir matrizes e data frames, as colunas devem apresentar o mesmo número de elementos.
Caso não saiba o operador ou a função que deve ser utilizada, busque no google ou pergunte para o chatgpt ou qualquer outra ferramenta. Por exemplo, se está em dúvida em como calcular o desvio padrão, busque por “desvio padrão R” ou, melhor ainda, “standard deviation R”. A comunidade do R é bastante ativa e grande parte das suas perguntas sobre ele já foram respondidas em algum lugar da web.
Não esqueça que tudo o que fizer no R precisa ser explicitamente indicado, como uma multiplicação 4ac com
4*a*c
. Para gerar um vetor 1,3,2,6 é necessário:c(1,3,2,6)
.
Listas
Listas consistem em uma coleção de objetos, não necessariamente de
mesma classe. Nelas podemos armazenar todos os outros objetos já vistos
e recuperá-los pela indexação com [[
. Como exemplo, vamos
utilizar alguns objetos que já foram gerados.
minha_lista <- list(campo1 = campo1, media_alt = tapply(campo1$altura, campo1$idade, mean), matrix_ex = W)
str(minha_lista)
## List of 3
## $ campo1 :'data.frame': 6 obs. of 6 variables:
## ..$ clone : chr [1:6] "GRA02" "URO01" "URO03" "GRA02" ...
## ..$ altura : num [1:6] 30.1 30.4 40 30.2 30.6 40.1
## ..$ diametro: num [1:6] 0.26 0.3 0.36 0.24 0.27 0.35
## ..$ idade : int [1:6] 3 4 5 3 4 5
## ..$ corte : logi [1:6] FALSE FALSE FALSE FALSE FALSE TRUE
## ..$ volume : num [1:6] 1.6 2.15 4.07 1.37 1.75 ...
## $ media_alt: num [1:3(1d)] 30.1 30.5 40
## ..- attr(*, "dimnames")=List of 1
## .. ..$ : chr [1:3] "3" "4" "5"
## $ matrix_ex: num [1:6, 1:2] 30.1 30.4 40 30.2 30.6 40.1 0.26 0.3 0.36 0.24 ...
## ..- attr(*, "dimnames")=List of 2
## .. ..$ : chr [1:6] "GRA02" "URO01" "URO03" "GRA02" ...
## .. ..$ : chr [1:2] "altura" "diametro"
Quero acessar o data.frame campo1
## clone altura diametro idade corte volume
## 1 GRA02 30.1 0.26 3 FALSE 1.597287
## 2 URO01 30.4 0.30 4 FALSE 2.147760
## 3 URO03 40.0 0.36 5 FALSE 4.069440
## 4 GRA02 30.2 0.24 3 FALSE 1.365523
## 5 GRA01 30.6 0.27 4 FALSE 1.751131
## 6 URO01 40.1 0.35 5 TRUE 3.856116
## clone altura diametro idade corte volume
## 1 GRA02 30.1 0.26 3 FALSE 1.597287
## 2 URO01 30.4 0.30 4 FALSE 2.147760
## 3 URO03 40.0 0.36 5 FALSE 4.069440
## 4 GRA02 30.2 0.24 3 FALSE 1.365523
## 5 GRA01 30.6 0.27 4 FALSE 1.751131
## 6 URO01 40.1 0.35 5 TRUE 3.856116
Para acessar uma coluna específica no data.frame campo1
,
que está dentro da minha_lista:
## [1] 0.26 0.30 0.36 0.24 0.27 0.35
## [1] 0.26 0.30 0.36 0.24 0.27 0.35
## [1] 0.26 0.30 0.36 0.24 0.27 0.35
Listas são muito úteis, por exemplo, quando vamos utilizar/gerar diversos objetos dentro de um loop.
Arrays
Este é um tipo de objeto que você provavelmente não irá utilizar agora no início, mas é bom saber da sua existência. São utilizados para armazenar dados com mais de duas dimensões. Por exemplo, se criarmos um array:
## , , 1
##
## [,1] [,2] [,3]
## [1,] 1 3 5
## [2,] 2 4 6
##
## , , 2
##
## [,1] [,2] [,3]
## [1,] 7 9 11
## [2,] 8 10 12
##
## , , 3
##
## [,1] [,2] [,3]
## [1,] 13 15 17
## [2,] 14 16 18
##
## , , 4
##
## [,1] [,2] [,3]
## [1,] 19 21 23
## [2,] 20 22 24
Teremos quatro matrizes com duas linhas e três colunas e os números de 1 a 24 estarão distribuídos nelas por colunas.
Se estiver adiantada/o em relação aos colegas, você já pode fazer os exercícios da Sessão 2, se não, faça-os em outro momento e nos envie dúvidas pelo fórum.
Importando e exportando dados
Faça o download dos objetos criados até agora clicando aqui
Os arquivos RData são exclusivos do R, clicando duas vezes no arquivo ou utilizando:
Você vai recuperar todos os objetos gerados até agora no tutorial.
Se tiver com acesso à internet. Você também pode usar o link web diretamente:
Para gerar esse arquivo RData, eu rodei todos os códigos daqui para cima e usei:
Este comando salva tudo o que você tem no seu Ambiente Global (todos os objetos que aparecem ali no canto direito superior). Você pode também salvar somente um objeto com:
Se removermos ele do nosso Ambiente Global com:
Podemos facilmente obtê-lo novamente com:
O formato RData é exclusivo para o R, ele é interessante de ser usado
para fazer o que estamos fazendo, paramos a análise em um dia, vamos
continuar em um outro e não queremos ter que rodar tudo de novo. Mas
muitas vezes precisamos exportar nossos dados para outros programas, que
exigem outros formatos, como, por exemplo, .txt
ou
.csv
. Para isso utilizamos:
write.table(campo1, file = "campo1.txt", sep = ";", dec = ".", row.names = FALSE)
write.csv(campo1, file = "campo1.csv", row.names = TRUE)
Obs: Você pode adquirir pacotes para exportar e importar dados com
outros formatos, como exemplo o pacote openxlsx
exporta e
importa dados com formato do excel. O pacote vroom
pode ser
utilizado para compactar grandes tabelas. Para instalar pacotes, utilize
a função install.packages("nome_do_pacote")
e para carregar
o pacote utilize library(nome_do_pacote)
.Veremos mais sobre
pacotes na sessão “Aplicação de Pacotes” deste curso.
Ao exportar, há diversas opções para a formatação do arquivo, é importante considerá-las se o arquivo for usado em outro software posteriormente.
Abra os arquivos gerados no seu bloco de notas para visualizar sua
formatação. Repare que o arquivo .txt
foi salvo com o
separador ;
e o separador decimal .
. Já o
arquivo .csv
foi salvo com o separador de vírgula
,
e o separador decimal .
.
Esses arquivos podem ser lidos novamente pelo R, utilizando as funções e suas especificações:
campo1_txt <- read.table(file = "campo1.txt", sep=";", dec=".", header = TRUE)
campo1_csv <- read.csv(file = "campo1.csv")
campo1_xlsx <- read.xlsx("campo1.xlsx", sheet = 1)
head(campo1_txt)
head(campo1_csv)
head(campo1_xlsx)
Agora que aprendemos a importar dados, vamos trabalhar com o conjunto gerado a partir do formulário enviado para vocês e para alunos de outras versões desse curso.
A planilha com os dados está disponível no link abaixo, adicione-a ao seu diretório de trabalho ou indique o caminho da pasta ao importá-la para dentro do R, como a seguir.
Também podemos importar os dados diretamente do github, apontando o endereço web.
Aqui usaremos também o argumento na.strings
que irá
indicar como foram nomeados os dados perdidos.
Vamos explorar a estrutura dos dados coletados:
## 'data.frame': 124 obs. of 8 variables:
## $ Timestamp : chr "07/04/2025 14:00:00" "07/04/2025 14:00:00" "07/04/2025 14:00:00" "07/04/2025 14:00:00" ...
## $ Affiliation : chr "Rcourse2021" "Rcourse2021" "Rcourse2021" "Rcourse2021" ...
## $ Using.Google.Maps..please.provide.the.longitude.of.the.city.country.of.your.birth. : chr "-54.5724" "-47.6476" "-48.0547" "-106.6563" ...
## $ Using.Google.Maps..please.provide.the.latitude.of.the.city.country.of.your.birth. : chr "-25.5263" "-22.725" "-15.911" "52.1418" ...
## $ Background.Field..e.g..Molecular.Biology..Animal.Breeding..Genetics..etc.. : chr "Agronomia" "Agronomia" "Biotecnologia" "Licenciatura em Ciências Biológicas" ...
## $ Current.professional.affiliation : chr "PhD" "PhD" "Masters degree" "Other" ...
## $ If.you.chose.other.in.the..current.professional.affiliation..question.above..please.specify.: chr NA NA NA NA ...
## $ Level.of.R.knowledge : chr "Intermediate" "Intermediate" "Beginner (some knowledge)" "Intermediate" ...
## [1] 124 8
Repare que nos nomes das colunas ainda estão as perguntas completas feitas no formulário, vamos alterar para nomes mais fáceis de trabalhar:
## [1] "Timestamp"
## [2] "Affiliation"
## [3] "Using.Google.Maps..please.provide.the.longitude.of.the.city.country.of.your.birth."
## [4] "Using.Google.Maps..please.provide.the.latitude.of.the.city.country.of.your.birth."
## [5] "Background.Field..e.g..Molecular.Biology..Animal.Breeding..Genetics..etc.."
## [6] "Current.professional.affiliation"
## [7] "If.you.chose.other.in.the..current.professional.affiliation..question.above..please.specify."
## [8] "Level.of.R.knowledge"
colnames(dados) = c("Data", "Afiliação", "Longitude", "Latitude", "Background", "Presente_Ocupação", "Explique", "ConhecimentoR")
colnames(dados)
## [1] "Data" "Afiliação" "Longitude"
## [4] "Latitude" "Background" "Presente_Ocupação"
## [7] "Explique" "ConhecimentoR"
## 'data.frame': 124 obs. of 8 variables:
## $ Data : chr "07/04/2025 14:00:00" "07/04/2025 14:00:00" "07/04/2025 14:00:00" "07/04/2025 14:00:00" ...
## $ Afiliação : chr "Rcourse2021" "Rcourse2021" "Rcourse2021" "Rcourse2021" ...
## $ Longitude : chr "-54.5724" "-47.6476" "-48.0547" "-106.6563" ...
## $ Latitude : chr "-25.5263" "-22.725" "-15.911" "52.1418" ...
## $ Background : chr "Agronomia" "Agronomia" "Biotecnologia" "Licenciatura em Ciências Biológicas" ...
## $ Presente_Ocupação: chr "PhD" "PhD" "Masters degree" "Other" ...
## $ Explique : chr NA NA NA NA ...
## $ ConhecimentoR : chr "Intermediate" "Intermediate" "Beginner (some knowledge)" "Intermediate" ...
Agora usaremos os dados que temos para aprender diferentes comandos e funções do Ambiente R.
Primeiro, vamos verificar quantos alunos responderam as questões do
formulario da disciplina, contando o número de linhas, para isso use a
função nrow
.
## [1] 124
Vamos então verificar se temos no nosso grupo pessoas que compartilham a mesma graduação e ocupação.
Podemos verificar isso facilmente com a função table
,
que indica a frequência de cada observação:
Estruturas condicionais
if e else
Para nossa próxima atividade com os dados, vamos primeiro entender
como funcionam as estruturas if
e else
.
Nas funções condicionais if
e else
,
estabelecemos uma condição para if, se ela for verdade a atividade será
realizada, caso contrário (else) outra tarefa será. Como no exemplo:
## dois não é maior que três
- Descubra a Nivel de Conhecimentos em R da segunda pessoa que o
respondeu (linha 2). Envie uma mensagem “Nível Intermediario” se for
intermediario ou “Nível Básico ou avançado” caso contrario. (dica: o
sinal
==
se refere a “exatamente igual a”)
## Data Afiliação Longitude Latitude
## 1 07/04/2025 14:00:00 Rcourse2021 -54.5724 -25.5263
## 2 07/04/2025 14:00:00 Rcourse2021 -47.6476 -22.725
## 3 07/04/2025 14:00:00 Rcourse2021 -48.0547 -15.911
## 4 07/04/2025 14:00:00 Rcourse2021 -106.6563 52.1418
## 5 07/04/2025 14:00:00 Rcourse2021 -47.6604 -22.7641
## 6 07/04/2025 14:00:00 Rcourse2021 -47.6434 -22.7118
## Background Presente_Ocupação Explique
## 1 Agronomia PhD <NA>
## 2 Agronomia PhD <NA>
## 3 Biotecnologia Masters degree <NA>
## 4 Licenciatura em Ciências Biológicas Other <NA>
## 5 Agronomia Profissional <NA>
## 6 Agronomia PhD <NA>
## ConhecimentoR
## 1 Intermediate
## 2 Intermediate
## 3 Beginner (some knowledge)
## 4 Intermediate
## 5 Beginner (some knowledge)
## 6 Intermediate
if(dados$ConhecimentoR[2] =="Intermediate"){
cat("Nível Intermediário")
} else {
cat("Nível Básico ou Avançado")
}
## Nível Intermediário
Podemos espeficiar mais do que uma condição repetindo a estrutura
if
else
: Agora vamos estudar a ocupação das
pessoas que responderam ao questionário.
if(dados$Presente_Ocupação[2] == "Other"){
print(dados$Explique[2])
} else if (dados$Presente_Ocupação[2] == "PhD"){
print(paste("O seu doutorado é em:",dados$Background[2], "?"))
} else {
print(paste("Você ainda trabalha com:", dados$Background[2], "?"))
}
## [1] "O seu doutorado é em: Agronomia ?"
Mas repare que só é possível utilizar essas estruturas para um elemento individual do vetor ou em todo ele, se quisermos percorrer os elementos individualmente precisamos recorrer a outro recurso.
Estruturas de repetição
For
Esse recurso pode ser a função for
, uma função muito
utilizada e poderosa. Ela constitui uma estrutura de loop, pois irá
aplicar a mesma atividade repetidamente até atingir uma determinada
condição. Veja exemplos:
## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 5
## [1] 6
## [1] 7
## [1] 8
## [1] 9
## [1] 10
## [1] 5 6 7 8 9 10 11 12 13 14
Nos casos acima, i
funciona como um índice que irá
variar de 1 até 10 a operação determinada entre chaves.
Com essa estrutura, podemos repetir a operação realizada com as
estruturas if
e else
para todo o vetor:
for(i in 1:nrow(dados)){
if(dados$Presente_Ocupação[i] == "Other"){
print(dados$Explique[i])
} else if (dados$Presente_Ocupação[i] == "PhD"){
print(paste("O seu doutorado é em:",dados$Background[i], "?"))
} else {
print(paste("Você ainda trabalha com:", dados$Background[i], "?"))
}
}
Repare que algumas pessoas não responderam quando perguntadas o que
queriam dizer com “outro”. Para evitar que o R retorne um erro, podemos
usar a função is.na
para verificar se a resposta é NA (não
disponível).
for(i in 1:nrow(dados)){
if(dados$Presente_Ocupação[i] == "Other"){
if(is.na(dados$Explique[i])) {
print("Esta pessoa não explicou o que quis dizer com 'outro'")
} else {
print(dados$Explique[i])
}
} else if (dados$Presente_Ocupação[i] == "PhD"){
print(paste("O seu doutorado é em:",dados$Background[i], "?"))
} else {
print(paste("Você ainda trabalha com:", dados$Background[i], "?"))
}
}
## [1] "O seu doutorado é em: Agronomia ?"
## [1] "O seu doutorado é em: Agronomia ?"
## [1] "Você ainda trabalha com: Biotecnologia ?"
## [1] "Esta pessoa não explicou o que quis dizer com 'outro'"
## [1] "Você ainda trabalha com: Agronomia ?"
## [1] "O seu doutorado é em: Agronomia ?"
## [1] "O seu doutorado é em: Zootecnia ?"
## [1] "O seu doutorado é em: Agronomia ?"
## [1] "O seu doutorado é em: Agronomia ?"
## [1] "O seu doutorado é em: Engenharia Florestal ?"
## [1] "O seu doutorado é em: Bacharel em Agronomia ?"
## [1] "Esta pessoa não explicou o que quis dizer com 'outro'"
## [1] "O seu doutorado é em: Engenharia Agrícola ?"
## [1] "O seu doutorado é em: Agronomia ?"
## [1] "Você ainda trabalha com: Engenharia Agronômica ?"
## [1] "Você ainda trabalha com: Ciências Biológicas ?"
## [1] "O seu doutorado é em: Agronomia ?"
## [1] "Você ainda trabalha com: Engenheiro Florestal ?"
## [1] "Você ainda trabalha com: Genética e Melhoramento de Plantas ?"
## [1] "Esta pessoa não explicou o que quis dizer com 'outro'"
## [1] "Você ainda trabalha com: Agronomia ?"
## [1] "Você ainda trabalha com: Engenharia Agronômica ?"
## [1] "O seu doutorado é em: Agronomia ?"
## [1] "O seu doutorado é em: Agronomia ?"
## [1] "Você ainda trabalha com: Ciências Biológicas ?"
## [1] "Você ainda trabalha com: Agronomia ?"
## [1] "Você ainda trabalha com: Ciências Biológicas ?"
## [1] "O seu doutorado é em: Engenharia Agronômica ?"
## [1] "Você ainda trabalha com: Ciências Biológicas ?"
## [1] "O seu doutorado é em: Agronomia ?"
## [1] "O seu doutorado é em: Biotecnologia ?"
## [1] "O seu doutorado é em: Biologia ?"
## [1] "Esta pessoa não explicou o que quis dizer com 'outro'"
## [1] "Você ainda trabalha com: Biologia ?"
## [1] "O seu doutorado é em: Agronomia ?"
## [1] "O seu doutorado é em: Biologia ?"
## [1] "Você ainda trabalha com: Agronomia ?"
## [1] "Você ainda trabalha com: Melhoramento genético ?"
## [1] "Esta pessoa não explicou o que quis dizer com 'outro'"
## [1] "O seu doutorado é em: Agronomia ?"
## [1] "Você ainda trabalha com: Ciências Biológicas ?"
## [1] "Você ainda trabalha com: Ciências Biológicas ?"
## [1] "Você ainda trabalha com: Agronomia ?"
## [1] "Você ainda trabalha com: Biologia ?"
## [1] "O seu doutorado é em: Agronomia ?"
## [1] "Você ainda trabalha com: Agronomia ?"
## [1] "Esta pessoa não explicou o que quis dizer com 'outro'"
## [1] "O seu doutorado é em: Zootecnia ?"
## [1] "Você ainda trabalha com: Agronomia ?"
## [1] "O seu doutorado é em: Biotecnologia ?"
## [1] "O seu doutorado é em: Agronomia ?"
## [1] "O seu doutorado é em: Agronomia ?"
## [1] "O seu doutorado é em: Agronomia ?"
## [1] "Você ainda trabalha com: Agronomia ?"
## [1] "O seu doutorado é em: Agronomia ?"
## [1] "O seu doutorado é em: Agronomia ?"
## [1] "Você ainda trabalha com: Agronomia ?"
## [1] "O seu doutorado é em: Genética e Melhoramento ?"
## [1] "Você ainda trabalha com: Agronomia ?"
## [1] "O seu doutorado é em: Agronomia ?"
## [1] "O seu doutorado é em: Agronomia ?"
## [1] "Esta pessoa não explicou o que quis dizer com 'outro'"
## [1] "O seu doutorado é em: Agronomia ?"
## [1] "O seu doutorado é em: Biologia ?"
## [1] "O seu doutorado é em: Genética e Melhoramento de Plantas ?"
## [1] "O seu doutorado é em: Agronomia ?"
## [1] "Você ainda trabalha com: Agronomia ?"
## [1] "O seu doutorado é em: Agronomia ?"
## [1] "O seu doutorado é em: Agronomia ?"
## [1] "O seu doutorado é em: Agronomia ?"
## [1] "O seu doutorado é em: Agronomia ?"
## [1] "Esta pessoa não explicou o que quis dizer com 'outro'"
## [1] "O seu doutorado é em: Agronomia ?"
## [1] "O seu doutorado é em: Engeheria em Biotecnologia Vegetal (Chile) ?"
## [1] "Você ainda trabalha com: AGRONOMIA ?"
## [1] "Você ainda trabalha com: Engenharia Agronômica ?"
## [1] "O seu doutorado é em: Agronomia ?"
## [1] "O seu doutorado é em: Agronomia ?"
## [1] "Você ainda trabalha com: Biología ?"
## [1] "O seu doutorado é em: Agronomia ?"
## [1] "O seu doutorado é em: Ciências Biológicas ?"
## [1] "Você ainda trabalha com: Agronomia ?"
## [1] "Você ainda trabalha com: Agronomia ?"
## [1] "O seu doutorado é em: Agronomia ?"
## [1] "O seu doutorado é em: Agronomia ?"
## [1] "O seu doutorado é em: Agronomia ?"
## [1] "O seu doutorado é em: Ciências Biológicas ?"
## [1] "O seu doutorado é em: Agronomia ?"
## [1] "O seu doutorado é em: Agronomia ?"
## [1] "Você ainda trabalha com: Agronomia ?"
## [1] "O seu doutorado é em: Agronomia ?"
## [1] "Você ainda trabalha com: Agronomia ?"
## [1] "O seu doutorado é em: Engenharia Biotecnológica ?"
## [1] "Você ainda trabalha com: Agronomia ?"
## [1] "Você ainda trabalha com: Agronomia ?"
## [1] "O seu doutorado é em: Engenharia Florestal ?"
## [1] "Você ainda trabalha com: Agronomia ?"
## [1] "O seu doutorado é em: Agronomia ?"
## [1] "Você ainda trabalha com: Biologia ?"
## [1] "O seu doutorado é em: Biologia ?"
## [1] "O seu doutorado é em: Ciências Biológicas ?"
## [1] "Você ainda trabalha com: Agronomia ?"
## [1] "Esta pessoa não explicou o que quis dizer com 'outro'"
## [1] "O seu doutorado é em: Agronomia ?"
## [1] "O seu doutorado é em: Engenheiro Agrônomo ?"
## [1] "O seu doutorado é em: Genética e Melhoramento ?"
## [1] "O seu doutorado é em: Agronomia ?"
## [1] "O seu doutorado é em: Agronomia ?"
## [1] "Esta pessoa não explicou o que quis dizer com 'outro'"
## [1] "O seu doutorado é em: Agronomia ?"
## [1] "Você ainda trabalha com: Agronomia ?"
## [1] "Esta pessoa não explicou o que quis dizer com 'outro'"
## [1] "Você ainda trabalha com: Engenharia Agronômica / Licenciatura em Ciências Agrárias ?"
## [1] "Você ainda trabalha com: Ciencias Biologicas ?"
## [1] "Você ainda trabalha com: Agronomia ?"
## [1] "O seu doutorado é em: Eng. Florestal ?"
## [1] "Postdoc"
## [1] "Você ainda trabalha com: Psychology ?"
## [1] "Você ainda trabalha com: Plant Genetics ?"
## [1] "Você ainda trabalha com: Plant Breeding ?"
## [1] "Finished my Masters "
## [1] "Você ainda trabalha com: Soil Sciencies ?"
## [1] "Masters degree"
## [1] "PhD"
Dica: Identação
Repare a diferença:
# Sem identação
for(i in 1:nrow(dados)){
if(dados$Presente_Ocupação[i] == "Other"){
if(is.na(dados$Explique[i])) {
print("Esta pessoa não explicou o que quis dizer com 'outro'")
} else {
print(dados$Explique[i])
}
} else if (dados$Presente_Ocupação[i] == "PhD"){
print(paste("O seu doutorado é em:",dados$Background[i], "?"))
} else {
print(paste("Você ainda trabalha com:", dados$Background[i], "?"))
}
}
O editor de código do RStudio tem uma facilitação para identar
códigos em R, selecione a área que deseja identar e aperte
Ctrl+i
.
Agora vamos trabalhar com a coluna 5, que possui a informação o
background dos participantes. Repare que a função table
retorna diferentes categorias que poderiam ser resumidas em apenas uma,
como “Engenharia agronômica” e “Agronomia”. Vamos utilizar um loop para
descobrir quais responderam áreas relacionadas à “Agro”. Depois, quais
dessas respostas não foram “Agronomia” e pedir para que este
participante modifique a resposta digitando apenas “Agronomia”.
Dica: Para identificar o padrão “Agro” podemos utilizar a função
grepl
.
## [1] "Agronomia"
## [2] "Agronomia"
## [3] "Biotecnologia"
## [4] "Licenciatura em Ciências Biológicas"
## [5] "Agronomia"
## [6] "Agronomia"
## [7] "Zootecnia"
## [8] "Agronomia"
## [9] "Agronomia"
## [10] "Engenharia Florestal"
## [11] "Bacharel em Agronomia"
## [12] "Engenharia Agronômica"
## [13] "Engenharia Agrícola"
## [14] "Agronomia"
## [15] "Engenharia Agronômica"
## [16] "Ciências Biológicas"
## [17] "Agronomia"
## [18] "Engenheiro Florestal"
## [19] "Genética e Melhoramento de Plantas"
## [20] "Agronomia"
## [21] "Agronomia"
## [22] "Engenharia Agronômica"
## [23] "Agronomia"
## [24] "Agronomia"
## [25] "Ciências Biológicas"
## [26] "Agronomia"
## [27] "Ciências Biológicas"
## [28] "Engenharia Agronômica"
## [29] "Ciências Biológicas"
## [30] "Agronomia"
## [31] "Biotecnologia"
## [32] "Biologia"
## [33] "Agronomia"
## [34] "Biologia"
## [35] "Agronomia"
## [36] "Biologia"
## [37] "Agronomia"
## [38] "Melhoramento genético"
## [39] "FAEM - UFPEL"
## [40] "Agronomia"
## [41] "Ciências Biológicas"
## [42] "Ciências Biológicas"
## [43] "Agronomia"
## [44] "Biologia"
## [45] "Agronomia"
## [46] "Agronomia"
## [47] "Eng. Agronômica"
## [48] "Zootecnia"
## [49] "Agronomia"
## [50] "Biotecnologia"
## [51] "Agronomia"
## [52] "Agronomia"
## [53] "Agronomia"
## [54] "Agronomia"
## [55] "Agronomia"
## [56] "Agronomia"
## [57] "Agronomia"
## [58] "Genética e Melhoramento"
## [59] "Agronomia"
## [60] "Agronomia"
## [61] "Agronomia"
## [62] "Ciências bilógicas"
## [63] "Agronomia"
## [64] "Biologia"
## [65] "Genética e Melhoramento de Plantas"
## [66] "Agronomia"
## [67] "Agronomia"
## [68] "Agronomia"
## [69] "Agronomia"
## [70] "Agronomia"
## [71] "Agronomia"
## [72] "Agronomia"
## [73] "Agronomia"
## [74] "Engeheria em Biotecnologia Vegetal (Chile)"
## [75] "AGRONOMIA"
## [76] "Engenharia Agronômica"
## [77] "Agronomia"
## [78] "Agronomia"
## [79] "Biología"
## [80] "Agronomia"
## [81] "Ciências Biológicas"
## [82] "Agronomia"
## [83] "Agronomia"
## [84] "Agronomia"
## [85] "Agronomia"
## [86] "Agronomia"
## [87] "Ciências Biológicas"
## [88] "Agronomia"
## [89] "Agronomia"
## [90] "Agronomia"
## [91] "Agronomia"
## [92] "Agronomia"
## [93] "Engenharia Biotecnológica"
## [94] "Agronomia"
## [95] "Agronomia"
## [96] "Engenharia Florestal"
## [97] "Agronomia"
## [98] "Agronomia"
## [99] "Biologia"
## [100] "Biologia"
## [101] "Ciências Biológicas"
## [102] "Agronomia"
## [103] "Agronomia"
## [104] "Agronomia"
## [105] "Engenheiro Agrônomo"
## [106] "Genética e Melhoramento"
## [107] "Agronomia"
## [108] "Agronomia"
## [109] "Biotecnologia"
## [110] "Agronomia"
## [111] "Agronomia"
## [112] "Biotecnologia"
## [113] "Engenharia Agronômica / Licenciatura em Ciências Agrárias"
## [114] "Ciencias Biologicas"
## [115] "Agronomia"
## [116] "Eng. Florestal"
## [117] "Genetics"
## [118] "Psychology"
## [119] "Plant Genetics"
## [120] "Plant Breeding"
## [121] "Climate Change"
## [122] "Soil Sciencies "
## [123] "Animal Science"
## [124] "Animal Breeding and Genetics"
## [1] TRUE TRUE FALSE FALSE TRUE TRUE FALSE TRUE TRUE FALSE TRUE TRUE
## [13] FALSE TRUE TRUE FALSE TRUE FALSE FALSE TRUE TRUE TRUE TRUE TRUE
## [25] FALSE TRUE FALSE TRUE FALSE TRUE FALSE FALSE TRUE FALSE TRUE FALSE
## [37] TRUE FALSE FALSE TRUE FALSE FALSE TRUE FALSE TRUE TRUE TRUE FALSE
## [49] TRUE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE TRUE TRUE
## [61] TRUE FALSE TRUE FALSE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [73] TRUE FALSE FALSE TRUE TRUE TRUE FALSE TRUE FALSE TRUE TRUE TRUE
## [85] TRUE TRUE FALSE TRUE TRUE TRUE TRUE TRUE FALSE TRUE TRUE FALSE
## [97] TRUE TRUE FALSE FALSE FALSE TRUE TRUE TRUE FALSE FALSE TRUE TRUE
## [109] FALSE TRUE TRUE FALSE TRUE FALSE TRUE FALSE FALSE FALSE FALSE FALSE
## [121] FALSE FALSE FALSE FALSE
## [1] "Agronomia"
## [2] "Agronomia"
## [3] "Agronomia"
## [4] "Agronomia"
## [5] "Agronomia"
## [6] "Agronomia"
## [7] "Bacharel em Agronomia"
## [8] "Engenharia Agronômica"
## [9] "Agronomia"
## [10] "Engenharia Agronômica"
## [11] "Agronomia"
## [12] "Agronomia"
## [13] "Agronomia"
## [14] "Engenharia Agronômica"
## [15] "Agronomia"
## [16] "Agronomia"
## [17] "Agronomia"
## [18] "Engenharia Agronômica"
## [19] "Agronomia"
## [20] "Agronomia"
## [21] "Agronomia"
## [22] "Agronomia"
## [23] "Agronomia"
## [24] "Agronomia"
## [25] "Agronomia"
## [26] "Agronomia"
## [27] "Eng. Agronômica"
## [28] "Agronomia"
## [29] "Agronomia"
## [30] "Agronomia"
## [31] "Agronomia"
## [32] "Agronomia"
## [33] "Agronomia"
## [34] "Agronomia"
## [35] "Agronomia"
## [36] "Agronomia"
## [37] "Agronomia"
## [38] "Agronomia"
## [39] "Agronomia"
## [40] "Agronomia"
## [41] "Agronomia"
## [42] "Agronomia"
## [43] "Agronomia"
## [44] "Agronomia"
## [45] "Agronomia"
## [46] "Agronomia"
## [47] "Agronomia"
## [48] "Engenharia Agronômica"
## [49] "Agronomia"
## [50] "Agronomia"
## [51] "Agronomia"
## [52] "Agronomia"
## [53] "Agronomia"
## [54] "Agronomia"
## [55] "Agronomia"
## [56] "Agronomia"
## [57] "Agronomia"
## [58] "Agronomia"
## [59] "Agronomia"
## [60] "Agronomia"
## [61] "Agronomia"
## [62] "Agronomia"
## [63] "Agronomia"
## [64] "Agronomia"
## [65] "Agronomia"
## [66] "Agronomia"
## [67] "Agronomia"
## [68] "Agronomia"
## [69] "Agronomia"
## [70] "Agronomia"
## [71] "Agronomia"
## [72] "Agronomia"
## [73] "Engenharia Agronômica / Licenciatura em Ciências Agrárias"
## [74] "Agronomia"
for(i in 1:nrow(dados)){
if(grepl("Agro", dados[i,5])){
if(dados[i,5] != "Agronomia"){
print("Por favor, substitua sua resposta por Agronomia.")
}
}
}
## [1] "Por favor, substitua sua resposta por Agronomia."
## [1] "Por favor, substitua sua resposta por Agronomia."
## [1] "Por favor, substitua sua resposta por Agronomia."
## [1] "Por favor, substitua sua resposta por Agronomia."
## [1] "Por favor, substitua sua resposta por Agronomia."
## [1] "Por favor, substitua sua resposta por Agronomia."
## [1] "Por favor, substitua sua resposta por Agronomia."
## [1] "Por favor, substitua sua resposta por Agronomia."
Repare que o código acima não retorna as linhas que não estão corretas, apenas imprime a mensagem. Para isso, precisamos armazenar essas linhas em um vetor e depois acessá-las.
homog <- vector()
for(i in 1:nrow(dados)){
if(grepl("Agro", dados[i,5])){
if(dados[i,5] != "Agronomia"){
print("Por favor, substitua sua resposta por Agronomia.")
homog <- c(homog, i)
}
}
}
## [1] "Por favor, substitua sua resposta por Agronomia."
## [1] "Por favor, substitua sua resposta por Agronomia."
## [1] "Por favor, substitua sua resposta por Agronomia."
## [1] "Por favor, substitua sua resposta por Agronomia."
## [1] "Por favor, substitua sua resposta por Agronomia."
## [1] "Por favor, substitua sua resposta por Agronomia."
## [1] "Por favor, substitua sua resposta por Agronomia."
## [1] "Por favor, substitua sua resposta por Agronomia."
## [1] 11 12 15 22 28 47 76 113
Como você faria para corrigir esses elementos errados? Tente!
‘dados[homog, 5] <- “Agronomia”’
While
Nesse tipo de estrutura de repetição a tarefa será realizada até que seja atingida determinada condição.
## 2345
É muito importante que nessa estrutura a condição seja atingida, caso contrário o loop irá funcionar infinitamente e você terá que interrompê-lo por meios externos. Um exemplo desses “meios externos” no RStudio é clicar no simbolo em vermelho no canto direito superior da janela do console. Você também pode apertar Ctrl+C no console.
Não é muito difícil disso acontecer, basta um pequeno erro como:
Aqui podemos utilizar os comandos break
e
next
para atender a outras condições, como:
## 23
## 235
Repeat
Esta estrutura também exige uma condição de parada, mas esta condição
é necessariamente colocada dentro do bloco de código com o uso do
break
. Ela então repete o bloco de código até a condição o
interrompa.
## 234
Loops dentro de loops
É possível também utilizarmos estruturas de repetição dentro de estruturas de repetição. Por exemplo, se quisermos trabalhar tanto nas colunas como nas linhas de uma matrix.
# Criando uma matrix vazia
ex_mat <- matrix(nrow=10, ncol=10)
# cada número dentro da matrix será o produto no índice da coluna pelo índice da linha
for(i in 1:dim(ex_mat)[1]) {
for(j in 1:dim(ex_mat)[2]) {
ex_mat[i,j] = i*j
}
}
Outro exemplo de uso:
var1 <- c("fertilizante1", "fertilizante2")
var2 <- c("ESS", "URO", "GRA")
w <- 1
for(i in var1){
for(j in var2){
nome_arquivo <- paste0(i,"_planta_",j,".txt")
arquivo <- data.frame("bloco" = "fake_data", "tratamento" ="fake_data")
write.table(arquivo, file = nome_arquivo)
w <- w + 1
}
}
# Verifique seu diretorio de trabalho, arquivos devem ter sido gerados
Se estiver adiantada/o em relação aos colegas, você já pode fazer os exercícios da Sessão 3, se não, faça-os em outro momento e nos envie dúvidas pelo fórum.
Algumas dicas:
- Cuidado ao rodar o mesmo comando mais de uma vez, algumas variáveis podem não ser mais como eram antes. Para que o comando funcione da mesma forma é necessário que os objetos de entrada estejam da forma como você espera.
- Lembrem-se que
=
é para definir objetos e==
é o sinal de igualdade. - Nas estruturas condicionais e de repetição, lembrem-se que é necessário manter a sintaxe esperada: If(){} e for(i in 1:10){}. No for, podemos trocar a letra que será o índice, mas é sempre necessário fornecer uma sequência de inteiros ou caracteres.
- Usar identação ajuda a visualizar o começo e fim de cada estrutura de código e facilita o abrir e fechar de chaves. Identação são aqueles espaços que usamos antes da linha, como:
# Criando uma matrix vazia
ex_mat <- matrix(nrow=10, ncol=10)
# cada número dentro da matrix será o produto no índice da coluna pelo índice da linha
for(i in 1:dim(ex_mat)[1]) { # Primeiro nível, não tem espaço
for(j in 1:dim(ex_mat)[2]) { # Segundo nível tem um espaço (tab)
ex_mat[i,j] = i*j # Terceiro nível tem dois espaços
} # Fechei o segundo nível
} # Fechei o primeiro nível
Vetorização
Embora loops sejam intuitivos e mais fáceis de entender, eles são mais lentos e menos eficientes do que a vetorização. A vetorização é uma técnica que permite aplicar operações em todos os elementos de um vetor ou matriz de uma só vez, sem a necessidade de iterar sobre cada elemento individualmente.
Aqui esta um simples exemplo de um codigo não vetorizado (utilizando loop) e sua versão vetorizada:
# Não vetorizado (usando loop)
numeros <- 1:5
resultado_loop <- numeric(length(numeros))
for(i in 1:length(numeros)) {
resultado_loop[i] <- numeros[i] * 2
}
# Abordagem vetorizada
numeros <- 1:5
resultado_vetorizado <- numeros * 2
resultado_loop == resultado_vetorizado
## [1] TRUE TRUE TRUE TRUE TRUE
Essa transformação de código pode se tornar mais complexa dependendo do cenário. Por exemplo, pense como seria uma versão vetorizada do loop anterior:
# Não vetorizado (usando loop)
ex_mat <- matrix(nrow=10, ncol=10)
for(i in 1:dim(ex_mat)[1]) {
for(j in 1:dim(ex_mat)[2]) {
ex_mat[i,j] = i*j
}
}
# Vetorizado?
Aqui é um bom momento para você praticar a utilizar de uma ferramenta AI para te ajudar a transformar o código em uma versão vetorizada. Você pode utilizar o chatgpt ou o copilot, por exemplo. Compare o resultado do código fornecido com o que você gerou com o loop para verificar se a ferramenta está realmente fazendo o que você deseja. Essa transformação vale a pena se o código em loop estiver muito demorado ou se você tiver que rodar o mesmo código muitas vezes.
’ex_mat <- outer(1:10, 1:10, “*“)’
Criando funções
Se você já está se sentindo confortável com o uso de loops, você pode estar se perguntando: “E se eu quiser fazer isso várias vezes?” ou “E se eu quiser aplicar essa lógica a diferentes conjuntos de dados?”. É aqui que as funções entram em cena.
Podemos criar funções personalizadas para realizar tarefas específicas. A sintaxe básica para criar uma função no R é a seguinte:
minha_funcao <- function(arg1, arg2) {
# Código da função
resultado <- arg1 + arg2
return(resultado)
}
A função minha_funcao
recebe dois argumentos
(arg1
e arg2
) e retorna a soma deles. Você
pode chamar essa função passando os valores desejados:
## [1] 8
Exemplo de função personalizada com vetorização:
soma_vetorizada <- function(vetor) {
# Verifica se o vetor é numérico
if (!is.numeric(vetor)) {
stop("O vetor deve ser numérico.")
}
# Realiza a soma dos elementos do vetor
# A função sum() já é vetorizada, então não precisamos de um loop
# para somar os elementos
soma <- sum(vetor)
# Padronizando z-score
z_score <- (vetor - mean(vetor)) / sd(vetor)
resultado <- list(soma = soma, z_score = z_score)
return(resultado)
}
# Chamando a função
resultado_vetorizado <- soma_vetorizada(c(1, 2, 3, 4, 5))
resultado_vetorizado
## $soma
## [1] 15
##
## $z_score
## [1] -1.2649111 -0.6324555 0.0000000 0.6324555 1.2649111
Exemplo de função utilizando a data.frame como entrada. Note o uso repetitivo da função vai exigir que o dado de entrada tenha o mesmo formato ou pelo menos as colunas que serão utilizadas na função. Uma boa prática é verificar se as colunas necessárias estão presentes no data.frame antes de realizar os cálculos.
## clone altura diametro idade corte volume
## 1 GRA02 30.1 0.26 3 FALSE 1.597287
## 2 URO01 30.4 0.30 4 FALSE 2.147760
## 3 URO03 40.0 0.36 5 FALSE 4.069440
## 4 GRA02 30.2 0.24 3 FALSE 1.365523
## 5 GRA01 30.6 0.27 4 FALSE 1.751131
## 6 URO01 40.1 0.35 5 TRUE 3.856116
calc_volume <- function(data_frame) {
# Verifica se as colunas necessárias estão presentes
if (!all(c("diametro", "altura") %in% colnames(data_frame))) {
stop("As colunas 'diametro' e 'altura' devem estar presentes no data frame.")
}
# Calcula o volume
volume <- 3.14 * ((data_frame$diametro / 2)^2) * data_frame$altura
return(volume)
}
Família de funções apply
A família de funções apply
também podem funcionar como
um estrutura de repetição. Sua sintaxe é mais enxuta quando comparada
com for
ou while
e pode facilitar a elaboração
do código.
Aqui vamos exemplificar o uso de algumas dessas funções.
apply
A função apply
é a base de todas as outras funções da
família, portanto a compreensão do funcionamento desta é essencial para
entender as demais. Se buscar no help da função, ele indicará que os
argumentos da função consistem em: apply(X, MARGIN, FUN, …). Sendo X o
conjunto de dados em formato de array (incluindo matrix, que consiste
num array de dimensão 2), MARGIN será 1 se a ação deverá ser aplicada à
linhas, 2 se for aplicada a colunas e c(1,2) se for aplicada a ambas;
FUN é a função que indica ação.
Num simples exemplo temos a matrix:
Se quisermos somar os elementos das colunas usamos:
## [1] 3 15 27 39
Se quisermos somar os elementos das linhas:
## [1] 36 48
Se fossemos utilizar o for
para realizar essa
tarefa:
## [1] 3
## [1] 15
## [1] 27
## [1] 39
## [1] 36
## [1] 48
Agora um exemplo utilizando uma função personalizada. Vamos criar um
função para a padronização z-score, que é uma transformação comum em
estatística. A função zscore
irá calcular o z-score de um
vetor de números. O z-score é calculado subtraindo a média do vetor e
dividindo pelo desvio padrão.
# Definindo a função
zscore <- function(vetor) {
# Padronizando z-score
resultado <- (vetor - mean(vetor)) / sd(vetor)
return(resultado)
}
# Aplicando a função à matriz
resultados_linhas <- apply(ex_mat, 1, function(x) zscore(x)) # nas linhas
resultados_linhas
## [,1] [,2]
## [1,] -1.1618950 -1.1618950
## [2,] -0.3872983 -0.3872983
## [3,] 0.3872983 0.3872983
## [4,] 1.1618950 1.1618950
## [,1] [,2] [,3] [,4]
## [1,] -0.7071068 -0.7071068 -0.7071068 -0.7071068
## [2,] 0.7071068 0.7071068 0.7071068 0.7071068
lapply
Se diferencia do apply
por poder receber vetores e
listas (mais utilizado com listas) e devolver o resultado em uma
lista.
ex_list <- list(A=matrix(seq(0,21,3), nrow = 2),
B=matrix(seq(0,14,2), nrow = 2),
C= matrix(seq(0,39,5), nrow = 2))
str(ex_list)
## List of 3
## $ A: num [1:2, 1:4] 0 3 6 9 12 15 18 21
## $ B: num [1:2, 1:4] 0 2 4 6 8 10 12 14
## $ C: num [1:2, 1:4] 0 5 10 15 20 25 30 35
Para selecionar a segunda coluna de todas as matrizes
## $A
## [1] 3
##
## $B
## [1] 2
##
## $C
## [1] 5
Usando com uma função personalizada:
# Aplicando a função zscore à lista
resultados <- lapply(ex_list, function(x) apply(x, 1, zscore))
resultados
## $A
## [,1] [,2]
## [1,] -1.1618950 -1.1618950
## [2,] -0.3872983 -0.3872983
## [3,] 0.3872983 0.3872983
## [4,] 1.1618950 1.1618950
##
## $B
## [,1] [,2]
## [1,] -1.1618950 -1.1618950
## [2,] -0.3872983 -0.3872983
## [3,] 0.3872983 0.3872983
## [4,] 1.1618950 1.1618950
##
## $C
## [,1] [,2]
## [1,] -1.1618950 -1.1618950
## [2,] -0.3872983 -0.3872983
## [3,] 0.3872983 0.3872983
## [4,] 1.1618950 1.1618950
sapply
sapply
é uma variação de lapply
que tenta
simplificar o resultado. Ele aplica uma função a cada elemento de uma
lista ou vetor, assim como lapply
, mas tenta retornar um
vetor, matriz ou array — em vez de sempre retornar uma lista.
## A B C
## 3 2 5
# Aplicando a função zscore à lista
resultados <- sapply(ex_list, function(x) apply(x, 1, zscore))
resultados
## A B C
## [1,] -1.1618950 -1.1618950 -1.1618950
## [2,] -0.3872983 -0.3872983 -0.3872983
## [3,] 0.3872983 0.3872983 0.3872983
## [4,] 1.1618950 1.1618950 1.1618950
## [5,] -1.1618950 -1.1618950 -1.1618950
## [6,] -0.3872983 -0.3872983 -0.3872983
## [7,] 0.3872983 0.3872983 0.3872983
## [8,] 1.1618950 1.1618950 1.1618950
tapply
Esta função é um pouco diferente das demais, ela exige que exista alguma variável categórica (fator) para aplicar ação separadamente conforme suas categorias (levels). Por isso, normalmente é aplicada a data.frames.
Vamos utilizar nosso conjunto de dados:
## 'data.frame': 124 obs. of 8 variables:
## $ Data : chr "07/04/2025 14:00:00" "07/04/2025 14:00:00" "07/04/2025 14:00:00" "07/04/2025 14:00:00" ...
## $ Afiliação : chr "Rcourse2021" "Rcourse2021" "Rcourse2021" "Rcourse2021" ...
## $ Longitude : chr "-54.5724" "-47.6476" "-48.0547" "-106.6563" ...
## $ Latitude : chr "-25.5263" "-22.725" "-15.911" "52.1418" ...
## $ Background : chr "Agronomia" "Agronomia" "Biotecnologia" "Licenciatura em Ciências Biológicas" ...
## $ Presente_Ocupação: chr "PhD" "PhD" "Masters degree" "Other" ...
## $ Explique : chr NA NA NA NA ...
## $ ConhecimentoR : chr "Intermediate" "Intermediate" "Beginner (some knowledge)" "Intermediate" ...
dados$Afiliação <- as.factor(dados$`Afiliação`)
dados$ConhecimentoR_num <- NA
dados$ConhecimentoR_num[dados$ConhecimentoR == "Advanced"] <- 3
dados$ConhecimentoR_num[dados$ConhecimentoR == "Intermediate"] <- 2
dados$ConhecimentoR_num[dados$ConhecimentoR == "Beginner (some knowledge)"] <- 1
dados$ConhecimentoR_num[dados$ConhecimentoR == "No R knowledge"] <- 0
dados$ConhecimentoR_num[dados$ConhecimentoR == ""] <- NA
tapply(dados$ConhecimentoR_num, dados$Afiliação, mean)
## Agronomic Engineer
## 1.00000
## Breeding Insight
## 1.75000
## CIA Central Pecuario
## 0.00000
## INTA
## 1.00000
## National Institute of Innovation and Transfer in Agricultural Technology
## 2.00000
## Rcourse2021
## 1.87069
## Agronomic Engineer
## 1.00000
## Breeding Insight
## 1.75000
## CIA Central Pecuario
## 0.00000
## INTA
## 1.00000
## National Institute of Innovation and Transfer in Agricultural Technology
## 2.00000
## Rcourse2021
## 1.87069
mapply
A função mapply
é uma versão multivariada da função
sapply
. Ela aplica uma função a múltiplos vetores ou
listas, retornando um vetor ou matriz. A sintaxe é semelhante à de
sapply
, mas permite passar vários argumentos para a
função.
# Exemplo de uso do mapply
# Definindo uma função simples
soma <- function(x, y) {
return(x + y)
}
# Criando dois vetores
vetor1 <- c(1, 2, 3)
vetor2 <- c(4, 5, 6)
# Aplicando a função soma a cada par de elementos dos vetores
resultado_mapply <- mapply(soma, vetor1, vetor2)
print(resultado_mapply)
## [1] 5 7 9
# Exemplo de uso do mapply com mais de dois vetores
# Definindo uma função simples
multiplicacao <- function(x, y, z) {
return(x * y * z)
}
# Criando três vetores
vetor1 <- c(1, 2, 3)
vetor2 <- c(4, 5, 6)
vetor3 <- c(7, 8, 9)
# Aplicando a função multiplicacao a cada tripla de elementos dos vetores
resultado_mapply <- mapply(multiplicacao, vetor1, vetor2, vetor3)
print(resultado_mapply)
## [1] 28 80 162
# Exemplo de uso do mapply com uma função anônima
# Criando dois vetores
vetor1 <- c(1, 2, 3)
vetor2 <- c(4, 5, 6)
# Aplicando uma função anônima que calcula a soma e o produto
resultado_mapply <- mapply(function(x, y) {
return(c(soma = x + y, produto = x * y))
}, vetor1, vetor2)
print(resultado_mapply)
## [,1] [,2] [,3]
## soma 5 7 9
## produto 4 10 18
# Exemplo de uso do mapply com uma função personalizada
# Definindo uma função personalizada
soma_produto <- function(x, y) {
return(c(soma = x + y, produto = x * y))
}
# Criando dois vetores
vetor1 <- c(1, 2, 3)
vetor2 <- c(4, 5, 6)
# Aplicando a função soma_produto a cada par de elementos dos vetores
resultado_mapply <- mapply(soma_produto, vetor1, vetor2)
print(resultado_mapply)
## [,1] [,2] [,3]
## soma 5 7 9
## produto 4 10 18
# Exemplo de uso do mapply com uma função personalizada e mais de dois vetores
# Definindo uma função personalizada
soma_produto <- function(x, y, z) {
return(c(soma = x + y + z, produto = x * y * z))
}
# Criando três vetores
vetor1 <- c(1, 2, 3)
vetor2 <- c(4, 5, 6)
vetor3 <- c(7, 8, 9)
# Aplicando a função soma_produto a cada tripla de elementos dos vetores
resultado_mapply <- mapply(soma_produto, vetor1, vetor2, vetor3)
print(resultado_mapply)
## [,1] [,2] [,3]
## soma 12 15 18
## produto 28 80 162
Se estiver adiantada/o em relação aos colegas, você já pode fazer os exercícios da Sessão extra, se não, faça-os no conforto do seu lar e nos envie dúvidas pelo fórum.
Formatos Longo e Largo
Na análise e visualização de dados com R, especialmente usando o
tidyverse
, a estrutura dos seus dados é muito importante. O
tidyverse
é uma coleção de pacotes do R voltados para
ciência de dados, e enfatiza o uso de princípios de dados organizados
(“tidy data”). Dados organizados seguem uma estrutura padronizada que
facilita o trabalho com eles. Aqui está uma lista de todos os pacotes
incluídos no tidyverse
:
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.4 ✔ readr 2.1.5
## ✔ forcats 1.0.0 ✔ stringr 1.5.1
## ✔ ggplot2 3.5.2 ✔ tibble 3.2.1
## ✔ lubridate 1.9.4 ✔ tidyr 1.3.1
## ✔ purrr 1.0.4
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
## [1] "broom" "conflicted" "cli" "dbplyr"
## [5] "dplyr" "dtplyr" "forcats" "ggplot2"
## [9] "googledrive" "googlesheets4" "haven" "hms"
## [13] "httr" "jsonlite" "lubridate" "magrittr"
## [17] "modelr" "pillar" "purrr" "ragg"
## [21] "readr" "readxl" "reprex" "rlang"
## [25] "rstudioapi" "rvest" "stringr" "tibble"
## [29] "tidyr" "xml2" "tidyverse"
Existem dois principais formatos para organizar os dados:
- Formato largo (wide): uma linha por sujeito, com múltiplas colunas para medidas repetidas.
- Formato longo (long): uma linha por observação,
tornando os dados organizados e compatíveis com ferramentas como o
ggplot2
.
Vamos considerar um conjunto de dados mostrando a população (em milhões) de 10 países ao longo de três anos:
# Dados no formato largo (estimativas realistas de população em milhões)
data_wide <- tibble(
country = c(
"EUA", "Canadá", "México", "Brasil", "Costa Rica",
"Uruguai", "China", "Japão", "Índia", "Groenlândia"
),
`2000` = c(282, 31, 98, 174, 4, 3.3, 1267, 127, 1050, 0.056),
`2010` = c(309, 34, 112, 196, 4.5, 3.4, 1340, 128, 1230, 0.057),
`2020` = c(331, 38, 126, 213, 5, 3.5, 1402, 126, 1380, 0.056)
)
data_wide
## # A tibble: 10 × 4
## country `2000` `2010` `2020`
## <chr> <dbl> <dbl> <dbl>
## 1 EUA 282 309 331
## 2 Canadá 31 34 38
## 3 México 98 112 126
## 4 Brasil 174 196 213
## 5 Costa Rica 4 4.5 5
## 6 Uruguai 3.3 3.4 3.5
## 7 China 1267 1340 1402
## 8 Japão 127 128 126
## 9 Índia 1050 1230 1380
## 10 Groenlândia 0.056 0.057 0.056
Use pivot_longer()
para converter de formato largo para
longo:
data_long <- pivot_longer(data_wide,
cols = -country,
names_to = "year",
values_to = "population"
)
data_long
## # A tibble: 30 × 3
## country year population
## <chr> <chr> <dbl>
## 1 EUA 2000 282
## 2 EUA 2010 309
## 3 EUA 2020 331
## 4 Canadá 2000 31
## 5 Canadá 2010 34
## 6 Canadá 2020 38
## 7 México 2000 98
## 8 México 2010 112
## 9 México 2020 126
## 10 Brasil 2000 174
## # ℹ 20 more rows
Note que nosso data.frame
foi convertido para o formato
tibble
. Tibbles são uma versão moderna dos
data.frames
, projetadas para serem mais fáceis de usar e
mais eficientes. Elas fazem parte do pacote tidyverse
e são
amplamente utilizadas em análises de dados. Veja a comparação
abaixo:
Característica | data.frame | tibble (do pacote tibble) |
---|---|---|
Base ou Tidyverse | Base R | Parte do tidyverse |
Impressão | Imprime tudo | Mostra prévia (10 linhas) |
Tipos de colunas | Pode converter | Sem conversão automática |
Indexação | df[,1] retorna vetor |
tibble[,1] retorna tibble |
Nomes de linha | Sempre possui | Não usa nomes de linha |
A maioria das funções do tidyverse
, especialmente o
ggplot2
, funcionam melhor com dados no formato longo. Veja
um exemplo:
ggplot(data_long, aes(x = year, y = population, color = country, group = country)) +
geom_line(size = 1.2) +
geom_point(size = 2) +
labs(
title = "População ao Longo do Tempo (em Milhões)",
x = "Ano",
y = "População (Milhões)"
) +
theme_minimal()
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
Tabelas em formato largo geralmente são mais fáceis de exportar para
CSV ou Excel. Para voltar ao formato largo, use
pivot_wider()
:
data_wide_back <- pivot_wider(data_long,
names_from = year,
values_from = population
)
data_wide_back
## # A tibble: 10 × 4
## country `2000` `2010` `2020`
## <chr> <dbl> <dbl> <dbl>
## 1 EUA 282 309 331
## 2 Canadá 31 34 38
## 3 México 98 112 126
## 4 Brasil 174 196 213
## 5 Costa Rica 4 4.5 5
## 6 Uruguai 3.3 3.4 3.5
## 7 China 1267 1340 1402
## 8 Japão 127 128 126
## 9 Índia 1050 1230 1380
## 10 Groenlândia 0.056 0.057 0.056
Introdução ao uso do pipe
O operador pipe (%>%
) é uma ferramenta poderosa em R,
especialmente com o tidyverse
. Ele permite encadear funções
de forma clara e legível, evitando a necessidade de aninhar chamadas de
funções.
Quando se tem várias operações a serem aplicadas a um conjunto de dados, o uso do pipe é ideal:
data_wide_back <- data_long %>%
pivot_wider(
names_from = year,
values_from = population
) %>%
mutate(total_population = `2000` + `2010` + `2020`) %>%
arrange(desc(total_population))
Outras funções úteis: filter()
para filtrar linhas,
select()
para selecionar colunas:
data_wide_back <- data_long %>%
pivot_wider(
names_from = year,
values_from = population
) %>%
mutate(total_population = `2000` + `2010` + `2020`) %>%
arrange(desc(total_population)) %>%
filter(total_population > 1000) %>%
select(country, total_population)
Também podemos usar summarise()
para calcular
estatísticas por grupo:
data_summary <- data_long %>%
group_by(year) %>%
summarise(
total_population = sum(population, na.rm = TRUE),
avg_population = mean(population, na.rm = TRUE),
max_population = max(population, na.rm = TRUE)
)
data_summary
## # A tibble: 3 × 4
## year total_population avg_population max_population
## <chr> <dbl> <dbl> <dbl>
## 1 2000 3036. 304. 1267
## 2 2010 3357. 336. 1340
## 3 2020 3625. 362. 1402
O pipe %>%
vem do pacote dplyr
, mas
também está disponível no R base como |>
. A principal
diferença é que %>%
permite o uso do .
como
marcador de posição:
##
## Call:
## lm(formula = `2020` ~ `2000`, data = .)
##
## Residuals:
## Min 1Q Median 3Q Max
## -105.426 -4.807 -1.463 3.357 130.481
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.5810 23.1470 0.068 0.947
## `2000` 1.1885 0.0434 27.384 3.41e-09 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 60.18 on 8 degrees of freedom
## Multiple R-squared: 0.9894, Adjusted R-squared: 0.9881
## F-statistic: 749.9 on 1 and 8 DF, p-value: 3.409e-09
Já no pipe do R base (|>
), você precisa usar uma
função anônima:
##
## Call:
## lm(formula = `2020` ~ `2000`, data = df)
##
## Residuals:
## Min 1Q Median 3Q Max
## -105.426 -4.807 -1.463 3.357 130.481
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.5810 23.1470 0.068 0.947
## `2000` 1.1885 0.0434 27.384 3.41e-09 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 60.18 on 8 degrees of freedom
## Multiple R-squared: 0.9894, Adjusted R-squared: 0.9881
## F-statistic: 749.9 on 1 and 8 DF, p-value: 3.409e-09
Introdução ao ggplot2
O ggplot2
é um pacote poderoso e flexível para criar
visualizações em R. Ele segue os princípios da Gramática dos
Gráficos, que define componentes estruturados para construir
visualizações.
Principais componentes:
- Dados: Conjunto de dados utilizado.
- Estéticas (
aes
): Propriedades visuais como posição, cor, tamanho. - Geometrias (
geom
): Tipos de gráfico, como pontos, linhas, barras. - Estatísticas (
stat
): Transformações aplicadas aos dados. - Escalas (
scale
): Ajustes das mapeamentos estéticos. - Coordenadas (
coord
): Sistema de coordenadas. - Facetamento (
facet
): Painéis múltiplos com subconjuntos dos dados.
Exemplos:
Com stat_summary
:
ggplot(data_long, aes(x = year, y = population)) +
stat_summary(fun = mean, geom = "line", group = 1) +
labs(title = "Tendência Média de População")
Com escalas de cor personalizadas:
ggplot(data_long, aes(x = year, y = population, group = country, color = country)) +
geom_line(size = 1.2) +
scale_color_manual(values = c("China" = "red", "India" = "orange", "USA" = "blue")) +
labs(title = "População por País")
Com a paleta viridis
:
## Loading required package: viridisLite
ggplot(data_long, aes(x = year, y = population, group = country, color = country)) +
geom_line(size = 1.2) +
scale_color_viridis_d() +
labs(title = "População por País (Viridis)")
Coordenadas invertidas:
ggplot(data_long %>% filter(year == "2020"), aes(x = country, y = population)) +
geom_col() +
coord_flip() +
labs(title = "População por País em 2020")
Facetamento:
ggplot(data_long, aes(x = year, y = population)) +
geom_line(group = 1) +
facet_wrap(~ country) +
labs(title = "Tendência Populacional por País")
Personalização de rótulos e temas:
ggplot(data_long, aes(x = year, y = population, color = country, group = country)) +
geom_line(size = 1.2) +
labs(
title = "População ao Longo do Tempo por País",
subtitle = "Dados simulados (em milhões)",
x = "Ano",
y = "População (Milhões)",
caption = "Fonte: Dados simulados"
) +
theme_minimal() + theme(
plot.title = element_text(size = 18, face = "bold"),
axis.title = element_text(size = 14),
legend.title = element_text(size = 12)
)
Criando mapas com ggplot2
dados <- read.csv("https://breeding-insight.github.io/learn-hub/r-intro/data/dados_2025.csv")
colnames(dados) <- c("Data", "Afiliação", "Longitude", "Latitude", "Formação", "Ocupação_Atual", "Explica", "ConhecimentoR")
dados$ConhecimentoR_num <- NA
dados$ConhecimentoR_num[dados$ConhecimentoR == "Avançado"] <- 3
dados$ConhecimentoR_num[dados$ConhecimentoR == "Intermediário"] <- 2
dados$ConhecimentoR_num[dados$ConhecimentoR == "Iniciante (algum conhecimento)"] <- 1
dados$ConhecimentoR_num[dados$ConhecimentoR == "Sem conhecimento em R"] <- 0
world_map <- map_data("world")
dados$Latitude <- as.numeric(dados$Latitude)
## Warning: NAs introduced by coercion
## Warning: NAs introduced by coercion
# Mapa simples
ggplot() +
geom_polygon(data = world_map, aes(x = long, y = lat, group = group), fill = "gray90", color = "white") +
geom_point(data = dados, aes(x = Longitude, y = Latitude), alpha = 0.7) +
labs(title = "Alunos do curso de R", x = "Longitude", y = "Latitude") +
theme_minimal()
## Warning: Removed 4 rows containing missing values or values outside the scale range
## (`geom_point()`).
# Com cor por ocupação atual
ggplot() +
geom_polygon(data = world_map, aes(x = long, y = lat, group = group), fill = "gray90", color = "white") +
geom_point(data = dados, aes(x = Longitude, y = Latitude, color = Ocupação_Atual), alpha = 0.7) +
labs(title = "Alunos do curso de R", x = "Longitude", y = "Latitude") +
theme_minimal()
## Warning: Removed 4 rows containing missing values or values outside the scale range
## (`geom_point()`).
# Paleta viridis (acessível para daltônicos)
ggplot() +
geom_polygon(data = world_map, aes(x = long, y = lat, group = group), fill = "gray90", color = "white") +
geom_point(data = dados, aes(x = Longitude, y = Latitude, color = Ocupação_Atual), alpha = 0.7) +
scale_colour_viridis_d() +
labs(title = "Alunos do curso de R", x = "Longitude", y = "Latitude") +
theme_minimal()
## Warning: Removed 4 rows containing missing values or values outside the scale range
## (`geom_point()`).