© Ricardo Solar/UFMG - compartilhamento e utilização não-comercial livres. Não reproduzir sem autorização
A primeira coisa que será necessário é instalar os programas R e RStudio. Para isso, gravei um vídeo mostrando como fazer essa instalação. Tenha certeza que seu computador tem os programas instalados e funcionando. Instale os softwares R primeiro e depois RStudio, seguem abaixo os links para os programas:
É sempre importante, ao utilizar o R, que cada nova análise que você faça tenha seus arquivos colocados em uma nova pasta. Trabalharemos com muitos arquivos no curso, bem como nas nossas análises. Colocar os arquivos em pastas separadas por cada análise fará com que você se organize melhor, encontrando mais fácil os arquivos que utilizou, scripts e plots. Outra coisa importante em utilizar pastas distintas é que você evitará conflitos entre arquivos.
O R é um software programado originalmente em inglês. Isso significa que ele não lida bem com acentos e caracteres especiais, como por exemplo ~ ! @ # $ % ˆ & * ( ) ‘ ; < > ? , [ ] { } ’ ” e outros caracteres que usamos nos nossos textos. Outra coisa que dificulta o dia-a-dia de quem usa R são os espaços, busque evitá-los e utilize o underline ( _ ) no lugar do espaço. Esta mesma dica vale para os nomes dentros das tabelas que faremos e para os nomes dos objetos que vamos criar dentro do R. Por fim, o programa irá diferenciar letras MAIÚSCULAS de minúsculas, você pode ficar a vontade pra usar qualquer um deles, mas é importante lembrar disso quando for chamar um determinado nome. Essas são dicas básicas, mas que vão facilitar bastante o seu relacionamente com o programa.
Ainda que seja possível fazer todas as suas análises diretamente no console do R, é sempre desejável manter um registro dos comandos que utilizamos, de maneira que possamos ter isso salvo no computador. Isso também é importante para que possamos garantir a replicabilidade do nosso código e também para que possamos compartilhar o que fizemos de maneira organizada. Dessa forma, iremos aprender a utilizar o script de análise e, mais importante, a fazer um documento que registra os resultados de nossas análises de maneira organizada e inteligível, o Rmarkdown.
Principalmente por conta do RStudio, muitas atividades corriqueiras do R ganharam botões de acesso rápido pelo mouse. Ainda que esses sejam bastante úteis quando estamos no desespero, saber fazer o comando original e garantir que o seu input no mouse não seja necessário aumenta muito o potencial de uso do programa. Uma das maiores vantagens de trabalhar em um software como o R é a possibilidade de automatizar tarefas repetitivas. Nesse sentido, evitar que você precise necessariamete clicar com o mouse a cada repetição acelera muito seu fluxo de trabalho. A título de exemplo, suponhamos que você pediu uma tarefa em que o computador repita 100 vezes determinada rotina (um exemplo bem pequenino) … imagine tenho que estar lá pra clicar a cada uma dessas repetições? Aprender a fazer as tarefas por linhas de comando pode parecer mais complicado no início, mas acredite em mim, salvam um tempo descomunal depois.
No R, é possível inserir linhas de comando que não será executado. Chamamos isso de comentar o texto e esses comentários começam com uma hashtag (#). Você pode usar esses comentários a vontade, garantindo assim que sabe porque cada comando está sendo feito.
# um comentário aparece assim no R
Na primeira vez que você abrir o RStudio após tê-lo instalado no seu computador, três janelas serão apresentadas. Há ainda uma quarta janela, a janela Fonte (ou Source), que é aberta pressionando Ctrl + Shift + N, ou Command + Shift + N (nos Mac). Ainda, é possível fazer isso pelo menu File > New File > R Script.
Pra começarmos, abra um novo script, conforme descrito acima.
Agora, para praticarmos, vamos utilizar o programa para fazer opeações matemáticas simples, aumentando gradativamente o nosso grau de dificuldade até ganharmos confiança.
Vamos começar com duas operações bem simples
8+9
Ao executarmos essa operação, veremos o seguinte retorno no console:
8+9
## [1] 17
O resultado que aparece no console é então o resultado da soma que pedimos, precedido deste [1]. O que este número entre colchetes significa é a posição do primeiro elemento naquela linha do vetor. Quando tivermos vetores maiores, vamos ver que esses números aparecerão a cada nova linha, marcando a posição do primeiro elemento dela. A esse número entre colchetes damos o nome de indexador, e ele será muito útil em breve.
Vamos agora experimentar outras operações:
#soma
8+9
## [1] 17
#subtracao
8-9
## [1] -1
#multiplicação
8*9
## [1] 72
#divisao
8/9
## [1] 0.8888889
O R segue a ordem padrão de operações matemáticas: primeiro expoentes e raízes, seguidos por multiplicação e divisão, depois adição e subtração. Para garantir uma determinada ordem de nosso interesse, devemos agrupar as operações por parênteses. Por exemplo, essas duas linhas de código irão produzir resultados diferentes:
#nesta primeira
8+9/3
## [1] 11
#e na segunda
(8+9)/3
## [1] 5.666667
No primeiro caso, primeiro o R fez a divisão (9/3) e depois somou o 8 ao resultado. No segundo, primeiro foi feita a soma dentro dos parênteses e só depois a divisão por 3. É muito importante que prestemos atenção para que o computador produza exatamente o resultado que queremos. Use a abuse dos parênteses!
No trabalho corriqueiro com o R, utilizaremos diversas funções. Elas são a forma que temos sempre que queremos que R faça algo (modelos, cálculos, carregamento de dados, plotagem, etc). Uma função sempre terá a seguinte cara: nomedafuncao(argumento1, argumento2, ..., argumenton). É muito importante aprender a lidar e entender como operacionalizar funções, pois são a principal maneira de interagir com o R. Vamos ver abaixo algumas funções:
Essa função é bem simples, e basta você digitar sqrt(x), veja abaixo.
sqrt(9)
## [1] 3
sqrt(8+9/3)
## [1] 3.316625
Por definição, o R calcula o logarítimo natural (ln) quando usamos a função log(x). Para podermos especificar exatamente qual o logarítimo de interesse, podemos lançar mão dos atalhos log2(x) e log10(x). De maneira mais genérica, podemos utilizar log(x, base=n), onde n é o valor de base que nos interessar. Outro atalho interessante para quem trabalha com dados contendo zeros é o log1p(x), que calcula log(x+1).
log(10) #computa o log natural
## [1] 2.302585
log2(10) #log na base 2
## [1] 3.321928
log10(10) #log na base 10
## [1] 1
log(10, base = 10) #especifica valor e base
## [1] 1
log(0) #nao eh possivel, pois o valor tende a inifito, para isso usamos
## [1] -Inf
log1p(0) #nesse caso, o calculo eh o log(0+1), que é zero.
## [1] 0
#computar somente os módulos
abs(8-9)
## [1] 1
Uma coisa importante que precisamos saber é como nos virar com a ajuda no R. Sempre que tivermos dúvidas numa função, a primeira coisa que podemos fazer é digitar ?nomedafuncao, ou ainda help("nomedafuncao"). Nesses dois casos, no RStudio, abrirá uma documentação naquele painel Help que vimos acima. Essa ajuda é a mais básica, mas contém em geral os elementos abaixo (nem todos sempre estão presentes):
Para terminar com essas operações e funções, podemos combiná-las como bem nos servir. No exemplo abaixo, veja que combinei todas as operações que trabalhamos até agora.
log(abs(8-9))+sqrt((3*5)-(6/2))
## [1] 3.464102
Como já vimos, é possível ir digitando os valores no R script e os executando no console. Todavia, a situação fica bem mais interessante quando começamos a armazenar os valores em variáveis, podendo-as chamar posteriormente para nossos trabalhos. Você verá que esses objetos são nossa moeda básica de conversa com o R.
Vamos utilizar como exemplo a conta que fizemos antes, quebrando a conta que fizemos em várias etapas, armazenando os resultados. Para armazenar, damos um nome à nossa variável (o nome é de sua escolha, desde que não contenha espaços, caracteres especiais ou comece com números). Para ligar o nome ao valor desejado, utulizaremos o comando de atribuição, representado por <-, cujo atalho no RStudio é alt + _.
Por fim, o R substituirá qualquer informação anterior armazenada em um objeto sem pedir sua permissão. Portanto, é uma boa ideia não usar nomes já usados.
Vamos lá:
modulo <- abs(8-9)
logaritimo <- log(modulo)
multiplicacao <- 3*5
divisao <- 6/2
raizquadrada <- sqrt(multiplicacao - divisao)
contafinal <- logaritimo + raizquadrada
contafinal
## [1] 3.464102
Trabalharemos com diferentes tipos de dados, categorias, números, nomes, etc. É importante que saibamos como o R interpreta cada uma dessas coisas, mesmo que de maneira superficial, para que possamos nos virar bem e saibamos potenciais fontes de erro. Nessa seção, vamos construir manualmente vários tipos de dados a título de exercício. Você precisa construir esses dados à mão - de forma nenhuma - podemos chamá-los carregando dados (mais adiante), mas o exercício agora nos ajudará a entender melhor. Como os nomes aparecerão em inglês no programa, usarei os nomes deles da mesma forma aqui.
De maneira bem sucinta, vou listar os tipos/classes de dados que podemos ter no R, para que possamos conhecer:
stringsAsFactors = T ou com as.factor(vetor).Um vector (ou atomic vector) é simplesmente um conjuntos simples de dados (um vetor de dados). Eles podem ter de 1 a vários elementos, e isso determinará o length, ou comprimento desse vetor. Portanto, quando armazenamos os valores na seção anterior, criamos vetores de length = 1. Para criar vetores maiores, não é possível simplesmente sair digitando os valores, precisamos lançar mão do comando c, que concatena valores dentro de um mesmo vetor. Vamos ao exemplo:
x <- 1 #este eh um vetor com um unico elemento
adicionado mais elementos …
x <- 1, 2, 3, 4 #assim veremos que dara um erro
## Error: <text>:1:7: unexpected ','
## 1: x <- 1,
## ^
para fazer esse vetor, com os números sequenciais de 1 a 4, temos várias opcões
x <- c(1, 2, 3, 4) #utilizar o comando de concatenar
#ou
x <- 1:4 #nesse caso, os : funcionam como uma funcao unica, que cria uma sequencia de 1 a 4, de 1 em 1
#ainda seria possível usar a funcao seq
x <- seq(from=1, to=4, by=1) #funcao mais generica, que permite determinar onde comeca, termina e qual o passo da sequência.
Agora, meu vetor será composto de números não sequenciais e preciso necessariamente fazer com o comando c. Vamos fazer um vetor com as respostas da turma ao grau de experiência com o R, que preencheram na inscrição do curso.
experiencia <- c(3, 3, 2, 2, 3, 3, 1, 3, 3, 2, 1, 2, 3, 3, 1, 2, 1, 2, 3, 1, 2, 3, 4, 1)
Aqui temos então um vetor com o comprimento de 24 elementos, representando a resposta de cada estudante que fez a solicitação de vaga. O mais legal de termos esses valores armazenados em um vetor é que podemos fazer uma série de operações com ele agora. Vamos aos resumos mais básicos desses dados:
#media
mean(experiencia)
## [1] 2.25
#mediana
median(experiencia)
## [1] 2
#desvio padrao
sd(experiencia)
## [1] 0.8968544
#somatório
sum(experiencia)
## [1] 54
#produtorio
prod(experiencia)
## [1] 30233088
#valores máximo e mínimo
max(experiencia)
## [1] 4
min(experiencia)
## [1] 1
#
Todos os valores acima são um resumo de todos os 24 valores presentes no vetor. Você talvez tenha sentido falta da moda, mas esse valor não possui uma função específica no R. Aproveite a oportunidade pra pensar um pouquinho e tentar achar uma maneira de calcular a moda no R.
É possível fazer operações aritiméticas com os vetores. Essas operações, em geral são feitas element wise, sendo aplicadas a cada um dos elementos do vetor. Portanto, se eu pedisse, como vimos antes, o logarítimo do vetor, meu resultado seria o seguinte:
log(experiencia)
## [1] 1.0986123 1.0986123 0.6931472 0.6931472 1.0986123 1.0986123 0.0000000
## [8] 1.0986123 1.0986123 0.6931472 0.0000000 0.6931472 1.0986123 1.0986123
## [15] 0.0000000 0.6931472 0.0000000 0.6931472 1.0986123 0.0000000 0.6931472
## [22] 1.0986123 1.3862944 0.0000000
Ou seja, a função é aplicada a cada um dos elementos individualmente. Da mesma forma, suponhamos que eu queira saber quanto falta pra cada um chegar ao nível 4 proposoto, eu poderia subtrair de 4 cada um dos valores do vetor, ficaria assim:
4-experiencia
## [1] 1 1 2 2 1 1 3 1 1 2 3 2 1 1 3 2 3 2 1 3 2 1 0 3
mean(4-experiencia)
## [1] 1.75
Vemos aqui então, por essa conta bem simples, que em média cada pessoa poderia subir 1.75 pontos para que toda a turma terminasse o curso no mesmo nível.
Outra informação importante nessas operações com vetores é que, se tivermos vetores do mesmo tamanho, a operação irá proceder normalmente entre cada elemento na mesma posição. Assim,o primeiro elemento do vetor 1 será somado ao primeiro elemento do vetor 2, o segundo ao segundo … e assim sucessivamente. Caso os vetores tenham tamanhos distintos, o R irá gastar o vetor menor e recomeçá-lo quantas vezes for necessário para utilizar todo o vetor maior. Veja o exemplo abaixo, para compreender melhor o que eu expliquei aqui. Utilizarei o vetor x e o vetor exepriencia que já criamos:
length(experiencia) #para termos o tamanho do vetor
## [1] 24
length(x) #idem
## [1] 4
experiencia+x
## [1] 4 5 5 6 4 5 4 7 4 4 4 6 4 5 4 6 2 4 6 5 3 5 7 5
Vejam que os valores de x foram somados ao vetor experiencia, sempre retornando ao início de x quando ele acabava. Assim, tivemos, para garantir que fique bem claro!
| experiencia | x | resultado |
|---|---|---|
| 4 | 1 | 4 |
| 3 | 2 | 5 |
| 3 | 3 | 5 |
| 2 | 4 | 6 |
| 3 | 1 | 4 |
| 3 | 2 | 5 |
| … | … | … |
| 1 | 4 | 5 |
Por fim, é importante lembrar que caso o vetor maior não seja múltiplo do menor, ainda assim ele fará a operação element wise, deixando um aviso ao final.
Nosso vetor possui 24 elementos. Como poderíamos saber qual é o \(8^o\) elemento do nosso vetor? Podemos saber isso utilizando a indexação dos vetores. Lembram-se daquele [1] que apareceu lá na nossa primeira conta feita, que eu comentei que era a posição na linha? Esse colchete tem exatamente essa função, o número dentro dele fala a posição dos elementos. Sendo assim, fica fácil responder nossa dúvida. Para achar o \(8^o\) elemento de experiencia, basta fazer:
experiencia[8]
## [1] 3
e para acharmos mais de um elemento, digamos o \(8^o\) e o \(12^o\), basta fazer assim:
experiencia[c(8,12)]
## [1] 3 2
Ou seja, o elemnto de número 8 é o 3 e o elemento número 12 é o 2.
Agora que já sabemos o que é um vetor, podemos pedir ao R para avaliar os elementos dentro deles de acordo com condições que queiramos saber:
experiencia>2 #perguntei quais valores de experiencia eram maiores que 2
## [1] TRUE TRUE FALSE FALSE TRUE TRUE FALSE TRUE TRUE FALSE FALSE FALSE
## [13] TRUE TRUE FALSE FALSE FALSE FALSE TRUE FALSE FALSE TRUE TRUE FALSE
experiencia>=2 #perguntei quais valores de experiencia eram maiores ou iguais do que 2
## [1] TRUE TRUE TRUE TRUE TRUE TRUE FALSE TRUE TRUE TRUE FALSE TRUE
## [13] TRUE TRUE FALSE TRUE FALSE TRUE TRUE FALSE TRUE TRUE TRUE FALSE
experiencia==3 #a igualdade em R é denotada por dois sinais de igual seguidos
## [1] TRUE TRUE FALSE FALSE TRUE TRUE FALSE TRUE TRUE FALSE FALSE FALSE
## [13] TRUE TRUE FALSE FALSE FALSE FALSE TRUE FALSE FALSE TRUE FALSE FALSE
experiencia!=3 #e a desigualdadade como !=
## [1] FALSE FALSE TRUE TRUE FALSE FALSE TRUE FALSE FALSE TRUE TRUE TRUE
## [13] FALSE FALSE TRUE TRUE TRUE TRUE FALSE TRUE TRUE FALSE TRUE TRUE
Os data frames serão muito utilizados por nós, visto que eles são basicamente nossas planilhas no R. Um dataframe tem por característica possuir vetores de mesmo tamanho (podem ter classes diferentes) e ser bi-dimensional, possuindo linhas e colunas. As linhas contém cada observação feita e as colunas cada variável mensurada. Ainda a título de exemplo, vamos criar aqui mesmo no R um dataframe para trabalhar.
Vamos criar um dataframe de observações de apostas, onde o resultado das apostas (numérico), será confrontado com o fato de senhoras possuírem ou não carros (aqui, um estimador de riqueza). Vamos dar uma olhada geral na tabela primeiro, depois a construímos do zero.
| Senhora | Resultado | Riqueza |
|---|---|---|
| 1 | 6.0 | Com_carro |
| 2 | 1.0 | Sem_carro |
| 3 | 3.0 | Sem_carro |
| 4 | 5.5 | Com_carro |
| 5 | 5.0 | Com_carro |
| 6 | 2.5 | Sem_carro |
| 7 | 2.0 | Sem_carro |
| 8 | 2.0 | Sem_carro |
| 9 | 5.0 | Com_carro |
| 10 | 6.0 | Com_carro |
| 11 | 5.5 | Com_carro |
| 12 | 3.0 | Sem_carro |
| 13 | 2.0 | Sem_carro |
| 14 | 4.0 | Sem_carro |
| 15 | 1.0 | Sem_carro |
| 16 | 4.0 | Sem_carro |
| 17 | 1.0 | Sem_carro |
| 18 | 1.0 | Sem_carro |
| 19 | 4.0 | Sem_carro |
| 20 | 5.0 | Com_carro |
Para fazermos esse dataframe, vamos precisar de alguns conhecimentos, que aprenderemos na medida que vamos fazendo.
Primeiro, vamos criar a coluna 1, com o número de cada senhora
Senhora <- 1:20
Depois, por ser mais fácil, vamos criar a coluna Resultado:
Resultado <- c(6,1,3,5.5,5,2.5,2,2,5,6,5.5,3,2,4,1,4,1,1,4,5)
E agora vamos criar a coluna Riqueza, que consiste em dizer se as senhoras estão com ou sem carro. Para cada uma dessas categorias, daremos o nome de “Com_carro” e “Sem_carro”. Poderíamos digitar os valores copiando a tabela diretamente, mas vamos aproveita para aprender duas coisas importantes:
rep(x, nvezes)
Portanto, na nossa tabela temos “Sem_carro” duas vezes, seguido de “Com_carro” mais duas, depois “Sem_carro” três vezes, e assim sucessivamente. Vamos fazer o vetor:
Agora, quase pronto, só precisamos juntar isso tudo num dataframe, utilizando o comando data.frame(a, b, c). Veja que todos possuem 20 elementos! Isso é imprescindível, pois um dataframe sempre tem colunas de mesmo tamanho. Como queremos que o R reconheça Com_carro e Sem_carro como categorias (factors), vamos usar o comando que mencionamos antes, sendo assim, nossa função fica ao final:
meusdados <- data.frame(Senhora, Resultado, Riqueza, stringsAsFactors = T)
meusdados
Agora, mudamos um pouco de patamar, nosso vector agora é um dataframe, ou seja, um conjunto de vectors do mesmo tamanho, ainda que com classes distintas. A primeira característica de um dataframe é ter duas dimensões, linhas e colunas. A primeira diferença aqui é em relação à indexação, que agora passa a conter 2 elementos, ficando assim: dataframe[linhas, colunas]. Vamos tentar achar aqui em meusdados, o dataframe que criamos, o elemento que está na linha 9 da coluna 2. Faríamos assim:
meusdados[9, 2]
## [1] 5
Nessa indexação, posso também pedir todas as linhas de uma determinada coluna. Por exemplo, quero todas as linhas da coluna 2. Para isso, basta deixar em branco o número de linhas e informar a coluna 2.
meusdados[ , 2]
## [1] 6.0 1.0 3.0 5.5 5.0 2.5 2.0 2.0 5.0 6.0 5.5 3.0 2.0 4.0 1.0 4.0 1.0 1.0 4.0
## [20] 5.0
Por fim, caso eu queira acessar uma das colunas do dataframe, posso chamá-la pelo nome. A maneira mais direta é digitar o nome do dataframe, seguido de $ e o nome da coluna - meusdados$Senhora, e posso fazer isso para cada uma das colunas para vê-las individualmente.
meusdados$Senhora
## [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
meusdados$Resultado
## [1] 6.0 1.0 3.0 5.5 5.0 2.5 2.0 2.0 5.0 6.0 5.5 3.0 2.0 4.0 1.0 4.0 1.0 1.0 4.0
## [20] 5.0
meusdados$Riqueza
## [1] Com_carro Sem_carro Sem_carro Com_carro Com_carro Sem_carro Sem_carro
## [8] Sem_carro Com_carro Com_carro Com_carro Sem_carro Sem_carro Sem_carro
## [15] Sem_carro Sem_carro Sem_carro Sem_carro Sem_carro Com_carro
## Levels: Com_carro Sem_carro
Uma outra função importantíssima quando temos um dataframe é ver o resumo geral dos dados nesse conjunto. São possíveis:
summary(meusdados) - faz um resumo geral dos dados em cada coluna, dependendo da classe de dados em cada uma, o resultado é um pouco diferente, explore abaixo:summary(meusdados)
## Senhora Resultado Riqueza
## Min. : 1.00 Min. :1.000 Com_carro: 7
## 1st Qu.: 5.75 1st Qu.:2.000 Sem_carro:13
## Median :10.50 Median :3.500
## Mean :10.50 Mean :3.425
## 3rd Qu.:15.25 3rd Qu.:5.000
## Max. :20.00 Max. :6.000
str(meusdados) - mostra a estrutura dos dados, nesse caso o foco é mais mostrar quais as classes e números de elementos em cada coluna. Explore abaixo:str(meusdados)
## 'data.frame': 20 obs. of 3 variables:
## $ Senhora : int 1 2 3 4 5 6 7 8 9 10 ...
## $ Resultado: num 6 1 3 5.5 5 2.5 2 2 5 6 ...
## $ Riqueza : Factor w/ 2 levels "Com_carro","Sem_carro": 1 2 2 1 1 2 2 2 1 1 ...
plot(dados) - aqui o objetivo é mesmo explorar visualmente os dados. São plotados “todos contra todos”. Explore o plot abaixo:plot(meusdados)
Poderíamos seguir aqui por muito tempo com essa introdução, mas o objetivo dela é mesmo ganhar intimidade com o programa. Seguirei apresentando novidades agora durante o andamento das aulas, bons estudos!