Bastão de Asclépio & Distribuição Normal

Bastão de Asclépio & Distribuição Normal

invisible(Sys.setlocale("LC_CTYPE", "pt_BR.UTF-8"))
invisible(Sys.setlocale("LC_ALL", "pt_BR.UTF-8"))
options(warn=-1)
suppressMessages(library(knitr, warn.conflicts=FALSE))
suppressMessages(library(kableExtra, warn.conflicts=FALSE))
suppressMessages(library(readxl, warn.conflicts=FALSE))
suppressMessages(library(haven, warn.conflicts=FALSE))
suppressMessages(library(readODS, warn.conflicts=FALSE))
suppressMessages(library(openxlsx, warn.conflicts=FALSE))
suppressMessages(library(tidyr, warn.conflicts=FALSE))
suppressMessages(library(eirasdata, warn.conflicts=FALSE))
suppressMessages(library(eiras, warn.conflicts=FALSE))


O pacote eiras está disponível em https://doi.org/10.7910/DVN/TBBAVU. Para instalá-lo, então, você precisará baixar o arquivo .tar.gz e, então, usar a linha de comando

install.packages(“ pathname eiras_X.X.X.tar.gz”)

onde pathname é o caminho até a pasta onde você baixou o arquivo e eiras_X.X.X.tar.gz deve ser substituído pela versão mais recente que estiver disponível. Por exemplo, no terminal Linux, tendo baixado a versão 0.1.1. para uma pasta chamada tmp localizada na área de trabalho de meu usuário, o comando é

install.packages("/home/silveira/tmp/eiras_0.1.1.tar.gz")

ou usar o auxílio do RStudio (Tools -> Install packages…), mudando do CRAN para um Package Archive File (.tar.gz) e apontando o arquivo para instalar.


Material

  • HTML de Rmarkdown em RPubs

Introdução

O RStudio é um ambiente que facilita o uso do R. Além do terminal R (chamado também de console, no qual pode dar comandos diretos) agrupa arquivos, disponibiliza janelas auxiliares e dá acesso à documentação do R.

RStudio roda em Linux, Macintosh e Windows sob R. Para que tudo funcione, o primeiro passo é instalá-los (primeiro R e, depois, o RStudio).

Para experimentar seu uso, vamos:

  • criar um projeto no RStudio,
  • ler um arquivo texto com dados e
  • experimentarmos alguns comandos de estatística descritiva.

Preparação do ambiente

A linguagem de programação R é de uso livre e código aberto.

Roda em Linux, Macintosh e Windows, mas o procedimento muda de acordo com seu sistema operacional.

O RStudio é um ambiente que roda sob R facilmente instalado depois que o R estiver em ordem.

Instalação do R

O projeto R está em https://www.r-project.org/

Neste site encontrará todo o desenvolvimento e documentação, mas a instalação pode não ser óbvia. Encontre o link para Download R, que levava a uma página com espelhos (mirrors) de onde se pode pegar o R. Escolhendo um deles, encontrará uma página similar a esta:

Siga as instruções para a instalação, diferentes para cada sistema operacional.

Instalação do RStudio

Uma vez instalada a linguagem R você pode instalar o RStudio. O procedimento, novamente, depende do sistema operacional. O RStudio funciona nos três: Linux, Macintosh e Windows.

No site oficial do RStudio, https://www.rstudio.com/products/rstudio/download/, encontrará o que precisa. Pegue a versão gratuita do RStudio Desktop.

Áreas da tela no RStudio

Ao entrar no RStudio, encontrará a uma tela como esta:

Reconheça os seguintes elementos:

  • uma área com as abas Console e Terminal. Usaremos a Console sempre (o terminal serve para usos mais avançados e desnecessários para nosso contexto). A console permite que usemos comandos diretos em R (veremos adiante).
  • uma área com as abas Environment (ambiente), History (histórico) e Connections (conexões). Usaremos principalmente o ambiente, onde as variáveis ativas aparecem (as veremos em ação adiante).
  • uma área com as abas Files (arquivos), Plots (gráficos), Packages (pacotes), Help (ajuda) e Viewer (visualizador). Os dois primeiros e a área de ajuda são os mais importantes para começar.

Começando a usar a Console

É através da Console que usamos comandos para o R. Vamos experimentar algumas coisas simples, para começar.

O símbolo > é o prompt do R indicando que está pronto para receber uma instrução qualquer. Por exemplo, podemos fazer uma conta digitando na Console (digite após o símbolo > e pressione [enter] ao final da linha):

4+5

obtendo

[1] 9

A soma de quatro e cinco resulta em 9.

Podemos guardar os valores em variáveis (pressione [enter] ao final de cada linha):

a <- 4
b <- 5
a + b
[1] 9

Dando nomes, a e b são variáveis que receberam (com o operador de atribuição, <-) os valores 4 e 5, respectivamente. Sua soma, a + b (+ é o operador da adição), é 9. Podemos guardar este resultado em uma outra variável:

soma <- a + b

e podemos ecoar o conteúdo da variável soma, simplesmente escrevendo seu nome:

soma
[1] 9


Observe que nomes de variáveis podem ter várias letras e números (desde que comece com letra). Não use letras acentuadas e tenha cuidado com a grafia porque o R distingue maiúsculas de minúsculas: soma, Soma e SOMA são variáveis diferentes, cada uma criada com conteúdo independente.

Nomes como soma_1, Soma_b, x ou A são, também, nomes válidos para variáveis. Crie variáveis com nomes que facilitem, para você, lembrar o tipo de conteúdo depositado nelas.


O resultado armazenado na variável soma pode ser usado:

raiz <- sqrt(soma)
raiz
[1] 3

Neste exemplo, pela primeira vez, usamos uma função, sqrt, que extrai a raiz quadrada (square root, em inglês) de soma e a armazena em outra variável, raiz. O R distingue variáveis de funções porque as funções recebem parâmetros (neste caso, um valor numérico contido em soma) entre parênteses. A função sqrt faz parte do conjunto de funções básicas do R.


Nada impede a criação de uma variável chamada sqrt, mas não é recomendável. O R não confundirá, mas você sim. Uma possível sugestão, se você não pretende distribuir seu código internacionalmente, é dar nomes em português para as variáveis (e.g., raiz_quadrada); outra opção é usar algum tipo de prefixo (e.g., v_sqrt ou v.sqrt).


Usar a console desta forma só é útil para tarefas pequenas ou testes para acertar a sintaxe. Adiante veremos como colocar vários comandos em um código e, mais sofisticadamente, em uma função, usando decisões ou loops, para facilitar seu trabalho. Por exemplo, apenas como um “aperitivo”, experimente um loop:

for (n in 0:10) 
{
  cat(n, "x 3 =", n*3, "\n")
}
0 x 3 = 0 
1 x 3 = 3 
2 x 3 = 6 
3 x 3 = 9 
4 x 3 = 12 
5 x 3 = 15 
6 x 3 = 18 
7 x 3 = 21 
8 x 3 = 24 
9 x 3 = 27 
10 x 3 = 30 

É um loop (usando a palavra reservada for) no qual a variável n vai de 0 a 10, usa o operador de multiplicação, *, e exibe a tabuada do 3 com um único comando.

Em muitas situações podemos evitar loops deste tipo, lançando mão de intervalos com o operador :, ou fazendo operações sobre vetores ou __dataframe_s_ inteiros.

Por exemplo, a tabuada acima pode ser obtida com:

paste(0:10,"x 3 =",(0:10)*3)
 [1] "0 x 3 = 0"   "1 x 3 = 3"   "2 x 3 = 6"   "3 x 3 = 9"   "4 x 3 = 12" 
 [6] "5 x 3 = 15"  "6 x 3 = 18"  "7 x 3 = 21"  "8 x 3 = 24"  "9 x 3 = 27" 
[11] "10 x 3 = 30"

Entenda o código. A instrução 0:10 gera

0:10
 [1]  0  1  2  3  4  5  6  7  8  9 10

e a função paste concatena o que está dentro dela, sendo chamada 11 vezes por causa 0:10, variando os números e mantendo a parte fixa entre aspas, “x 3 =”.

Variáveis podem conter listas de valores. A mais simples são vetores, criadas com a função de contatenação, c:

vetor <- c(0,1,2,3,4,5,6,7,8,9,10)
vetor
 [1]  0  1  2  3  4  5  6  7  8  9 10

ou, o que é o mesmo,

vetor <- 0:10
vetor
 [1]  0  1  2  3  4  5  6  7  8  9 10

Vetores permitem operações “em lote”, por exemplo, mostrando os resultados da tabuada do 3 sem precisar do loop:

vetor * 3
 [1]  0  3  6  9 12 15 18 21 24 27 30

Em R como vetor tem 11 valores, a multiplicação por 3 será repetida para cada um deles, e 11 resultados (de 3x0 a 3x10) serão computados. Porém, perdemos o formato da tabuada. Funções podem ser aninhadas:

vetor <- 0:10
tabuada <- paste(vetor,"x",3,"=",vetor*3)
m <- matrix(data=tabuada, ncol=1, nrow=11)
prmatrix(m, collab="", rowlab=rep("",11), quote=FALSE)
            
 0 x 3 = 0  
 1 x 3 = 3  
 2 x 3 = 6  
 3 x 3 = 9  
 4 x 3 = 12 
 5 x 3 = 15 
 6 x 3 = 18 
 7 x 3 = 21 
 8 x 3 = 24 
 9 x 3 = 27 
 10 x 3 = 30

A função prmatrix imprime uma matriz. Matrizes podem ser criadas quando queremos uma coleção de valores com duas dimensões (o vetor é unidimensional), cujos elementos individuais são todos do mesmo tipo (neste exemplo, strings alfanuméricas) endereçados por [linha,coluna]. Neste exemplo, linha vai de 1 a 11, mas só existe uma coluna. Para ver por exemplo, o conteúdo da terceira linha, podemos usar

cat("A terceira linha contém",m[3,1],"\n")
A terceira linha contém 2 x 3 = 6 

As funções cat, print e prmatrix que usamos até aqui têm comportamentos similares em várias situações, mas diferentes em outras. A mais simples é cat. Repare que existe um “\n”, que tem pouco efeito aqui mas é importante em Rscripts. O efeito de “\n” é de carriage return, similar ao que ocorre quando pressiona [enter] em um processador de textos para continuar escrevendo na próxima linha (aparecerão exemplos adiante).

Note, também, que um espaço foi adicionado após a palavra “contém”.

cat("A terceira linha contém",m[3,1],"\n")
A terceira linha contém 2 x 3 = 6 

Isto nem sempre é desejado, quando colocamos os espaços do nosso jeito e não queremos a interferência da função, que inclui um espaço em branco como separador por default. Podemos mudar o separador com o parâmetro sep e escrever:

cat("A terceira linha contém ",m[3,1],"\n",sep="")
A terceira linha contém 2 x 3 = 6

(o separador é vazio e o espaço após “contém” foi explicitamente colocado dentro das aspas).

O equivalente com a função print precisa da ajuda de paste mas não precisa de “\n” (pois print já termina mudando de linha):

print(paste("A terceira linha contém ",m[3,1],sep=""))
[1] "A terceira linha contém 2 x 3 = 6"

A função print “suja” o início da linha com [1] e não é a mais indicada para uma saída destinada a quem não é usuário do R e não sabe o que isto significa. No entanto, print consegue exibir estruturas mais complexas, como por exemplo a matriz m que definimos acima. Compare:

cat(m,"\n")
0 x 3 = 0 1 x 3 = 3 2 x 3 = 6 3 x 3 = 9 4 x 3 = 12 5 x 3 = 15 6 x 3 = 18 7 x 3 = 21 8 x 3 = 24 9 x 3 = 27 10 x 3 = 30 

com

print(m)
      [,1]         
 [1,] "0 x 3 = 0"  
 [2,] "1 x 3 = 3"  
 [3,] "2 x 3 = 6"  
 [4,] "3 x 3 = 9"  
 [5,] "4 x 3 = 12" 
 [6,] "5 x 3 = 15" 
 [7,] "6 x 3 = 18" 
 [8,] "7 x 3 = 21" 
 [9,] "8 x 3 = 24" 
[10,] "9 x 3 = 27" 
[11,] "10 x 3 = 30"

Por fim, prmatrix é uma especialização de print, com parâmetros que podem ocultar os endereçamentos das linhas e colunas, como fizemos com

prmatrix(m, collab="", rowlab=rep("",11), quote=FALSE)
            
 0 x 3 = 0  
 1 x 3 = 3  
 2 x 3 = 6  
 3 x 3 = 9  
 4 x 3 = 12 
 5 x 3 = 15 
 6 x 3 = 18 
 7 x 3 = 21 
 8 x 3 = 24 
 9 x 3 = 27 
 10 x 3 = 30
substituindo os rótulos (labels, em inglês) das colunas (collab) e linhas (rowlab) por um vazio, além de não exibir aspas (quote=FALSE). Experimente alterar estes parâmetros para ver o que acontece.


Criando um projeto

Antes de fazer qualquer coisa recomendamos SEMPRE iniciar um Projeto. Repare no canto superior-direito da tela que existe um menu mostrando que não há um projeto aberto (veja, por exemplo, a tela do RStudio acima).


O principal motivo para criar um projeto é a organização. O projeto reserva uma pasta, dentro da qual ficarão os Rscripts que desenvolverá, os arquivos com dados ou resultados, ou o que mais você fizer pertinentemente ao projeto.


Para criar um projeto novo no RStudio, no canto superior-direito clique em New project e aponte-o para uma pasta de sua preferência (ou crie uma pasta nova). Terá, também, que dar um nome ao projeto. Neste exemplo vou chamá-lo de Anticoncepcional.

Você pode apontar uma pasta existente ou criar uma nova através do próprio RStudio. No caso de pasta nova, chegará em uma tela assim:

O nome do diretório (sinônimo de pasta) será a pasta nova e, também, o nome do projeto. A segunda parte é sob qual pasta seu projeto ficará subordinado.


Em meu caso uso o RStudio em Linux, e este sistema operacional endereça as pastas com sua própria sintaxe, separando os níveis por slash (‘/’). No Windows aparecerão caminhos como “C:\Meus Documentos\…”, separando os níveis por backslash (‘\’)).


O RStudio, na pasta que você apontar criará o arquivo Anticoncepcional.Rproj e mostrará, na janela inferior-direita, o caminho até a pasta apontada e os arquivos que ela contém na aba Files.

Neste exemplo, como criei uma pasta nova, só aparece nela (por enquanto) o que o RStudio criou para mim.

Criando um código

Vamos aproveitar o que testamos na Console para ilustrar como guardá-lo junto ao projeto que acabamos de criar.

Use o menu e selecione

File -> New file -> Rscript

(que, no meu sistema, pode ser substituído por um “atalho” pelo teclado, pressionando as teclas Ctrl+Shift+N, simultaneamente).

Uma nova aba, chamada Untitled1 deve abrir-se:

Coloque, dentro desta nova área, a tabuada do 3 que ensaiamos acima, digitando:

# Este é meu primeiro Rscript
cat("Apresentando a tabuada do 3\n")
for (n in 0:10) 
{
  cat(n,"x",3,"=",n*3,"\n")
}


Entenda a sintaxe do R:

  • O símbolo de hashtag (#) indica uma linha de comentário (algo para você lembrar o que faz determinado trecho de um código, que não será executada).
  • cat é uma função R que ecoa na Console o texto que for passado como parâmetro; neste exemplo, o primeiro cat apenas escreve “Apresentando a tabuada do 3” e avança uma linha (por causa do caracter especial \n).
  • o for já foi apresentado, e faz a variável n assumir sequencialmente os valores 0, 1, 2, …, 10.
  • tudo que está entre as chaves, {…}, é executado repetidamente a cada ciclo do for.
  • este segundo cat tem parte do texto fixo com parte variável, ecoando o resultado de cada multiplicação, uma em cada linha.


Salve seu código na mesma pasta em que está o projeto, usando

File -> Save

com o nome tabuada3.R. Agora a aba tem o nome do arquivo que acabou de ser criado.

Execute seu código clicando o botão [Source] e observe o resultado na Console

Apresentando a tabuada do 3
0 x 3 = 0 
1 x 3 = 3 
2 x 3 = 6 
3 x 3 = 9 
4 x 3 = 12 
5 x 3 = 15 
6 x 3 = 18 
7 x 3 = 21 
8 x 3 = 24 
9 x 3 = 27 
10 x 3 = 30 

Um uso um pouco mais avançado é a criação de funções. Você não precisa se contentar com as milhares de funções já disponíveis em R. A linguagem é expansível, e você pode criar mais funções. É assim que R com a cooperação de muitas pessoas, cresce continuamente.

Por exemplo, podemos criar uma função chamada tabuada assim:

tabuada <- function (multiplicando=1)
{
  cat("Apresentando a tabuada do ",multiplicando,":\n", sep="")
  for (n in 0:10) 
  {
    cat(n,"x",multiplicando,"=",n*multiplicando,"\n")
  }
}

Salve este código com o nome de tabuada.R. Rode este código com [Source] uma única vez para que a função tabuada fique disponível na memória. Esta função recebe um parâmetro, o multiplicando. Caso nenhum parâmetro seja passado, a declaração da função tem o valor 1 como default (multiplicando=1). Passando qualquer outro valor aparecerá a tabuada solicitada. Por exemplo, experimente com a Console várias possibilidades:

tabuada()
Apresentando a tabuada do 1:
0 x 1 = 0 
1 x 1 = 1 
2 x 1 = 2 
3 x 1 = 3 
4 x 1 = 4 
5 x 1 = 5 
6 x 1 = 6 
7 x 1 = 7 
8 x 1 = 8 
9 x 1 = 9 
10 x 1 = 10 
tabuada(multiplicando=5)
Apresentando a tabuada do 5:
0 x 5 = 0 
1 x 5 = 5 
2 x 5 = 10 
3 x 5 = 15 
4 x 5 = 20 
5 x 5 = 25 
6 x 5 = 30 
7 x 5 = 35 
8 x 5 = 40 
9 x 5 = 45 
10 x 5 = 50 
tabuada(8)
Apresentando a tabuada do 8:
0 x 8 = 0 
1 x 8 = 8 
2 x 8 = 16 
3 x 8 = 24 
4 x 8 = 32 
5 x 8 = 40 
6 x 8 = 48 
7 x 8 = 56 
8 x 8 = 64 
9 x 8 = 72 
10 x 8 = 80 
tabuada(-2)
Apresentando a tabuada do -2:
0 x -2 = 0 
1 x -2 = -2 
2 x -2 = -4 
3 x -2 = -6 
4 x -2 = -8 
5 x -2 = -10 
6 x -2 = -12 
7 x -2 = -14 
8 x -2 = -16 
9 x -2 = -18 
10 x -2 = -20 

Esta função recebe somente um parâmetro e não retorna valores. Podemos melhorá-la, guardando a tabuada em uma matriz e retornando-a para que seus valores possam ser usados separadamente e/ou manipulados por outras partes de um código. Por exemplo:

tabuada <- function (multiplicando=1, echo=TRUE)
{
  if (echo)
  {
    cat("Tabuada do ",multiplicando,"\n",sep="")
  }  
  matriz <- matrix(data=NA, ncol=4, nrow=11)
  colnames(matriz) <- c("multiplicando", "multiplicado", "produto", "texto")
  for (m in seq(from=0,to=10,by=1))
  {
    produto <- m*multiplicando
    matriz[m+1,1] <- m
    matriz[m+1,2] <- multiplicando
    matriz[m+1,3] <- produto
    matriz[m+1,4] <- paste(m,"x",multiplicando,"=",produto,sep="")
    if (echo)
    {
      cat(matriz[m+1,4],"\n")
    }
  }
  return(matriz)
}

Esta nova versão recebe dois parâmetros. O segundo, echo=TRUE, por default ecoa a tabuada enquanto a calcula. Caso passe echo=FALSE, a função trabalhará “em silêncio”. No entanto, retornará uma matriz que tem quatro colunas, respectivamente contendo o número a ser multiplicado (variando de 0 a 10), o multiplicando, o produto resultante da multiplicação e uma string alfanumérica que pode ser usada para ecoar o resultado.


Esta função está implementada com melhorias sob eiras::multiplication.table. O pacote eiras está disponível no Harvard Dataverse em
https://doi.org/10.7910/DVN/TBBAVU.


Uma vez construída, esta função pode ser usada em outros Rscripts. Por exemplo, crie e salve o seguinte com o nome de TesteTabuada.R:

source("tabuada.R")

cat("Chamando as tabuadas\n")
for (t in 0:10)
{
  m <- tabuada(t, echo=FALSE)
  cat("-Tabuada do ",t,":\n",sep="")
  cat("\t",m[1:nrow(m),4],"\n")
}

A primeira linha coloca a função tabuada na memória (tal como está declarada dentro do arquivo tabuada.R). O nome da função e do arquivo não precisam ser iguais e um arquivo pode conter a declaração de mais que uma função. O restante do código chama tabuada em silêncio, trazendo seus resultados para a matriz m e, depois mostra apenas as strings armazenadas na quarta coluna com as.character(m[r,4]). Execute-a com [Source] e veja seu resultado na Console:

Chamando as tabuadas
-Tabuada do 0:
     0x0=0 1x0=0 2x0=0 3x0=0 4x0=0 5x0=0 6x0=0 7x0=0 8x0=0 9x0=0 10x0=0 
-Tabuada do 1:
     0x1=0 1x1=1 2x1=2 3x1=3 4x1=4 5x1=5 6x1=6 7x1=7 8x1=8 9x1=9 10x1=10 
-Tabuada do 2:
     0x2=0 1x2=2 2x2=4 3x2=6 4x2=8 5x2=10 6x2=12 7x2=14 8x2=16 9x2=18 10x2=20 
-Tabuada do 3:
     0x3=0 1x3=3 2x3=6 3x3=9 4x3=12 5x3=15 6x3=18 7x3=21 8x3=24 9x3=27 10x3=30 
-Tabuada do 4:
     0x4=0 1x4=4 2x4=8 3x4=12 4x4=16 5x4=20 6x4=24 7x4=28 8x4=32 9x4=36 10x4=40 
-Tabuada do 5:
     0x5=0 1x5=5 2x5=10 3x5=15 4x5=20 5x5=25 6x5=30 7x5=35 8x5=40 9x5=45 10x5=50 
-Tabuada do 6:
     0x6=0 1x6=6 2x6=12 3x6=18 4x6=24 5x6=30 6x6=36 7x6=42 8x6=48 9x6=54 10x6=60 
-Tabuada do 7:
     0x7=0 1x7=7 2x7=14 3x7=21 4x7=28 5x7=35 6x7=42 7x7=49 8x7=56 9x7=63 10x7=70 
-Tabuada do 8:
     0x8=0 1x8=8 2x8=16 3x8=24 4x8=32 5x8=40 6x8=48 7x8=56 8x8=64 9x8=72 10x8=80 
-Tabuada do 9:
     0x9=0 1x9=9 2x9=18 3x9=27 4x9=36 5x9=45 6x9=54 7x9=63 8x9=72 9x9=81 10x9=90 
-Tabuada do 10:
     0x10=0 1x10=10 2x10=20 3x10=30 4x10=40 5x10=50 6x10=60 7x10=70 8x10=80 9x10=90 10x10=100 

Quando a execução terminar a última tabuada estará na memória. Experimente:

print(m)
      multiplicando multiplicado produto texto      
 [1,] "0"           "10"         "0"     "0x10=0"   
 [2,] "1"           "10"         "10"    "1x10=10"  
 [3,] "2"           "10"         "20"    "2x10=20"  
 [4,] "3"           "10"         "30"    "3x10=30"  
 [5,] "4"           "10"         "40"    "4x10=40"  
 [6,] "5"           "10"         "50"    "5x10=50"  
 [7,] "6"           "10"         "60"    "6x10=60"  
 [8,] "7"           "10"         "70"    "7x10=70"  
 [9,] "8"           "10"         "80"    "8x10=80"  
[10,] "9"           "10"         "90"    "9x10=90"  
[11,] "10"          "10"         "100"   "10x10=100"

Este objeto, m, pode ter seus elementos acessados. A quinta linha, por exemplo,

print(m[5,])
multiplicando  multiplicado       produto         texto 
          "4"          "10"          "40"     "4x10=40" 

que pede a linha 5 e todas as colunas. Veremos melhor estes endereçamentos de [linha,coluna] nos dataframes, adiante.


Como TesteTabuada.R não é uma função, seus valores estão acessíveis depois que foi executado. As variáveis internas de uma função, no entanto, não estão. Tente acessar por exemplo, a variável matriz construída dentro de tabuada.R e verá que não existe. As funções, uma vez desenvolvidas, funcionam como “caixas-pretas”, e seus conteúdos ficam protegidos, de forma que não haverá conflito se variáveis externas tiverem o mesmo nome daquelas usadas dentro de suas funções. O que retornamos, neste exemplo, foi uma cópia da matriz para a variável m que é, portanto, também uma matriz e podemos acessá-la.


Lendo arquivos de dados

Existem formas de ler vários tipos de arquivo com R. As duas formas mais comuns são um arquivo texto que utilize algum tipo de delimitador (vírgula, ponto e vírgula ou caracteres de tabulação são os mais comuns), ou planilhas (o formato Excel, xls ou xlsx são os mais difundidos). No R como veremos adiante, o formato RDS é muito conveniente.

Arquivos no formato texto são simples e completamente portáveis entre diferentes sistemas operacionais. Há problemas, porém, com a comunicação com pesquisadores menos habituados a eles: atrapalham-se com os delimitadores, criam arquivos usando vírgulas como separador decimal (misturando-os com vírgulas usadas como delimitadores e, assim, bagunçando os dados de colunas diferentes), digitam números ora com pontos decimais, ora com vírgulas (bagunçando os dados numéricos ao transformar 1300 em 1.3 ou levar o sistema operacional a interpretar 1,3 como se fosse um texto) ou esquecem de especificar os delimitadores.

Arquivos em formato texto

Para este exemplo lidaremos com um arquivo MetodoAnticoncepcional.txt, que deve ser baixado e colocado na pasta do projeto. Ele aparecerá na lista de arquivos, junto aos arquivos Anticoncepcional.Rproj e tabuada3.R mencionados acima. Este é um exemplo hipotético, usando o seguinte enredo:


Um agente comunitário do programa de saúde da família deseja escrever um pequeno texto alertando os jovens de sua comunidade sobre o problema da gravidez indesejada. Com este propósito, ele decide investigar quais os métodos que os jovens estão usando.

Após pesquisa realizada com 60 jovens (14 – 19 anos), escolhidos aleatoriamente, obteve as respostas contidas em um arquivo texto.


Este é um arquivo texto tem 61 linhas. A primeira linha tem os nomes das colunas (que se tornarão os nomes das variáveis) e, em seguida, os dados de cada indivíduo (um indivíduo em cada linha).

Você pode ter uma ideia do arquivo com a ajuda do RStudio: basta clicar sobre ele na área de Files, e o arquivo se abrirá em uma nova janela à esquerda. Agora o RStudio mostra quatro áreas:

A Console foi deslocada para baixo e o arquivo MetodoAnticoncepcional.txt está aberto em uma nova aba.


Este arquivo ainda não foi convertido a um formato com o qual R possa lidar tanto que as colunas parecem desalinhadas por causa de seus conteúdos com diferentes larguras. As colunas estão separadas por caracteres de tabulação (tabs, que na tela têm a aparência de um espaço em branco, dando a impressão de que as colunas estão desalinhadas, um dos motivos para a confusão que estes arquivos causam para usuários “não iniciados”).

Repare, também, que não foram utilizadas letras acentuadas nos nomes das variáveis (Metodo em vez de Método). Caso o faça, poderá ter que lidar com alguns problemas adicionais, especialmente quando seu sistema operacional não for capaz de resolver sozinho, como acontece com o Windows (com o passar dos anos os problemas diminuiram, mas é melhor não arriscar: sugere-se evitar acentos em nomes de variáveis e em nomes de arquivos).

Sugerimos que deixe a acentuação somente para o que exibirá para o usuário final, se estiver fazendo um programa em português. As seguintes duas linhas podem ser adicionadas no início de todos os seus scripts; não atrapalham sistemas operacionais como Linux ou Mac, mas fazem com que a acentuação possa ser usada em Windows:

invisible(Sys.setlocale(“LC_CTYPE”, “pt_BR.UTF-8”))

invisible(Sys.setlocale(“LC_ALL”,“pt_BR.UTF-8”))


Variáveis, em R podem ter estruturas mais elaboradas do que as que contém apenas um valor um vetor ou uma matriz com valores em linhas e colunas, mas todos de mesma natureza. Criaremos uma variável que chamaremos de metodos, que conterá toda a informação que está neste arquivo .txt com o seguinte comando no console (janela à esquerda):

metodos <- read.table("MetodoAnticoncepcional.txt", 
                      header=TRUE,  dec=".", sep="\t")

Repare as especificações (parâmetros) sobre o arquivo que foram utilizadas com a função read.table:

  • header=TRUE informa que a primeira linha deve ser usada como nome das variáveis;
  • dec=“.” informa que ponto, se existir é o separador decimal usado;
  • sep=“\t” informa o uso do tab como delimitador.

Outro formato comum de arquivo texto é o que recebe a extensão .csv, no qual as colunas são separadas por vírgula (comma) ou ponto e vírgula (quando a vírgula já está usada para separar decimais em língua portuguesa). O processo de importação é o mesmo, exceto que precisará ajustar os parâmetros dec e sep adequadamente.

Na janela Environment (superior-direita) aparece a variável metodos, mostrando que a importação aconteceu. Clique no nome da variável e na seta que aparece ao lado esquerdo do nome da variável para ver algumas informações sobre seus detalhes, e sobre o nome da variável para que o RStudio mostre-lhe seu conteúdo:

Como pode observar o RStudio lhe informa que metodos contém três variáveis internas:

  • ID, do tipo int (número inteiro, quantitativa)
  • Idade, do tipo int (número inteiro, quantitativa)
  • Metodo, fator com 4 níveis

A identificação do tipo de variável é automática, de acordo com o conteúdo encontrado. Não havia números fracionários, então dec=“.” não era necessário (o símbolo usado como separador decimal - quem importa arquivo texto precisa saber se os números foram escritos com a notação inglesa, usando pontos como em nosso exemplo, ou portuguesa, usando vírgulas). ID, identificação do indivíduo, foi identificada como numérica, embora não o seja, mas não atrapalha muito deixar assim por enquanto. Idade, ao contrário, interessa como variável quantitativa, foi identificada como tal, e podemos fazer cálculos com ela. A coluna Metodo foi reconhecida, corretamente, como fator i.e., pode ser usada para separar grupos. Como é variável categórica (veremos, adiante, que são 4 categorias), podemos fazer contagens.

Além de conhecer os tipos de variável de cada coluna, precisamos saber qual é o tipo de metodos. Use (na Console) o comando:

is.table(metodos)
[1] FALSE

O que é uma surpresa! Apesar do nome e do comando de importação, metodos NÃO É do tipo table. Experimente:

is.data.frame(metodos)
[1] TRUE

metodos é um dataframe. Confuso, mas muito conveniente. A função read.table, lê um arquivo que encaramos como uma “tabela” e o retorna como um dataframe, o qual guardamos em metodos; é um formato muito flexível, como veremos adiante.


Uma das coisas confusas em R especialmente para quem conhece outras linguagens de programação, é a quantidade de tipos diferentes de variáveis. Há uma série de comandos em R para que se verifique qual tipo foi assumido (veremos isto adiante).


Arquivos em formato Excel

Este é um formato muito comum, e vai encontrá-lo com as extensões .xls ou .xlsx e é muito conveniente porque não é necessário preocupar-se com separadores de coluna ou delimitadores das casas decimais.

Basta que a planilha esteja estruturada com a mesma regra que usamos para o arquivo-texto: a primeira linha contém os nomes das variáveis (se houver acentos, sugere-se que os remova) e cada linha abaixo desta deve conter os dados de um indivíduo ou de uma unidade experimental.

O RStudio tem mecanismos de importação. Um dos métodos aparece em Environment -> Import Dataset. Outra maneira é clicar sobre o nome do arquivo e o RStudio lhe oferecerá a opção Import Dataset. Pode experimentar estes métodos, mas é bom saber como seria em uma Console “pura” (e que, depois, você pode colocar em um código).


O ambiente do RStudio é um facilitador. Os puristas do R podem preferir um terminal, que funciona como a Console sem a ajuda do ambiente do RStudio. Assim, tudo que aparece nas janelas do RStudio é, também, obtido por comandos que podem ser aproveitados para seus Rscripts.


Baixe o arquivo MetodoAnticoncepcional.xlsx para a pasta do projeto (este é um arquivo Excel com os mesmos dados do arquivo texto que utilizamos acima).

Nesse caso, para ler uma planilha Excel, usaremos um pacote (também chamado de library no R) chamado readxl. Caso readxl esteja instalado, bastará clicar sobre o nome do arquivo (na aba Files) e escolher Import Dataset. Na Console o RStudio mostra a operação que fez:

library(readxl)
MetodoAnticoncepcional <- readxl::read_excel("MetodoAnticoncepcional.xlsx")
View(MetodoAnticoncepcional)


Caso o comando library(readxl) dê erro, o pacote precisa ter sido instalado. A mensagem de erro será algo como:

Error in library(readxl) : there is no package called ‘readxl’

Como esse pacote está no CRAN, no RStudio você pode instalá-lo usando o menu Tools -> Install Packages… e e seguir as instruções na tela, fornecendo o nome do pacote.

Outra alternativa é dar o comando na Console com:

install.packages("readxl")

Ainda há um detalhe: fazer isto dentro do RStudio funciona bem no Windows, mas você pode preferir instalar os pacotes no Linux ou Macintosh como superusuário (sudo). Caso seja essa sua opção, abra um terminal e inicie o R Console como root. Em meu Ubuntu, por exemplo, o comportamento do terminal é assim:

Um instalação, geralmente, escreve várias coisas no terminal, que o instalador precisará ler apenas no caso de algo dar errado. Observe, principalmente, as últimas linhas. Caso termine com

* DONE (readxl)

sua instalação foi bem sucedida.


Estando tudo funcionando, a função library aparece pela primeira vez neste texto. A segunda função, read_excel lê a planilha e o operador de atribuição, <-, coloca seu conteúdo em uma variável. O RStudio aproveita o nome da planilha como nome da variável (o que pode não ser conveniente, mas você pode alterar). A terceira linha, View(MetodoAnticoncepcional) exibe a variável da mesma forma que obtivemos acima, quando clicamos sobre o nome da variável na aba Environment.


Os mesmos comandos que o RStudio ecoa na Console podem ser colocados dentro de um código, com resultados idênticos. Em um código você poderá escolher um nome de variável que lhe convenha e ter maior agilidade para lidar com os arquivos. Por exemplo:

library(readxl)
metodos <- readxl::read_excel("MetodoAnticoncepcional.xlsx")


O que fazem?

  • library ativa um package (pacote). As funções do R fazem parte de pacotes. Na primeira instalação do R é comum termos apenas as funções básicas com as funções vistas até aqui.
  • A função read_excel, uma das funções do pacote readxl, só funciona depois que library(readxl) for executada uma vez.
  • Alternativamente, observe a chamada da função com readxl::read_excel. Tendo usado library, readxl:: é opcional; usando readxl::, library pode ser dispensada. Embora seja redundante usar as duas formas, prefiro manter o hábito por vários motivos: (1) lembrar de qual pacote a função veio e (2) evitar ambiguidades porque pacotes diferentes podem ter funções com nomes iguais, e é melhor ter certeza de que o R está usando a função que você escolheu.
  • a variável metodos é o nome que escolhemos (note que sem acentuação; pode ser qualquer nome válido para um variável), e conterá os dados da planilha importada.

Existe uma terceira razão para preferir a notação package:: sem usar library no início do código. É a melhor forma de implementar chamadas entre funções quando desenvolvemos pacotes novos, mas essa discussão está além do escopo do presente tutorial — você pode aceitar por enquanto, como um bom hábito.


Para saber qual é o tipo de objeto que readxl::read_excel devolve, podemos perguntar ao R:

metodos <- readxl::read_excel("MetodoAnticoncepcional.xlsx")
cat(is.data.frame(metodos))
TRUE

O R informa que é um dataframe mas, cuidado… observe:

metodos <- readxl::read_excel("MetodoAnticoncepcional.xlsx")
print(str(metodos))
tibble [60 × 3] (S3: tbl_df/tbl/data.frame)
 $ ID    : num [1:60] 1 2 3 4 5 6 7 8 9 10 ...
 $ Idade : num [1:60] 15 15 16 17 16 15 17 16 17 16 ...
 $ Metodo: chr [1:60] "Tabelinha" "Tabelinha" "Preservativo" "Pílula" ...
NULL
metodos <- as.data.frame(metodos)
print(str(metodos))
'data.frame':   60 obs. of  3 variables:
 $ ID    : num  1 2 3 4 5 6 7 8 9 10 ...
 $ Idade : num  15 15 16 17 16 15 17 16 17 16 ...
 $ Metodo: chr  "Tabelinha" "Tabelinha" "Preservativo" "Pílula" ...
NULL

Isto significa que readxl::read_excel devolve um objeto é um dataframe modificado, aceito como tal pela função is.data.frame. O tibble é uma versão de dataframe amplamente utilizado no ecossistema tidyverse, que pode causar problemas de compatibilidade com funções que não são parte desse conjunto. É um objeto tão parecido que, para muitas funções, é equivalente. A função str revela que metodos é um tibble. Quando há problemas, podemos forçar a conversão em dataframe com

metodos <- as.data.frame(metodos)

confirmamos que algo mudou usando, novamente, a função str. Portanto, para garantir que o objeto seja um dataframe, pode-se fazer a leitura de planilhas assim:

metodos <- as.data.frame(readxl::read_excel("MetodoAnticoncepcional.xlsx"))
print(str(metodos))
'data.frame':   60 obs. of  3 variables:
 $ ID    : num  1 2 3 4 5 6 7 8 9 10 ...
 $ Idade : num  15 15 16 17 16 15 17 16 17 16 ...
 $ Metodo: chr  "Tabelinha" "Tabelinha" "Preservativo" "Pílula" ...
NULL

Arquivos em outros formatos

Há alguns outros formatos pré-instalados no RStudio. Funcionará como no caso do Excel.

Por exemplo, para SPSS:

library(haven)
dt_anxproc1 <- haven::read_sav("AnxietyProcrastination.sav")

Para Stata:

library(haven)
lbw <- haven::read_dta("lbw.dta")

Para o formato do LibreOffice (.ods) não há nada pronto no RStudio. Não é problema: existe package para isto, como:

library(readODS)
dt_anxproc2 <- readODS::read_ods("AnxietyProcrastination.ods")

Caso os execute serão criados __dataframe_s_, respectivamente chamados dt_anxproc1, lbw e dt_anxproc2, todos com o mesmo conteúdo (claramente, é preciso antes baixar os arquivos AnxietyProcrastination.sav, lbw.dta e AnxietyProcrastination.ods para a pasta do projeto).

Manipulando um dataframe

retomando o dataframe

Vamos retormar o dataframe metodos com os seguintes comandos, já executados:

metodos <- as.data.frame(readxl::read_excel("MetodoAnticoncepcional.xlsx"))

acessando elementos individuais de um dataframe

Podemos verificar tanto o conteúdo das colunas de um dataframe quanto os tipos de variável nele contidos.

O conteúdo das colunas podem ser acessados, fornecendo simplesmente o nome da variável:

metodos$Idade
 [1] 15 15 16 17 16 15 17 16 17 16 16 17 15 15 14 16 16 18 14 16 17 16 15 16 17
[26] 18 18 15 16 16 16 14 15 15 16 17 14 16 15 16 16 15 16 18 19 18 18 16 17 18
[51] 15 17 16 16 18 15 17 15 16 15

Note o símbolo $, significando que queremos a coluna Idade que está dentro do dataframe metodos.

Os números entre colchetes à esquerda representam a posição do primeiro elemento exibido em cada linha. Por exemplo, o primeiro elemento contém o valor 15

metodos$Idade[1]
[1] 15

o vigésimo sexto elemento contém o valor 18:

metodos$Idade[26]
[1] 18

o quinquagésimo terceiro contém o valor 16:

metodos$Idade[53]
[1] 16

e o último elemento contém o valor 15:

metodos$Idade[60]
[1] 15


Em situações em que o número de linhas (rows, em inglês) não é conhecido, o último elemento pode ser acessado com:

metodos$Idade[nrow(metodos)]
[1] 15

A função nrow, aninhada dentros dos colchetes, devolve o número de linhas que metodos tem; neste caso:

nrow(metodos)
[1] 60

devolve o valor 60.

Note que o R executa os colchetes e parênteses em uma expressão do mais interno para fora. Então, metodos$Idade[nrow(metodos)] torna-se metodos$Idade[60] e esta variável contém o valor 15.


Os elementos da coluna metodos$Idade são todos números:

is.numeric(metodos$Idade)
[1] TRUE

E podemos perguntar se são, por exemplo, finitos (e, neste caso, cada valor é verificado):

is.finite(metodos$Idade)
 [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[16] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[31] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[46] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE


Em conexão com o comentário, acima, de que em R há muitos tipos de variáveis que não têm correspondência em outras linguagens de programação, note também que uma variável pode ser vista como se tivesse vários “tipos” e ou “subtipos” simultaneamente. Por exemplo, a coluna Idade, além de numérica e contendo números finitos, também pode ser tratada como um vetor.

is.vector(metodos$Idade)
[1] TRUE


A coluna Metodo, obviamente, não é numérica:

is.numeric(metodos$Metodo)
[1] FALSE


Não confunda metodos, que é o nome que demos ao dataframe, com Metodo que é uma coluna do dataframe, a qual é endereçada por metodos$Metodo.


A coluna metodos$Metodo poderia ser um fator uma vez que tem poucos valores diferentes:

unique(metodos$Metodo)
[1] "Tabelinha"    "Preservativo" "Pílula"       "Outro"       

No entanto, a função read_excel a trouxe como uma variável character:

is.factor(metodos$Metodo)
[1] FALSE
is.character(metodos$Metodo)
[1] TRUE

Isto pode ser corrigido; voltaremos a lidar com fatores adiante.

__dataframe_s_ são organizados em [linha,coluna]. É possível acessar uma linha específica de um dataframe pelo seu número. A segunda linha contém:

metodos[2,]
# A tibble: 1 × 3
     ID Idade Metodo   
  <dbl> <dbl> <chr>    
1     2    15 Tabelinha

Podemos também acessar uma coluna pelo seu número. A terceira coluna contém:

metodos[,3]
 [1] "Tabelinha"    "Tabelinha"    "Preservativo" "Pílula"       "Pílula"      
 [6] "Tabelinha"    "Tabelinha"    "Preservativo" "Pílula"       "Preservativo"
[11] "Preservativo" "Preservativo" "Outro"        "Pílula"       "Preservativo"
[16] "Tabelinha"    "Tabelinha"    "Outro"        "Pílula"       "Outro"       
[21] "Preservativo" "Pílula"       "Tabelinha"    "Tabelinha"    "Tabelinha"   
[26] "Pílula"       "Tabelinha"    "Preservativo" "Preservativo" "Tabelinha"   
[31] "Outro"        "Tabelinha"    "Tabelinha"    "Preservativo" "Pílula"      
[36] "Pílula"       "Preservativo" "Preservativo" "Preservativo" "Outro"       
[41] "Tabelinha"    "Tabelinha"    "Pílula"       "Tabelinha"    "Pílula"      
[46] "Preservativo" "Preservativo" "Tabelinha"    "Preservativo" "Pílula"      
[51] "Tabelinha"    "Tabelinha"    "Preservativo" "Preservativo" "Pílula"      
[56] "Tabelinha"    "Tabelinha"    "Pílula"       "Preservativo" "Tabelinha"   

o mesmo que buscar por

metodos[, "Metodo"]
 [1] "Tabelinha"    "Tabelinha"    "Preservativo" "Pílula"       "Pílula"      
 [6] "Tabelinha"    "Tabelinha"    "Preservativo" "Pílula"       "Preservativo"
[11] "Preservativo" "Preservativo" "Outro"        "Pílula"       "Preservativo"
[16] "Tabelinha"    "Tabelinha"    "Outro"        "Pílula"       "Outro"       
[21] "Preservativo" "Pílula"       "Tabelinha"    "Tabelinha"    "Tabelinha"   
[26] "Pílula"       "Tabelinha"    "Preservativo" "Preservativo" "Tabelinha"   
[31] "Outro"        "Tabelinha"    "Tabelinha"    "Preservativo" "Pílula"      
[36] "Pílula"       "Preservativo" "Preservativo" "Preservativo" "Outro"       
[41] "Tabelinha"    "Tabelinha"    "Pílula"       "Tabelinha"    "Pílula"      
[46] "Preservativo" "Preservativo" "Tabelinha"    "Preservativo" "Pílula"      
[51] "Tabelinha"    "Tabelinha"    "Preservativo" "Preservativo" "Pílula"      
[56] "Tabelinha"    "Tabelinha"    "Pílula"       "Preservativo" "Tabelinha"   

Podemos combinar linha e coluna. O conteúdo da segunda linha, terceira coluna contém:

metodos[2,3]
[1] "Tabelinha"


A coluna Idade é a segunda coluna do dataframe. Antes, acessamos esta coluna com

metodos$Idade
 [1] 15 15 16 17 16 15 17 16 17 16 16 17 15 15 14 16 16 18 14 16 17 16 15 16 17
[26] 18 18 15 16 16 16 14 15 15 16 17 14 16 15 16 16 15 16 18 19 18 18 16 17 18
[51] 15 17 16 16 18 15 17 15 16 15

e vimos que R nos fornece um vetor numérico. Podemos acessar os dados também pelo número da coluna com

metodos[,2]
 [1] 15 15 16 17 16 15 17 16 17 16 16 17 15 15 14 16 16 18 14 16 17 16 15 16 17
[26] 18 18 15 16 16 16 14 15 15 16 17 14 16 15 16 16 15 16 18 19 18 18 16 17 18
[51] 15 17 16 16 18 15 17 15 16 15

Observe que os dados são os mesmos, mas o formato não é. Acessando pelo número da coluna não obtivemos um vetor numérico. Caso precise, por exemplo para que uma função que aguarde dados neste formato, o equivalente é:

as.numeric(unlist(metodos[,2]))
 [1] 15 15 16 17 16 15 17 16 17 16 16 17 15 15 14 16 16 18 14 16 17 16 15 16 17
[26] 18 18 15 16 16 16 14 15 15 16 17 14 16 15 16 16 15 16 18 19 18 18 16 17 18
[51] 15 17 16 16 18 15 17 15 16 15

ou

as.numeric(unlist(metodos["Idade"]))
 [1] 15 15 16 17 16 15 17 16 17 16 16 17 15 15 14 16 16 18 14 16 17 16 15 16 17
[26] 18 18 15 16 16 16 14 15 15 16 17 14 16 15 16 16 15 16 18 19 18 18 16 17 18
[51] 15 17 16 16 18 15 17 15 16 15

Caso queiramos os métodos em um vetor alfanumérico, pode usar (pelo número da coluna ou pelo nome da coluna) algo como:

as.character(unlist(metodos["Metodo"]))
 [1] "Tabelinha"    "Tabelinha"    "Preservativo" "Pílula"       "Pílula"      
 [6] "Tabelinha"    "Tabelinha"    "Preservativo" "Pílula"       "Preservativo"
[11] "Preservativo" "Preservativo" "Outro"        "Pílula"       "Preservativo"
[16] "Tabelinha"    "Tabelinha"    "Outro"        "Pílula"       "Outro"       
[21] "Preservativo" "Pílula"       "Tabelinha"    "Tabelinha"    "Tabelinha"   
[26] "Pílula"       "Tabelinha"    "Preservativo" "Preservativo" "Tabelinha"   
[31] "Outro"        "Tabelinha"    "Tabelinha"    "Preservativo" "Pílula"      
[36] "Pílula"       "Preservativo" "Preservativo" "Preservativo" "Outro"       
[41] "Tabelinha"    "Tabelinha"    "Pílula"       "Tabelinha"    "Pílula"      
[46] "Preservativo" "Preservativo" "Tabelinha"    "Preservativo" "Pílula"      
[51] "Tabelinha"    "Tabelinha"    "Preservativo" "Preservativo" "Pílula"      
[56] "Tabelinha"    "Tabelinha"    "Pílula"       "Preservativo" "Tabelinha"   


selecionando dados

É possível filtrar por determinadas condições. Existem operadores:

  • de comparação: < (menor), <= (menor ou igual), == (igual), != (diferente), >= (maior ou igual) e > (maior).
  • lógicos: & (and), | (or) e ! (not).

As linhas dos indivíduos com idade menor ou igual a 15 anos são:

dftmp <- metodos[metodos$Idade<=15,]
print(dftmp)
   ID Idade       Metodo
1   1    15    Tabelinha
2   2    15    Tabelinha
6   6    15    Tabelinha
13 13    15        Outro
14 14    15       Pílula
15 15    14 Preservativo
19 19    14       Pílula
23 23    15    Tabelinha
28 28    15 Preservativo
32 32    14    Tabelinha
33 33    15    Tabelinha
34 34    15 Preservativo
37 37    14 Preservativo
39 39    15 Preservativo
42 42    15    Tabelinha
51 51    15    Tabelinha
56 56    15    Tabelinha
58 58    15       Pílula
60 60    15    Tabelinha

Este dftmp é um dataframe, contendo um subconjunto de metodos. Caso não apareça inteiro na Console (print só exibe as primeiras linhas), use a aba Environment para ver todo o seu conteúdo e confira o sucesso desta operação.

Quem não tem 17 é dado por:

dftmp <- metodos[metodos$Idade!=17,]
print(dftmp)
   ID Idade       Metodo
1   1    15    Tabelinha
2   2    15    Tabelinha
3   3    16 Preservativo
5   5    16       Pílula
6   6    15    Tabelinha
8   8    16 Preservativo
10 10    16 Preservativo
11 11    16 Preservativo
13 13    15        Outro
14 14    15       Pílula
15 15    14 Preservativo
16 16    16    Tabelinha
17 17    16    Tabelinha
18 18    18        Outro
19 19    14       Pílula
20 20    16        Outro
22 22    16       Pílula
23 23    15    Tabelinha
24 24    16    Tabelinha
26 26    18       Pílula
27 27    18    Tabelinha
28 28    15 Preservativo
29 29    16 Preservativo
30 30    16    Tabelinha
31 31    16        Outro
32 32    14    Tabelinha
33 33    15    Tabelinha
34 34    15 Preservativo
35 35    16       Pílula
37 37    14 Preservativo
38 38    16 Preservativo
39 39    15 Preservativo
40 40    16        Outro
41 41    16    Tabelinha
42 42    15    Tabelinha
43 43    16       Pílula
44 44    18    Tabelinha
45 45    19       Pílula
46 46    18 Preservativo
47 47    18 Preservativo
48 48    16    Tabelinha
50 50    18       Pílula
51 51    15    Tabelinha
53 53    16 Preservativo
54 54    16 Preservativo
55 55    18       Pílula
56 56    15    Tabelinha
58 58    15       Pílula
59 59    16 Preservativo
60 60    15    Tabelinha

Por exemplo, para saber quais estão entre 15 e 18 anos de idade (incluindo 15 mas não incluindo 18):

dftmp <- metodos[metodos$Idade>=15 & metodos$Idade<18,]
print(dftmp)
   ID Idade       Metodo
1   1    15    Tabelinha
2   2    15    Tabelinha
3   3    16 Preservativo
4   4    17       Pílula
5   5    16       Pílula
6   6    15    Tabelinha
7   7    17    Tabelinha
8   8    16 Preservativo
9   9    17       Pílula
10 10    16 Preservativo
11 11    16 Preservativo
12 12    17 Preservativo
13 13    15        Outro
14 14    15       Pílula
16 16    16    Tabelinha
17 17    16    Tabelinha
20 20    16        Outro
21 21    17 Preservativo
22 22    16       Pílula
23 23    15    Tabelinha
24 24    16    Tabelinha
25 25    17    Tabelinha
28 28    15 Preservativo
29 29    16 Preservativo
30 30    16    Tabelinha
31 31    16        Outro
33 33    15    Tabelinha
34 34    15 Preservativo
35 35    16       Pílula
36 36    17       Pílula
38 38    16 Preservativo
39 39    15 Preservativo
40 40    16        Outro
41 41    16    Tabelinha
42 42    15    Tabelinha
43 43    16       Pílula
48 48    16    Tabelinha
49 49    17 Preservativo
51 51    15    Tabelinha
52 52    17    Tabelinha
53 53    16 Preservativo
54 54    16 Preservativo
56 56    15    Tabelinha
57 57    17    Tabelinha
58 58    15       Pílula
59 59    16 Preservativo
60 60    15    Tabelinha

Para saber quem tem menos que 15 (inclusive) ou exatamente 17:

dftmp <- metodos[metodos$Idade<=15 | metodos$Idade==17,]
print(dftmp)
   ID Idade       Metodo
1   1    15    Tabelinha
2   2    15    Tabelinha
4   4    17       Pílula
6   6    15    Tabelinha
7   7    17    Tabelinha
9   9    17       Pílula
12 12    17 Preservativo
13 13    15        Outro
14 14    15       Pílula
15 15    14 Preservativo
19 19    14       Pílula
21 21    17 Preservativo
23 23    15    Tabelinha
25 25    17    Tabelinha
28 28    15 Preservativo
32 32    14    Tabelinha
33 33    15    Tabelinha
34 34    15 Preservativo
36 36    17       Pílula
37 37    14 Preservativo
39 39    15 Preservativo
42 42    15    Tabelinha
49 49    17 Preservativo
51 51    15    Tabelinha
52 52    17    Tabelinha
56 56    15    Tabelinha
57 57    17    Tabelinha
58 58    15       Pílula
60 60    15    Tabelinha

Para saber quem não é menor de idade (i.e., idades que não são menores que 18 anos), precisamos saber quem tem menor que 17 ou, pela negativa, quem não tem mais que 18:

dftmp <- metodos[metodos$Idade<=17,]
print(dftmp)
   ID Idade       Metodo
1   1    15    Tabelinha
2   2    15    Tabelinha
3   3    16 Preservativo
4   4    17       Pílula
5   5    16       Pílula
6   6    15    Tabelinha
7   7    17    Tabelinha
8   8    16 Preservativo
9   9    17       Pílula
10 10    16 Preservativo
11 11    16 Preservativo
12 12    17 Preservativo
13 13    15        Outro
14 14    15       Pílula
15 15    14 Preservativo
16 16    16    Tabelinha
17 17    16    Tabelinha
19 19    14       Pílula
20 20    16        Outro
21 21    17 Preservativo
22 22    16       Pílula
23 23    15    Tabelinha
24 24    16    Tabelinha
25 25    17    Tabelinha
28 28    15 Preservativo
29 29    16 Preservativo
30 30    16    Tabelinha
31 31    16        Outro
32 32    14    Tabelinha
33 33    15    Tabelinha
34 34    15 Preservativo
35 35    16       Pílula
36 36    17       Pílula
37 37    14 Preservativo
38 38    16 Preservativo
39 39    15 Preservativo
40 40    16        Outro
41 41    16    Tabelinha
42 42    15    Tabelinha
43 43    16       Pílula
48 48    16    Tabelinha
49 49    17 Preservativo
51 51    15    Tabelinha
52 52    17    Tabelinha
53 53    16 Preservativo
54 54    16 Preservativo
56 56    15    Tabelinha
57 57    17    Tabelinha
58 58    15       Pílula
59 59    16 Preservativo
60 60    15    Tabelinha

ou

dftmp <- metodos[!metodos$Idade>=18,]
print(dftmp)
   ID Idade       Metodo
1   1    15    Tabelinha
2   2    15    Tabelinha
3   3    16 Preservativo
4   4    17       Pílula
5   5    16       Pílula
6   6    15    Tabelinha
7   7    17    Tabelinha
8   8    16 Preservativo
9   9    17       Pílula
10 10    16 Preservativo
11 11    16 Preservativo
12 12    17 Preservativo
13 13    15        Outro
14 14    15       Pílula
15 15    14 Preservativo
16 16    16    Tabelinha
17 17    16    Tabelinha
19 19    14       Pílula
20 20    16        Outro
21 21    17 Preservativo
22 22    16       Pílula
23 23    15    Tabelinha
24 24    16    Tabelinha
25 25    17    Tabelinha
28 28    15 Preservativo
29 29    16 Preservativo
30 30    16    Tabelinha
31 31    16        Outro
32 32    14    Tabelinha
33 33    15    Tabelinha
34 34    15 Preservativo
35 35    16       Pílula
36 36    17       Pílula
37 37    14 Preservativo
38 38    16 Preservativo
39 39    15 Preservativo
40 40    16        Outro
41 41    16    Tabelinha
42 42    15    Tabelinha
43 43    16       Pílula
48 48    16    Tabelinha
49 49    17 Preservativo
51 51    15    Tabelinha
52 52    17    Tabelinha
53 53    16 Preservativo
54 54    16 Preservativo
56 56    15    Tabelinha
57 57    17    Tabelinha
58 58    15       Pílula
59 59    16 Preservativo
60 60    15    Tabelinha

Os operadores podem ser combinados. A ordem das comparações é dada por , indo do mais interno para o mais externo, se forem aninhados. Por exemplo, os cálculos são diferentes:

  1+3 / 4+5 / 2
[1] 4.25
((1+3)/(4+5)) / 2
[1] 0.2222222

O primeiro obedece a precedência habitual da matemática (divisão vem antes da soma). Então divide 3 por 4 resultando em 0.75, então 5 por 2 resultando em 2.5, e finalmente faz a soma de 1+0.75+2.5 resultando em 4.25; se não era o pretendido, os espaços em branco nada resolvem (são ignorados). O segundo soma 1+3 (resulta em 4), depois 3+5 (resulta em 8), então divide 4 por 8 resultando em 0.5 e, finalmente, divide por 2 resultando em 0.25. Na dúvida sobre a precedência das operações, use e abuse dos .

Da mesma forma, para comparações a ordem é regulada com . Se quisermos saber quem tem entre (15 e 16) ou entre (18 e 19), inclusive

dftmp <- metodos[(metodos$Idade>=15 & metodos$Idade<=16) | 
                 (metodos$Idade>=18 & metodos$Idade<=19),]
print(dftmp)
   ID Idade       Metodo
1   1    15    Tabelinha
2   2    15    Tabelinha
3   3    16 Preservativo
5   5    16       Pílula
6   6    15    Tabelinha
8   8    16 Preservativo
10 10    16 Preservativo
11 11    16 Preservativo
13 13    15        Outro
14 14    15       Pílula
16 16    16    Tabelinha
17 17    16    Tabelinha
18 18    18        Outro
20 20    16        Outro
22 22    16       Pílula
23 23    15    Tabelinha
24 24    16    Tabelinha
26 26    18       Pílula
27 27    18    Tabelinha
28 28    15 Preservativo
29 29    16 Preservativo
30 30    16    Tabelinha
31 31    16        Outro
33 33    15    Tabelinha
34 34    15 Preservativo
35 35    16       Pílula
38 38    16 Preservativo
39 39    15 Preservativo
40 40    16        Outro
41 41    16    Tabelinha
42 42    15    Tabelinha
43 43    16       Pílula
44 44    18    Tabelinha
45 45    19       Pílula
46 46    18 Preservativo
47 47    18 Preservativo
48 48    16    Tabelinha
50 50    18       Pílula
51 51    15    Tabelinha
53 53    16 Preservativo
54 54    16 Preservativo
55 55    18       Pílula
56 56    15    Tabelinha
58 58    15       Pílula
59 59    16 Preservativo
60 60    15    Tabelinha

(a linha quebrada após | é opcional; apenas para facilitar a legibilidade do código, evitando escrever linhas muito longas que saem da tela).

alterando o conteúdo do dataframe

Como podemos acessar os elementos de um dataframe, podemos também alterar seus valores usando o operador de atribuição, <-. Por exemplo:

metodos$Idade[45] <- 19.5

e confira com

metodos$Idade
 [1] 15.0 15.0 16.0 17.0 16.0 15.0 17.0 16.0 17.0 16.0 16.0 17.0 15.0 15.0 14.0
[16] 16.0 16.0 18.0 14.0 16.0 17.0 16.0 15.0 16.0 17.0 18.0 18.0 15.0 16.0 16.0
[31] 16.0 14.0 15.0 15.0 16.0 17.0 14.0 16.0 15.0 16.0 16.0 15.0 16.0 18.0 19.5
[46] 18.0 18.0 16.0 17.0 18.0 15.0 17.0 16.0 16.0 18.0 15.0 17.0 15.0 16.0 15.0

(localize o 450 elemento e veja que seu valor é, agora, 19.5).

Mais uma coisa aconteceu. Notou que, ao adicionarmos um elemento com uma casa decimal, todos os valores agora apareceram com uma casa decimal? Um vetor tem que ter elementos todos do mesmo tipo e, para acomodar o 19.5, é inteiramente formado por números do tipo double (a forma do R dizer que é número fracionário).

is.numeric(metodos$Idade)
[1] TRUE
is.integer(metodos$Idade)
[1] FALSE
is.double(metodos$Idade)
[1] TRUE

A esta altura você pode imaginar que devem existir muitas funções R iniciadas com is… e que pode ser uma tarefa insana ficar tentando várias funções até adivinhar com qual tipo estamos lidando. Podemos reproduzir na Console as informações de uma variável que aparecem na aba Environment com a função str (de structure, estrutura):

str(metodos)
'data.frame':   60 obs. of  3 variables:
 $ ID    : num  1 2 3 4 5 6 7 8 9 10 ...
 $ Idade : num  15 15 16 17 16 15 17 16 17 16 ...
 $ Metodo: chr  "Tabelinha" "Tabelinha" "Preservativo" "Pílula" ...

mostrando a coluna ID é numérica (num), Idade é numérica e Metodo é character (chr).

Ajuda, ainda, conhecer a função sapply:

sapply(metodos, typeof)
         ID       Idade      Metodo 
   "double"    "double" "character" 

que informa o tipo double para metodos$Idade.


Como sempre, se usamos apenas o nome da variável metodos na Console, R tenta exibir todo seu conteúdo:

print(metodos)
   ID Idade       Metodo
1   1  15.0    Tabelinha
2   2  15.0    Tabelinha
3   3  16.0 Preservativo
4   4  17.0       Pílula
5   5  16.0       Pílula
6   6  15.0    Tabelinha
7   7  17.0    Tabelinha
8   8  16.0 Preservativo
9   9  17.0       Pílula
10 10  16.0 Preservativo
11 11  16.0 Preservativo
12 12  17.0 Preservativo
13 13  15.0        Outro
14 14  15.0       Pílula
15 15  14.0 Preservativo
16 16  16.0    Tabelinha
17 17  16.0    Tabelinha
18 18  18.0        Outro
19 19  14.0       Pílula
20 20  16.0        Outro
21 21  17.0 Preservativo
22 22  16.0       Pílula
23 23  15.0    Tabelinha
24 24  16.0    Tabelinha
25 25  17.0    Tabelinha
26 26  18.0       Pílula
27 27  18.0    Tabelinha
28 28  15.0 Preservativo
29 29  16.0 Preservativo
30 30  16.0    Tabelinha
31 31  16.0        Outro
32 32  14.0    Tabelinha
33 33  15.0    Tabelinha
34 34  15.0 Preservativo
35 35  16.0       Pílula
36 36  17.0       Pílula
37 37  14.0 Preservativo
38 38  16.0 Preservativo
39 39  15.0 Preservativo
40 40  16.0        Outro
41 41  16.0    Tabelinha
42 42  15.0    Tabelinha
43 43  16.0       Pílula
44 44  18.0    Tabelinha
45 45  19.5       Pílula
46 46  18.0 Preservativo
47 47  18.0 Preservativo
48 48  16.0    Tabelinha
49 49  17.0 Preservativo
50 50  18.0       Pílula
51 51  15.0    Tabelinha
52 52  17.0    Tabelinha
53 53  16.0 Preservativo
54 54  16.0 Preservativo
55 55  18.0       Pílula
56 56  15.0    Tabelinha
57 57  17.0    Tabelinha
58 58  15.0       Pílula
59 59  16.0 Preservativo
60 60  15.0    Tabelinha
print.data.frame(metodos)
   ID Idade       Metodo
1   1  15.0    Tabelinha
2   2  15.0    Tabelinha
3   3  16.0 Preservativo
4   4  17.0       Pílula
5   5  16.0       Pílula
6   6  15.0    Tabelinha
7   7  17.0    Tabelinha
8   8  16.0 Preservativo
9   9  17.0       Pílula
10 10  16.0 Preservativo
11 11  16.0 Preservativo
12 12  17.0 Preservativo
13 13  15.0        Outro
14 14  15.0       Pílula
15 15  14.0 Preservativo
16 16  16.0    Tabelinha
17 17  16.0    Tabelinha
18 18  18.0        Outro
19 19  14.0       Pílula
20 20  16.0        Outro
21 21  17.0 Preservativo
22 22  16.0       Pílula
23 23  15.0    Tabelinha
24 24  16.0    Tabelinha
25 25  17.0    Tabelinha
26 26  18.0       Pílula
27 27  18.0    Tabelinha
28 28  15.0 Preservativo
29 29  16.0 Preservativo
30 30  16.0    Tabelinha
31 31  16.0        Outro
32 32  14.0    Tabelinha
33 33  15.0    Tabelinha
34 34  15.0 Preservativo
35 35  16.0       Pílula
36 36  17.0       Pílula
37 37  14.0 Preservativo
38 38  16.0 Preservativo
39 39  15.0 Preservativo
40 40  16.0        Outro
41 41  16.0    Tabelinha
42 42  15.0    Tabelinha
43 43  16.0       Pílula
44 44  18.0    Tabelinha
45 45  19.5       Pílula
46 46  18.0 Preservativo
47 47  18.0 Preservativo
48 48  16.0    Tabelinha
49 49  17.0 Preservativo
50 50  18.0       Pílula
51 51  15.0    Tabelinha
52 52  17.0    Tabelinha
53 53  16.0 Preservativo
54 54  16.0 Preservativo
55 55  18.0       Pílula
56 56  15.0    Tabelinha
57 57  17.0    Tabelinha
58 58  15.0       Pílula
59 59  16.0 Preservativo
60 60  15.0    Tabelinha

Como são muitas linhas, R trunca e informa quantas não exibiu. Tentar mostrar um dataframe desta forma, portanto, não é muito prático; usar o ambiente do RStudio através da aba Environment é muito mais fácil.

Note, ainda, os números das linhas à esquerda. Estes são os números de linha de metodos. Neste caso é apenas uma coincidência que sejam iguais a metodos$ID, pois os pacientes foram numerados sequencialmente no arquivo original.


alterando o tipo de variável

para character

Caso lhe incomode que metodos$ID seja um número, um tipo pode ser convertido em outro:

metodos$ID <- as.character(metodos$ID)

Repare que a função é as.character, significando como alfanumérica (e não is.character, que pergunta se é alfanumérica?). Variáveis do tipo chr são as que podem acomodar textos como “Tabelinha”, “Outros métodos” ou mesmo letras e números combinados, como “RG 123456”.

Também pode ser estranho atribuir a metodos$ID uma operação feita com a própria variável. O que acontece em linguagens de programação é que o que está além do operador de atribuição <- é processado primeiro e, então seu resultado é jogado na variável à sua esquerda. Neste exemplo, o conteúdo de metodos$ID é passado à função as.character, que a devolve convertida em caracteres; o resultado desta operação é atribuído à própria metodos$ID, sobrepondo seus valores anteriores. Confira que o tipo da variável metodos$ID mudou para chr:

str(metodos)
'data.frame':   60 obs. of  3 variables:
 $ ID    : chr  "1" "2" "3" "4" ...
 $ Idade : num  15 15 16 17 16 15 17 16 17 16 ...
 $ Metodo: chr  "Tabelinha" "Tabelinha" "Preservativo" "Pílula" ...

para fator

Mencionamos, acima, que metodos$Metodo deveria ser tratado como um fator. Existe função para isto:

metodos$Metodo <- as.factor(metodos$Metodo)

Confira que ocorreu com metodos$Metodo:

str(metodos)
'data.frame':   60 obs. of  3 variables:
 $ ID    : chr  "1" "2" "3" "4" ...
 $ Idade : num  15 15 16 17 16 15 17 16 17 16 ...
 $ Metodo: Factor w/ 4 levels "Outro","Pílula",..: 4 4 3 2 2 4 4 3 2 3 ...

Observe que metodos$Metodo, sendo um fator (portanto uma variável nominal), tem indicação de quantos níveis (i.e., quantos valores diferentes existem) armazenados na variável. São 4, diferentes, como já tínhamos visto com

unique(metodos$Metodo)
[1] Tabelinha    Preservativo Pílula       Outro       
Levels: Outro Pílula Preservativo Tabelinha

Note também que os níveis têm números inteiros associados com cada categoria. A ordem dos níveis do fator segue a ordem de aparição dos dados no dataframe.

print(metodos$Metodo)
 [1] Tabelinha    Tabelinha    Preservativo Pílula       Pílula      
 [6] Tabelinha    Tabelinha    Preservativo Pílula       Preservativo
[11] Preservativo Preservativo Outro        Pílula       Preservativo
[16] Tabelinha    Tabelinha    Outro        Pílula       Outro       
[21] Preservativo Pílula       Tabelinha    Tabelinha    Tabelinha   
[26] Pílula       Tabelinha    Preservativo Preservativo Tabelinha   
[31] Outro        Tabelinha    Tabelinha    Preservativo Pílula      
[36] Pílula       Preservativo Preservativo Preservativo Outro       
[41] Tabelinha    Tabelinha    Pílula       Tabelinha    Pílula      
[46] Preservativo Preservativo Tabelinha    Preservativo Pílula      
[51] Tabelinha    Tabelinha    Preservativo Preservativo Pílula      
[56] Tabelinha    Tabelinha    Pílula       Preservativo Tabelinha   
Levels: Outro Pílula Preservativo Tabelinha

Esta ordem, quando não é conveniente, pode ser escolhida com:

metodos$Metodo <- factor(metodos$Metodo,levels=c("Tabelinha","Pílula","Preservativo","Outro"))

Veja o que mudou com

str(metodos)
'data.frame':   60 obs. of  3 variables:
 $ ID    : chr  "1" "2" "3" "4" ...
 $ Idade : num  15 15 16 17 16 15 17 16 17 16 ...
 $ Metodo: Factor w/ 4 levels "Tabelinha","Pílula",..: 1 1 3 2 2 1 1 3 2 3 ...
unique(metodos$Metodo)
[1] Tabelinha    Preservativo Pílula       Outro       
Levels: Tabelinha Pílula Preservativo Outro

e observe a ordem dos levels que a função unique agora exibe.

- relevel

Já existindo uma variável que é um fator sem ter que refazer o trabalho, podemos mudar qual é a categoria de referência (o primeiro nível, que algumas funções estatísticas usam para computar diferenças) com o uso de relevel:

unique(metodos$Metodo)
[1] Tabelinha    Preservativo Pílula       Outro       
Levels: Tabelinha Pílula Preservativo Outro
metodos$Metodo <- relevel(metodos$Metodo, ref="Preservativo")
unique(metodos$Metodo)
[1] Tabelinha    Preservativo Pílula       Outro       
Levels: Preservativo Tabelinha Pílula Outro

Note que unique mostra as strings na ordem em que as encontra no dataframe, mas relata os Levels na ordem definida no fator. Uma forma mais direta é usar

levels(metodos$Metodo)
[1] "Preservativo" "Tabelinha"    "Pílula"       "Outro"       

- droplevels

Outra situação acontece quando queremos excluir do dataframe as categorias que, por algum motivo, não mais interessam para a análise. O problema é que ela continua existindo na definição da variável e conta como zero ocorrências. Precisamos de droplevels para consertar. Observe (criaremos cópia de metodos para não estragar o que está feito até o momento):

teste1 <- metodos
nrow(teste1) # originalmente tem 60 linhas
[1] 60
teste1 <- teste1[teste1$Metodo!="Outro",]
summary(teste1$Metodo)
Preservativo    Tabelinha       Pílula        Outro 
          19           22           14            0 
levels(teste1$Metodo)
[1] "Preservativo" "Tabelinha"    "Pílula"       "Outro"       
nrow(teste1) # mostra que perdeu linhas (toda a linha, muito radical)
[1] 55
teste1$Metodo <- droplevels(teste1$Metodo)
summary(teste1$Metodo)
Preservativo    Tabelinha       Pílula 
          19           22           14 
levels(teste1$Metodo)
[1] "Preservativo" "Tabelinha"    "Pílula"      

Jogar fora todos os dados de um indivíduos (nesse exemplo a idade, mas poderíamos ter estatura, IMC, dados demográficos, etc.) só porque usa outro método anticoncepcional pode não ser interessante. Uma alternativa é somente colocar NA em uma ou mais categorias e reorganizar os níveis remanescentes. Fica assim:

teste2 <- metodos
nrow(teste2) # originalmente tem 60 linhas
[1] 60
teste2$Metodo[teste2$Metodo=="Outro"] <- NA
summary(teste2$Metodo)
Preservativo    Tabelinha       Pílula        Outro         NA's 
          19           22           14            0            5 
levels(teste2$Metodo)
[1] "Preservativo" "Tabelinha"    "Pílula"       "Outro"       
nrow(teste2) # continua com 60 linhas, sem perder os outros dados
[1] 60
teste2$Metodo <- droplevels(teste2$Metodo)
summary(teste2$Metodo)
Preservativo    Tabelinha       Pílula         NA's 
          19           22           14            5 
levels(teste2$Metodo)
[1] "Preservativo" "Tabelinha"    "Pílula"      

Gravando e recuperando um dataframe

formatos nativos do R

Depois de alterar como precisa um dataframe, você pode querer armazená-lo, para uso futuro, em um arquivo em formato do R use:

saveRDS(metodos, file="metodos.rds")

e aparecerá um arquivo chamado metodos.rds na aba Files.

RDS é destinado a salvar um único objeto (qualquer objeto, não necessariamente um dataframe; veremos outros tipos de objeto adiante).

Uma outra alternativa é usar

save(metodos, file="metodos.Rdata")

para criar metodos.Rdata na aba Files. Seu conteúdo é o estado atual de metodos e mais…

RData permite salvar múltiplos objetos em um único arquivo. É uma representação gravada de parte ou de todas as variáveis que estão na memória. Cuidado porque podem ser criados arquivos muito grandes.


É comum, quando tentar fechar o RStudio, que o sistema lhe ofereça salvar tudo o que está na memória, para reabrir quando você for continuar a trabalhar. Esse processo que pode levar vários minutos e outros tantos quando quiser retomar o trabalho.

Sugerimos que não salve o ambiente inteiro ao final de cada sessão.


Para comprovar que tivemos sucesso em gravar nossos dados, vamos destruir a variável metodos com

rm(metodos)

Esta função, rm, remove o dataframe que, agora, não está mais disponível na memória do computador para uso (observe a aba Environment):

try(str(metodos))
Error in eval(expr, envir) : objeto 'metodos' não encontrado

A função que recupera o que está salvo é readRDS, retornando o objeto diretamente e permitindo que você escolha o nome dele ao carregá-lo. Por exemplo:

copia.de.metodos <- readRDS("metodos.rds")

ou, para trazer com o mesmo nome, use

metodos <- readRDS("metodos.rds")

o que pode ser comprovado com

str(metodos)
'data.frame':   60 obs. of  3 variables:
 $ ID    : chr  "1" "2" "3" "4" ...
 $ Idade : num  15 15 16 17 16 15 17 16 17 16 ...
 $ Metodo: Factor w/ 4 levels "Preservativo",..: 2 2 1 3 3 2 2 1 3 1 ...

a cópia que fizemos é idêntica:

str(copia.de.metodos)
'data.frame':   60 obs. of  3 variables:
 $ ID    : chr  "1" "2" "3" "4" ...
 $ Idade : num  15 15 16 17 16 15 17 16 17 16 ...
 $ Metodo: Factor w/ 4 levels "Preservativo",..: 2 2 1 3 3 2 2 1 3 1 ...

No caso do Rdata recupera-se com a função load mas o que estamos trazendo de volta vem com seus nomes originais (note que não há atribuição com o operador <-)

rm(metodos)
try(str(metodos))
Error in eval(expr, envir) : objeto 'metodos' não encontrado
load("metodos.Rdata")
str(metodos)
'data.frame':   60 obs. of  3 variables:
 $ ID    : chr  "1" "2" "3" "4" ...
 $ Idade : num  15 15 16 17 16 15 17 16 17 16 ...
 $ Metodo: Factor w/ 4 levels "Preservativo",..: 2 2 1 3 3 2 2 1 3 1 ...

Entre outras vantagens de usar os formatos nativos do R observe que os atributos das colunas do dataframe são preservados. A coluna ID está em chr e Metodo é fator.

formato Excel

Caso prefira salvar em formato de planilha, uma possibilidade é usar

library(openxlsx)
openxlsx::write.xlsx(metodos,"MetodosAnticoncepcionais.xlsx")

para recuperar a planilha em um dataframe:

library(readxl)
metodos <- readxl::read_excel("MetodosAnticoncepcionais.xlsx")

Por ter convertido em planilhas Excel, atributos de algumas colunas podem se perder e você terá que defini-los novamente. Veja que a coluna Metodo deixou de ser fator e (como não usamos as.data.frame) a variável metodos voltou a conter um tibble.

str(metodos)
tibble [60 × 3] (S3: tbl_df/tbl/data.frame)
 $ ID    : chr [1:60] "1" "2" "3" "4" ...
 $ Idade : num [1:60] 15 15 16 17 16 15 17 16 17 16 ...
 $ Metodo: chr [1:60] "Tabelinha" "Tabelinha" "Preservativo" "Pílula" ...

c, NA, NULL, rm

Estes funções e valores precisam ser claramente entendidos em R.

A função c é o combinador que já utilizamos antes. Há situações em que precisamos criar um vetor numérico vazio e adicionar valores um a um. Por exemplo, este código cria um vetor vazio e, depois, adiciona 20 números inteiros pseudo-aleatórios entre 0 e 10:

vetor <- c()
for ( i in 1:20)
{
  vetor <- c(vetor, round(runif(n=1, min=0, max=10), 0))  
}
cat("O vetor contém",vetor,"\n")
O vetor contém 10 4 6 5 6 7 1 2 3 7 6 2 3 3 9 1 8 2 9 6 

O valor ausente NA (not available, não disponível) aparece quando há valores faltantes. Muitas vezes é necessário informar ao R para ignorá-los. Isto acontece com frequência quando uma planilha é lida para um dataframe e há células em branco: o R as indica com NA.

Por exemplo, imagine que pretendemos computar a média do vetor numérico que acabamos de criar:

cat("A média aritmética é",mean(vetor),"\n")
A média aritmética é 5 

Suponha, agora, que o terceiro valor do vetor esteja ausente e queiramos calcular a média:

vetor[3] <- NA
cat("O vetor agora contém:",vetor,"\n")
O vetor agora contém: 10 4 NA 5 6 7 1 2 3 7 6 2 3 3 9 1 8 2 9 6 
cat("A média aritmética é",mean(vetor),"\n")
A média aritmética é NA 

Por causa de um único NA entre os 20 números, a média não pode ser calculada. A função mean (e várias outras funções do R) tem o parâmetro lógico na.rm que instrui sua remoção antes de calcular a média.

cat("A média aritmética é",mean(vetor, na.rm=TRUE),"\n")
A média aritmética é 4.947368 

Existe, também, a função is.na para verificar se algum valor está ausente. Por exemplo, o vetor tem tamanho de 20 números, mas somente 19 são válidos. Podemos saber disto perguntando ao R:

cat("Valores válidos: n =",sum(!is.na(vetor)),"\n")
Valores válidos: n = 19 

onde is.na(vetor) retorna TRUE (ou 1) para os números NA e ! é a negativa (portanto a expressão retorna a soma de TRUEs que não são NA, i.e., números válidos).

O valor NULL é nulo, vazio, diferente do NA que é ausente. É menos usado, mas pode servir para esvaziar uma variável. Observe a aba do Environment, onde deve estar a variável vetor. Faça:

vetor <- NULL

e verá que ela ainda existe, mas agora está esvaziada (e, portanto, liberou a memória que ocupava). Isto pode ser útil em Rscripts maiores, para desocupar memória de processamento.

Mais que NULL é a remoção da variável do ambiente. Observe o Environment e faça:

rm(vetor)

para verificar que a variável desaparece.

Lidando com variável qualitativa

Este arquivo é pequeno e podemos ler todas as linhas da coluna Metodo. Mas e se o arquivo fosse maior? Já vimos que isto se resolve com

metodos <- readRDS("metodos.rds")
unique(metodos$Metodo)
[1] Tabelinha    Preservativo Pílula       Outro       
Levels: Preservativo Tabelinha Pílula Outro

Temos, portanto, 4 métodos na coluna metodos$Metodo. É bom verificar com a função unique porque em variáveis contendo textos é comum haver erro na digitação dos dados. Podemos verificar quantas ocorrências de cada:

table(metodos$Metodo)

Preservativo    Tabelinha       Pílula        Outro 
          19           22           14            5 

Existe uma outra função, summary, em determinadas situações equivalente

summary(metodos$Metodo)
Preservativo    Tabelinha       Pílula        Outro 
          19           22           14            5 

São equivalentes porque tivemos o cuidado de transformar metodos$Metodo em fator. Caso esta coluna fosse chr, o comportamento de summary seria assim:

metodos$Metodo <- as.character(metodos$Metodo)
summary(metodos$Metodo)
   Length     Class      Mode 
       60 character character 

Caso isto aconteça com alguma variável sua, é só arrumar convertendo em fator com is.factor como descrevemos acima.

calculando porcentagens

Caso prefira ver as contagens em porcentagem, em vez de números absolutos, faça:

contagem <- table(metodos$Metodo) 
contagem/sum(contagem)*100

       Outro       Pílula Preservativo    Tabelinha 
    8.333333    23.333333    31.666667    36.666667 


Entenda o código:

Note que a variável contagem, criada com a função table é uma tabela:

is.table(contagem)
[1] TRUE

Já tínhamos visto o comando summary(metodos$Metodo) que devolvia as contagens do número de ocorrências de cada categoria da coluna Metodo dentro da metodos. O operador <- é o operador de atribuição e, então,

contagem <- summary(metodos$Metodo)

em vez de ecoar na tela, cria uma variável chamada contagem para armazenar o resultado de summary. Esta contagem tem os 4 valores, correspondendo às ocorrências de Tabelinha, Preservativo, Pílula e Outro

A função sum (soma) totaliza os valores da variável contagem. O comando contagem/sum(contagem)*100, portanto, pega cada valor de contagem, divide por sum(contagem) e multiplica por 100 para transformar em porcentagem. Como existem 4 valores em contagem a operação é feita 4 vezes e a saída traz os 4 resultados convertidos (lembre-se da operação “em lote” que foi feita para a tabuada do 3).


Um gráfico do tipo pie (torta) ou, como gostamos mais, pizza, formalmente conhecido como gráfico de setores, é obtido com:

tabela <- table(metodos$Metodo)
pie(tabela, main="Anticoncepcionais")

Passar um table para a função pie é equivalente a passar uma lista de valores e seus rótulos (labels). Produz o mesmo resultado:

pie(c(22,14,19,5), 
    labels=c("Tabelinha", "Pilula", "Preservativo", "Outro"), 
    main="Anticoncepcionais")

diferindo, apenas, pela ordem em que passamos cada uma das categorias.


A função pie pode receber outros valores além dos números, nomes das fatias e título para o gráfico.

Para acessar a documentação desta ou de qualquer outra função R use o operador ‘?’. Por exemplo, experimente na Console do RStudio:

?pie

e observe a aba Help com sua documentação.

Quer ver algo divertido?

pie(c(Sky = 78, 
      "Sunny side of pyramid" = 17, 
      "Shady side of pyramid" = 5), 
    init.angle = 315, 
    col = c("deepskyblue", "yellow", "yellow3"), 
    border = FALSE)


O gráfico dos métodos anticoncepcionais terá exatamente a mesma aparência se o apresentarmos em porcentagens. Aqui são apenas 4 fatias, e eu poderia trocar os valores de fatias por suas respectivas porcentagens. No entanto, não é necessário todo o trabalho; podemos criar os vetores fatias e nomes com comandos do R e tornar esta sequência de comandos mais fácil de ajustar para outras tabelas. Experimente:

# fatias recebem os números da tabela
fatias <- as.vector(contagem)
# transforma em porcentagem
fatias <- fatias/sum(fatias)*100
# nomes recebem os nomes das colunas da tabela
nomes <- names(contagem)
pie(fatias, labels=nomes, main="Métodos utilizados")


Repare o uso de um comentário: tudo que escrever após # não é executado.

A variável fatias recebe os números 5, 14, 19 e 22. Então fatias é sobrescrita com as próprias porcentagens (frequências relativas) correspondentes a cada uma das categorias. A função names retorna os nomes, respectivamente, associados. A função pie já é nossa conhecida.


Lidando com variável quantitativa

Neste exemplo podemos explorar a idade dos indivíduos. Sendo variável numérica, podemos usar funções que envolvem cálculos e, assim, ter medidas de localização e de dispersão.

Para variáveis numéricas, table e summary têm comportamentos diferentes:

Com table obtemos:

t <- table(metodos$Idade)
print(t)

  14   15   16   17   18 19.5 
   4   15   22   10    8    1 

Significando que existem 4 valores 14, 15 valores 15, 22 valores 16, e assim por diante, até o valor que adicionamos, com 1 ocorrência de 19.5.

Enquanto summary:

t <- summary(metodos$Idade)
print(t)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  14.00   15.00   16.00   16.11   17.00   19.50 

fornece quartis, mediana, média e desvio-padrão da mesma variável.

Como metodos$Idade é numérica, podemos computar estes valores separadamente:

  • Média aritmética:
mean(metodos$Idade)
[1] 16.10833
  • Variância:
var(metodos$Idade)
[1] 1.43298
  • Desvio-padrão assim:
sd(metodos$Idade)
[1] 1.197072

ou assim:

var(metodos$Idade)**0.5
[1] 1.197072


O operador ** é potência (elevar a 0.5 equivale à raiz quadrada) Também pode ser usado como ^ com resultado idêntico:

var(metodos$Idade)^0.5
[1] 1.197072


  • Mediana:
median(metodos$Idade)
[1] 16
  • Quartis:
quantile(metodos$Idade, probs=seq(0, 1, 0.25))
  0%  25%  50%  75% 100% 
14.0 15.0 16.0 17.0 19.5 
  • Intervalo interquartílico assim:
quartil <- quantile(metodos$Idade, probs=seq(0,1,0.25))
cat("IIQ: ",quartil[4]-quartil[2], sep="")
IIQ: 2

ou usando a função IQR:

iiq <- IQR(metodos$Idade)
cat("IIQ: ",iiq, sep="")
IIQ: 2
  • e amplitude dada por:
quartil <- quantile(metodos$Idade, probs=seq(0,1,0.25))
cat("A: ",quartil[5]-quartil[1], sep="")
A: 5.5

ou usando a função range:

a <- range(metodos$Idade)
cat("A: ",a[2]-a[1], sep="")
A: 5.5


Duas observações:

  • A função seq cria uma sequência para as probabilidades, neste caso seq(0,1,0.25) iniciando com o valor 0, terminando em 1, com passo de 0.25: cria, portanto, os valores 0, 0.25, 0.5, 0.75 e 1.0 que correspondem aos quartis desejados.

  • A função que computa os quartis é quantile, não é quartile. Esta função não é para computar apenas quartis, mas qualquer quantil; é só alterar a função seq de forma adequada. Por exemplo:

quantile(metodos$Idade, probs=seq(0, 1, 0.1))
  0%  10%  20%  30%  40%  50%  60%  70%  80%  90% 100% 
14.0 15.0 15.0 15.0 16.0 16.0 16.0 17.0 17.0 18.0 19.5 
fornece as divisões de 10% em 10%.


Podemos, ainda, produzir gráficos. Dois dos mais conhecidos são o histograma:

hist(metodos$Idade)

e o boxplot:

boxplot(metodos$Idade)

Uma forma melhor e mais sofisticada é converter as idades em densidade de probabilidade e usar um density plot:

densidade <- density(metodos$Idade)
plot(densidade)


Todas estas funcões gráficas podem receber parâmetros adicionais, incluindo títulos, rótulos para os eixos x e y, controlar as escalas, alterar as cores, etc.

Por exemplo:

plot(densidade, 
     main="Distribuição de probabilidades", 
     xlab="Idade dos respondentes", 
     xlim=c(13,20), ylab="Densidade", ylim=c(0,0.4), 
     col="#BA8DB4", lwd=3)

obtendo-se:

Para descobrir o que são os parâmetros usados e outros mais, comece por

? plot

Há um link na documentação que o leva aos parâmetros. É o mesmo que usar

?par


O density plot mostra uma distribuição unimodal. Define-se a moda, aproximadamente, como a posição do pico da curva de densidade de probabilidades, dada por:

densidade$x[which.max(densidade$y)]
[1] 15.95746

É possível acrescentar linhas ao gráfico. Experimente colocar as de média, mediana e moda, assim:

media <- mean(metodos$Idade)
mediana <- median(metodos$Idade)
densidade <- density(metodos$Idade)
moda <- densidade$x[which.max(densidade$y)]
plot(densidade, main="Distribuição de probabilidades", xlab="Idade dos respondentes", xlim=c(13,20), ylab="Densidade", ylim=c(0,0.4), col="#BA8DB4", lwd=3)
abline(v=media, lty=2)
abline(v=mediana, lty=3)
abline(v=moda, lty=4)

Quer adicionar uma legenda? Explore a documentação:

?legend


Um exemplo (ao meu gosto):

media <- mean(metodos$Idade)
mediana <- median(metodos$Idade)
densidade <- density(metodos$Idade)
moda <- densidade$x[which.max(densidade$y)]
plot(densidade, 
     main="Distribuição de probabilidades", 
     xlab="Idade dos respondentes", xlim=c(13,20), 
     ylab="Densidade", ylim=c(0,0.4), 
     col="#BA8DB4", lwd=3)
y2 <- densidade$y[which(abs(densidade$x-media) == min(abs(densidade$x-media)))]
lines(x=c(media,media), y=c(0,y2), lty=2)
y2 <- densidade$y[which(abs(densidade$x-mediana) == min(abs(densidade$x-mediana)))]
lines(x=c(mediana,mediana), y=c(0,y2), lty=3)
y2 <- densidade$y[which(abs(densidade$x-moda) == min(abs(densidade$x-moda)))]
lines(x=c(moda,moda), y=c(0,y2), lty=4)
legend ("topright",
        c("FDP", "média", "mediana", "moda"),
        lty=c(1,2,3,4),
        lwd=c(3,1,1,1),
        col=c("#BA8DB4","black","black","black"),
        cex=0.8,
        box.lwd=0, bg="transparent"        
       )


A moda apresentada aqui é conhecida como “moda contínua”. No entanto, a coluna metodos$Idade deste exemplo (exceto pelo 19.5 que inserimos) é dada em números inteiros. É, portanto, possível computar a “moda discreta” (pode haver mais de uma moda discreta em um mesmo conjunto de dados). O seguinte código a fornece:

# funcao para moda discreta
modadiscreta <- function(x)
{
  w <- table(x) 
  return(w[max(w)==w])
}

modad <- modadiscreta(metodos$Idade)
modas <- names(modad)
freqs <- as.vector(modad)
cat ("Moda(s) discreta(s) amostral(is): ",modas," com ",freqs[1]," ocorrencia(s)\n")
n <- sum(!is.na(metodos$Idade)) 
cat("Numero de observacoes validas =",n, "\n")
nm <- sum(is.na(metodos$Idade)) 
cat("Numero de observacoes faltantes =",nm, "\n")

que produz:

Moda(s) discreta(s) amostral(is):  16  com  22  ocorrencia(s)
Numero de observacoes validas = 60 
Numero de observacoes faltantes = 0 

Neste exemplo note a declaração da função modadiscreta e como foi chamada a partir do código.


Entrada de dados entre-participantes e intraparticipantes

Considere o seguinte estudo (baseado em Christine Dancey & John Reidy. Estatística sem Matemática para Psicologia. 7 ed., Porto Alegre: Penso, 2019):

Pesquisadores interessados em saber se os cães facilitam ou não as interações sociais entre os adultos realizaram quatro estudos diferentes em que pesquisadores do sexo masculino e feminino caminharam com e sem cachorros. Em dois estudos, o pesquisador abordou pessoas e pediu algum dinheiro, em outro estudo o pesquisador deixou cair algumas moedas para ver se as pessoas ajudariam a pegá-las e, em um estudo final, um pesquisador do sexo masculino abordou mulheres na rua e pediu-lhes números de telefone. Em cada estudo, o pesquisador realizou as tarefas com e sem cães. Em todos os quatro estudos descobriram que os comportamentos de ajuda eram mais frequentes quando o pesquisador tinha um cachorro.

O número de encontros sociais foram os seguintes:

  • Passeando com cão: 9 7 10 12 6 8
  • Passeando sem cão: 4 5 3 6 5 1

Este tipo de estudo pode ter dois delineamentos:

  • se um grupo andou sem os cães, e outro grupo com os cães, define-se um estudo entre-participantes.
  • as mesmas pessoas andaram sem os cães em um momento e com os cães em outro, define-se um estudo intraparticipantes.

entre-participantes

A forma de estruturar este tipo de dado é montar sua planilha em duas colunas, uma para o grupo (com ou sem cão) e outra com o número de encontros. Esta planilha está pronta em cao_entreparticipantes.xlsx.

Como boa prática vamos carregar a planilha, olhar sua estrutura e apresentar as primeiras linhas para vermos se nada estranho aparece.

cao_entre <- readxl::read_excel("cao_entreparticipantes.xlsx")
str(cao_entre)
tibble [12 × 2] (S3: tbl_df/tbl/data.frame)
 $ Cachorro : chr [1:12] "com" "com" "com" "com" ...
 $ Encontros: num [1:12] 9 7 10 12 6 8 4 5 3 6 ...
sapply(cao_entre, typeof)
   Cachorro   Encontros 
"character"    "double" 
print(cao_entre)
# A tibble: 12 × 2
   Cachorro Encontros
   <chr>        <dbl>
 1 com              9
 2 com              7
 3 com             10
 4 com             12
 5 com              6
 6 com              8
 7 sem              4
 8 sem              5
 9 sem              3
10 sem              6
11 sem              5
12 sem              1

Também para termos uma boa ideia dos achados (e ver se não há dados estranhos no arquivo, como aconteceria por erros de digitação), uma estratégia é usar alguma estatística descritiva.

Para ter um sumário descritivo dos dados assim arranjados pode ser:

s <- summary(cao_entre$Encontros)
print(s)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  1.000   4.750   6.000   6.333   8.250  12.000 

Um boxplot, pelo menos, para ver se há outliers estranhos:

boxplot(cao_entre$Encontros)

Não parece haver nada estranho: há um mínimo de 1, máximo de 12, com mediana de 6 e média de 6.3333333, números perfeitamente possíveis para pensar em número de encontros. O boxplot é “bem comportado”.

Para separar os encontros com e sem cachorros:

s <- summary(cao_entre$Encontros[cao_entre$Cachorro=="com"])
print(s)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  6.000   7.250   8.500   8.667   9.750  12.000 

No grupo com cães, mínimo de 6, máximo de 12, com mediana de 8.5 e média de 8.6666667.

s <- summary(cao_entre$Encontros[cao_entre$Cachorro=="sem"])
print(s)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   1.00    3.25    4.50    4.00    5.00    6.00 

No grupo sem cães, mínimo de 1, máximo de 6, com mediana de 4.5 e média de 4.

Ainda sem tratamento estatístico, os números sem cães parecem menores, tanto assim que o boxplot mostra o passeio sem cães com número de encontros menores, assim:

boxplot(cao_entre$Encontros~cao_entre$Cachorro,
        xlab="Tipo de passeio",
        ylab="Encontros")

Note o uso de cao_entre$Encontros~cao_entre$Cachorro, que instrui o boxplot a mostrar o número de encontros de acordo com estar com ou sem cães.

intraparticipantes

Suponha que as mesmas pessoas andaram sem os cães em um momento e com os cães em outro, definindo-se um estudo intraparticipantes.

No delineamento intraparticipantes, dependendo das funções R que for usar o dataframe precisará estar no formato longo (long) ou largo (wide).

A forma wide de estruturar este tipo de dado é montar em duas colunas, uma para cada grupo, como aparece em cao_intraparticipantes.xlsx:

dt_cao_intra <- readxl::read_excel("cao_intraparticipantes.xlsx")
str(dt_cao_intra)
tibble [6 × 2] (S3: tbl_df/tbl/data.frame)
 $ Com_cachorro: num [1:6] 9 7 10 12 6 8
 $ Sem_cachorro: num [1:6] 4 5 3 6 5 1
sapply(dt_cao_intra, typeof)
Com_cachorro Sem_cachorro 
    "double"     "double" 
print(dt_cao_intra)
# A tibble: 6 × 2
  Com_cachorro Sem_cachorro
         <dbl>        <dbl>
1            9            4
2            7            5
3           10            3
4           12            6
5            6            5
6            8            1

A estrutura é bem diferente da anterior. Este arquivo tem colunas chamadas Com_cachorro e Sem_cachorro. Cada linha contém um mesmo indivíduo, submetido às duas situações. Os dois tipos de encontro, portanto, já estão separados.

A estratégia para ter um sumário descritivo dos dados assim arranjados precisa ser adaptada. Por exemplo, pode ser:

summary(dt_cao_intra$Com_cachorro)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  6.000   7.250   8.500   8.667   9.750  12.000 
summary(dt_cao_intra$Sem_cachorro)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   1.00    3.25    4.50    4.00    5.00    6.00 

Além disto, todos os gráficos discutidos acima podem ser adaptados para melhor descrever os estudos aqui apresentados (tente você mesmo).

de wide para long

Há funções estatísticas em R que precisam dos dados em formato long ou wide. Especialmente quando há maior volume de dados, saber transformar de um para outro formato é uma habilidade necessária:

  • o formato do arquivo de dados para análise estatística por meio do Modelo Linear Geral (GLM) é o largo.
  • o formato longo é usado para análises com Modelo Linear Misto Generalizado (GLMM) e Equações de Estimação Generalizadas (GEE).

No formato wide, cada linha do arquivo corresponde a uma unidade experimental distinta, como aparece na planilha cao_intraparticipantes.xlsx:

cao_intra.wide <- readxl::read_excel("cao_intraparticipantes.xlsx")
print(cao_intra.wide)
# A tibble: 6 × 2
  Com_cachorro Sem_cachorro
         <dbl>        <dbl>
1            9            4
2            7            5
3           10            3
4           12            6
5            6            5
6            8            1

Com crédito ao Prof. Koichi Sameshima que nos mostrou como utilizar o pacote tidyr, podemos transformar em long com:

# wide -> long
cao_intra.long <- tidyr::gather(cao_intra.wide,condicao,medida,
                                Sem_cachorro,Com_cachorro)
print(cao_intra.long)
# A tibble: 12 × 2
   condicao     medida
   <chr>         <dbl>
 1 Sem_cachorro      4
 2 Sem_cachorro      5
 3 Sem_cachorro      3
 4 Sem_cachorro      6
 5 Sem_cachorro      5
 6 Sem_cachorro      1
 7 Com_cachorro      9
 8 Com_cachorro      7
 9 Com_cachorro     10
10 Com_cachorro     12
11 Com_cachorro      6
12 Com_cachorro      8

Repare o que gather fez, como entramos com os dados em formato wide, onde informamos as colunas necessárias à conversão, e como demos os nomes das colunas para o arquivo long que foram criadas.

Há alguns problemas com cao_intra.long:

  • o mais grave é termos perdido a informação do participante de quem veio cada um dos dados.
  • um problema estético, pois os nomes das colunas de cao_intra.wide tornaram-se o conteúdo da coluna cao_intra.long$condicao; aqui não é tão ruim, mas pode acontecer do nome da coluna ser muito inadequado.
  • a nova coluna cao_intra.long$condicao deveria ser fator mas está declarada como chr.

Então, antes de converter do wide para o long, vamos modificar nosso R script para incluir uma coluna de identificação. Como usaremos uma sequência numérica, a coluna no arquivo long vai se tornar int, e convém que seja tratada como chr.

Aproveitaremos para arrumar a estética e garantir que está ordenado pelos respondentes, para que todas as participações estejam em linhas sequenciais.

Ao final de todo o trabalho, seria bom guardar em outra planilha o arquivo modificado. Como um bônus, mostramos um uso da library openxlsx.

O código completo é assim (para que você possa adaptar ao seu caso):

# Dados.wide <- readxl::read_excel("NEncontros_Cao_Wide.xlsx")
cao_intra.wide <- readxl::read_excel("cao_intraparticipantes.xlsx")

# adiciona um número de identificacao
cao_intra.wide$ID <- 1:nrow(cao_intra.wide)

# wide -> long
cao_intra.long <- tidyr::gather(cao_intra.wide,condicao,medida,
                                Sem_cachorro,Com_cachorro)
# troca as strings da coluna $condicao
cao_intra.long$condicao <- ifelse(cao_intra.long$condicao=="Sem_cachorro",
                                  "sem cao", 
                                  ifelse(cao_intra.long$condicao=="Com_cachorro",
                                         "com cao",NA))

# coloca os dados em ordem de ID
cao_intra.long <- cao_intra.long[order(cao_intra.long$ID),]

# torna ID em caracter e condicao em fator
cao_intra.long$condicao <- as.factor(cao_intra.long$condicao)
cao_intra.long$condicao <- as.factor(cao_intra.long$condicao)

# salva o resultado final
openxlsx::write.xlsx(cao_intra.long,"cao_intra_long.xlsx")

Para vermos o efeito de cada etapa, você pode experimentar executá-lo linha a linha. Para facilitar vamos executá-lo com print, para explicitar o efeito de cada operação.

Lê a planilha em formato wide:

# Dados.wide <- readxl::read_excel("NEncontros_Cao_Wide.xlsx")
cao_intra.wide <- readxl::read_excel("cao_intraparticipantes.xlsx")
print(cao_intra.wide)
# A tibble: 6 × 2
  Com_cachorro Sem_cachorro
         <dbl>        <dbl>
1            9            4
2            7            5
3           10            3
4           12            6
5            6            5
6            8            1

Adiciona a coluna ID:

# adiciona um número de identificacao
cao_intra.wide$ID <- 1:nrow(cao_intra.wide)
print(cao_intra.wide)
# A tibble: 6 × 3
  Com_cachorro Sem_cachorro    ID
         <dbl>        <dbl> <int>
1            9            4     1
2            7            5     2
3           10            3     3
4           12            6     4
5            6            5     5
6            8            1     6

Transforma de wide para long:

# wide -> long
cao_intra.long <- tidyr::gather(cao_intra.wide,condicao,medida,
                                Sem_cachorro,Com_cachorro)
print(cao_intra.long)
# A tibble: 12 × 3
      ID condicao     medida
   <int> <chr>         <dbl>
 1     1 Sem_cachorro      4
 2     2 Sem_cachorro      5
 3     3 Sem_cachorro      3
 4     4 Sem_cachorro      6
 5     5 Sem_cachorro      5
 6     6 Sem_cachorro      1
 7     1 Com_cachorro      9
 8     2 Com_cachorro      7
 9     3 Com_cachorro     10
10     4 Com_cachorro     12
11     5 Com_cachorro      6
12     6 Com_cachorro      8

Resolve a “estética”, mencionada acima:

# troca as strings da coluna $condicao
cao_intra.long$condicao <- ifelse(cao_intra.long$condicao=="Sem_cachorro",
                             "sem cao", 
ifelse(cao_intra.long$condicao=="Com_cachorro",
                                    "com cao",NA))
print(cao_intra.long)
# A tibble: 12 × 3
      ID condicao medida
   <int> <chr>     <dbl>
 1     1 sem cao       4
 2     2 sem cao       5
 3     3 sem cao       3
 4     4 sem cao       6
 5     5 sem cao       5
 6     6 sem cao       1
 7     1 com cao       9
 8     2 com cao       7
 9     3 com cao      10
10     4 com cao      12
11     5 com cao       6
12     6 com cao       8

Coloca os respondentes em ordem:

# coloca os dados em ordem de ID
cao_intra.long <- cao_intra.long[order(cao_intra.long$ID),]
print(cao_intra.long)
# A tibble: 12 × 3
      ID condicao medida
   <int> <chr>     <dbl>
 1     1 sem cao       4
 2     1 com cao       9
 3     2 sem cao       5
 4     2 com cao       7
 5     3 sem cao       3
 6     3 com cao      10
 7     4 sem cao       6
 8     4 com cao      12
 9     5 sem cao       5
10     5 com cao       6
11     6 sem cao       1
12     6 com cao       8

E finalmente força a coluna de identificação do participante ser do tipo caracter e a condição de andar com ou sem cachorro ser do tipo fator:

# torna ID em caracter e condicao em fator
cao_intra.long$ID <- as.character(cao_intra.long$ID)
cao_intra.long$condicao <- as.factor(cao_intra.long$condicao)
print(cao_intra.long)
# A tibble: 12 × 3
   ID    condicao medida
   <chr> <fct>     <dbl>
 1 1     sem cao       4
 2 1     com cao       9
 3 2     sem cao       5
 4 2     com cao       7
 5 3     sem cao       3
 6 3     com cao      10
 7 4     sem cao       6
 8 4     com cao      12
 9 5     sem cao       5
10 5     com cao       6
11 6     sem cao       1
12 6     com cao       8

de long para wide

Supondo a situação oposta, a função mais importante é tidyr::spread. A sintaxe é a seguinte:

# lendo o arquivo
cao_intra.long <- readxl::read_excel("cao_intra_long.xlsx")

# long -> wide
cao_intra.wide2 <- tidyr::spread(cao_intra.long,
                                 condicao,
                                 medida)

# exibe o _dataframe_ convertido
print(cao_intra.wide2)
# A tibble: 6 × 3
     ID `com cao` `sem cao`
  <dbl>     <dbl>     <dbl>
1     1         9         4
2     2         7         5
3     3        10         3
4     4        12         6
5     5         6         5
6     6         8         1
# salva o resultado final
openxlsx::write.xlsx(cao_intra.wide2,"cao_intra_wide2.xlsx")

Há pequenos problemas a resolver similares aos vistos acima, que pode experimentar por si mesmo.

Boxplot e outlier

Boxplots (conhecidos em português como gráfico de caixa com bigodes) são muito usados para dar uma ideia da distribuição de uma variável quantitativa. Outliers são valores destoantes dos demais, que podem ser definidos na construção de boxplots. Inicialmente caixa é definida pelo intervalo interquartil (distância entre o primeiro e terceiro quartil). É outlier o valor que dista 1.5 vezes esta altura acima do terceiro quartil ou abaixo do primeiro quartil. Os bigodes superior e inferior respectivamente, são os valores mais alto e mais baixo que não são outliers. É possível, ainda, pensar em outliers extremos, distantes 3 vezes ou mais a altura da caixa.

Pare este exemplo, usaremos uma função nossa, eiras::BoxplotJitter (é necessário instalar o pacote eiras para executar este exemplo), apenas porque mostra melhor os outliers pela aplicação da função jitter. Não é o caso no exemplo abaixo, mas mostra outliers extremos, quando ocorrem, como asteriscos.

Observe o que acontece quando criamos um conjunto de dados e tentamos adicionar outliers:

set.seed(7622)
# create values
estaturas <- round(rnorm(30,170,10),0)
# quartis
q <- quantile(estaturas)
print (q)
  0%  25%  50%  75% 100% 
 151  163  166  176  192 
original.min <- min(estaturas)
original.max <- max(estaturas)
invisible(eiras::BoxplotJitter(estaturas, ylab="Estatura (cm)", 
                                ylim=c(original.min-30,
                                       original.max+30)))

Para referência adiante, traçamos como linhas horizontais pontilhadas os valores do mínimo e máximo deste boxplot que guardamos anteriormente:

abline(h=original.min,lty=2,col="gray")
abline(h=original.max,lty=2,col="gray")

Pela regra que conhecemos, será um outlier qualquer valor que fique acima ou abaixo de 1.5 vezes a altura da caixa deste gráfico (acima de 3.0 vezes são outliers extremos). A altura da caixa é o intervalo interquartílico (q[4]-q[2]=13). Assim, tentamos criar 3 outliers com indivíduos de estatura acima de q[4]+1.5*(q[4]-q[2])=195.5. Em R podemos implementar assim:

# tentar cria 3 ouliers acima do intervalo interquartilico
iq <- q[4]-q[2]
# junta os valores 
novas.estaturas <- round(runif(3,q[4]+1.5*iq,q[4]+3.0*iq),0)
cat("Adicionando três valores:",novas.estaturas,"\n")
Adicionando três valores: 214 197 210 
estaturas <- c(estaturas,novas.estaturas)
# boxplot
invisible(eiras::BoxplotJitter(estaturas, ylab="Estatura (cm)", 
                                ylim=c(original.min-30,
                                       original.max+30)))
abline(h=c(original.min,original.max),lty=2,col="gray")

# quartis
q2 <- quantile(estaturas)
print (q2)
  0%  25%  50%  75% 100% 
 151  163  172  180  214 

Surpreendentemente, apenas dois dos três novos valores apareceram como outliers. Outlier é um conceito relativo. O três valores incluídos alteraram a distribuição, tanto que os valores da mediana, terceiro quartil (75%) e máximo (100%) foram alterados.

A terceira estatura (197 cm) é o que deu a altura do “bigode” superior do outlier: para se construir o bigode superior de um boxplot encontra-se o valor que está a 1,5 vezes a altura da caixa, que neste exemplo é q2[4]+1.5*(q2[4]-q2[2])=205.5 e, então, traça-se o bigode superior na altura do primeiro valor abaixo deste. Oo procedimento é similar para traçar o bigode inferior com as direções trocadas. Assim, quando não existem outliers, os bigodes superior e inferior correspondem, respectivamente, aos valores máximo e mínimo; caso contrário, precisam ser encontrados.

É difícil prever o que acontecerá com os outliers ao incluirmos dados (o mesmo vale para quando alguém tenta retirar dados). Por exemplo, vamos tentar incluir 4 outliers extremos inferiores, portanto abaixo de q2[2]-3.0*(q2[4]-q2[2])=112:

# tentar cria 4 ouliers abaixo do intervalo interquartilico
iq <- q2[4]-q2[2]
# junta os valores 
novas.estaturas <- round(runif(4,q[2]-6.0*iq,q[2]-3.0*iq),0)
cat("Adicionando quatro valores:",novas.estaturas,"\n")
Adicionando quatro valores: 64 108 73 107 
estaturas <- c(estaturas,novas.estaturas)
# boxplot
invisible(eiras::BoxplotJitter(estaturas, ylab="Estatura (cm)"))
abline(h=c(original.min,original.max),lty=2, col="gray")

# quartis
q3 <- quantile(estaturas)
print(q3)
  0%  25%  50%  75% 100% 
  64  160  166  180  214 

Somente dois dos quatro novos valores tornam-se outliers extremos. Os outros dois apareceram como um outliers comuns. Mais ainda, repare que um dos outliers superiores desapareceu.


Este exercício mostra o porquê de não ser recomendado que um pesquisador retire dados que considera extremos e sejam inconvenientes para suas conclusões. Imagine que tenhamos as seguintes medidas de massa corpórea:

massa <- c(65, 70, 64, 63, 80, 61, 95, 63)
boxplot(massa, ylab="Massa corporea (kg)", ylim=c(60,100))

O indivíduo com 95 kg está “atrapalhando” suas conclusões sobre a dieta que implementou? É um outlier, atípico, que não deve ter seguido direito o tratamento e, portanto, este pesquisador resolve eliminá-lo da amostra, obtendo:

massa <- c(65, 70, 64, 63, 80, 61, 63)
boxplot(massa, ylab="Massa corporea (kg)", ylim=c(60,100))

Lamentavelmente, um indivíduo de 80 kg agora é o outlier e o tenaz pesquisador resolve, também removê-lo. Agora encontra:

massa <- c(65, 70, 64, 63, 61, 63)
boxplot(massa, ylab="Massa corporea (kg)", ylim=c(60,100))

Que estranho! Mantendo-se fiel aos seus princípios éticos e sua sabedoria, pois tem certeza que a dieta funciona bem… fora com quem ainda pesa 70kg!

massa <- c(65, 64, 63, 61, 63)
boxplot(massa, ylab="Massa corporea (kg)", ylim=c(60,100))

Como todo pesquisador aprendeu que não pode ser tendencioso e, embora seja favorável às suas conclusões, depois de tantas eliminações, não aceitará tipo algum de outlier contaminando seus dados. Assim, removerá o paciente de 61 kg, obtendo…

massa <- c(65, 64, 63, 63)
boxplot(massa, ylab="Massa corporea (kg)", ylim=c(60,100))

… finalmente sua amostra pura, embora monótona e inconclusiva, posto que todos têm praticamente o mesmo peso final, tendo sacrificado metade dos dados que possuía.

Apêndice: friendlydemo.R

Cerca de 10% dos homens e e menos que 1% das mulheres são daltônicos. Portanto, encorajamos o uso de gráficos em preto, cinza e branco ou gradações de uma mesma cor. Caso queira usar cores, sugerimos a função eiras::FriendlyColor, a qual aplica uma paleta de cores distinguível para quase todas as pessoas.

Para demonstrar seu funcionamento, este código exibe todas as cores da função eiras::FriendlyColor:

# exibe as 46 cores disponíveis em eiras::FriendlyColor.R
index <- 1
plot(NA, xlim=c(0,10), ylim=c(0,7), 
     xlab="", ylab="", axes=FALSE)
for (x in 1:8)
{
  for (y in 1:6)
  {
    if (index > 46) {next}

    points(x, 7-y, pch=21, cex=5, col="black", bg=eiras::FriendlyColor(index))
    cortext <- "black"
    if (index >= 25 & index <= 36)
    {
      cortext <- "white"
    }
    text(x, 7-y, index, col=cortext)
    index <- index+1
  }
}

Para uma aproximação, apliquei esta imagem em Coblis (https://www.color-blindness.com/coblis-color-blindness-simulator/), simulando as cores tal como vistas por pessoas daltônicas:

Referência
Visão normal
Monocromacia de cones azuis
Cones verdes e vermelhos disfuncionais,
1/100.000 indivíduos.
Acromatopsia
Visão monocromática,
1/30.000 indivíduos.
Protanomalia
Deficiência em cones vermelhos,
1% dos homens, 0.1% das mulheres.
Deuteranomalia
Deficiência em cones verdes,
6% dos homens, 0.4% das mulheres.
Tritanomalia
Deficiência em cones azuis,
0.1% dos homens e mulheres.
Protanopia
Falta de cones vermelhos,
1% dos homens.
Deuteranopia
Falta de cones verdes,
1% dos homens.
Tritanopia
Falta de cones azuis,
menos que 0.1% dos homens e mulheres.

Experimente, também, para ver as cores pré-definidas em R:

eiras::Colors(mcex=0.7)

$captured
    number                             name   r   g   b     hex
1        1                 white or grey100 255 255 255 #ffffff
2        2                        aliceblue 240 248 255 #f0f8ff
3        3                     antiquewhite 250 235 215 #faebd7
4        4                    antiquewhite1 255 239 219 #ffefdb
5        5                    antiquewhite2 238 223 204 #eedfcc
6        6                    antiquewhite3 205 192 176 #cdc0b0
7        7                    antiquewhite4 139 131 120 #8b8378
8        8                       aquamarine 127 255 212 #7fffd4
9        9                      aquamarine1 127 255 212 #7fffd4
10      10                      aquamarine2 118 238 198 #76eec6
11      11                      aquamarine3 102 205 170 #66cdaa
12      12                      aquamarine4  69 139 116 #458b74
13      13                            azure 240 255 255 #f0ffff
14      14                           azure1 240 255 255 #f0ffff
15      15                           azure2 224 238 238 #e0eeee
16      16                           azure3 193 205 205 #c1cdcd
17      17                           azure4 131 139 139 #838b8b
18      18                            beige 245 245 220 #f5f5dc
19      19                           bisque 255 228 196 #ffe4c4
20      20                          bisque1 255 228 196 #ffe4c4
21      21                          bisque2 238 213 183 #eed5b7
22      22                          bisque3 205 183 158 #cdb79e
23      23                          bisque4 139 125 107 #8b7d6b
24      24                   black or grey0   0   0   0 #000000
25      25                   blanchedalmond 255 235 205 #ffebcd
26      26                             blue   0   0 255 #0000ff
27      27                            blue1   0   0 255 #0000ff
28      28                            blue2   0   0 238 #0000ee
29      29                            blue3   0   0 205 #0000cd
30      30                            blue4   0   0 139 #00008b
31      31                       blueviolet 138  43 226 #8a2be2
32      32                            brown 165  42  42 #a52a2a
33      33                           brown1 255  64  64 #ff4040
34      34                           brown2 238  59  59 #ee3b3b
35      35                           brown3 205  51  51 #cd3333
36      36                           brown4 139  35  35 #8b2323
37      37                        burlywood 222 184 135 #deb887
38      38                       burlywood1 255 211 155 #ffd39b
39      39                       burlywood2 238 197 145 #eec591
40      40                       burlywood3 205 170 125 #cdaa7d
41      41                       burlywood4 139 115  85 #8b7355
42      42                        cadetblue  95 158 160 #5f9ea0
43      43                       cadetblue1 152 245 255 #98f5ff
44      44                       cadetblue2 142 229 238 #8ee5ee
45      45                       cadetblue3 122 197 205 #7ac5cd
46      46                       cadetblue4  83 134 139 #53868b
47      47                       chartreuse 127 255   0 #7fff00
48      48                      chartreuse1 127 255   0 #7fff00
49      49                      chartreuse2 118 238   0 #76ee00
50      50                      chartreuse3 102 205   0 #66cd00
51      51                      chartreuse4  69 139   0 #458b00
52      52                        chocolate 210 105  30 #d2691e
53      53                       chocolate1 255 127  36 #ff7f24
54      54                       chocolate2 238 118  33 #ee7621
55      55                       chocolate3 205 102  29 #cd661d
56      56                       chocolate4 139  69  19 #8b4513
57      57                            coral 255 127  80 #ff7f50
58      58                           coral1 255 114  86 #ff7256
59      59                           coral2 238 106  80 #ee6a50
60      60                           coral3 205  91  69 #cd5b45
61      61                           coral4 139  62  47 #8b3e2f
62      62                   cornflowerblue 100 149 237 #6495ed
63      63                         cornsilk 255 248 220 #fff8dc
64      64                        cornsilk1 255 248 220 #fff8dc
65      65                        cornsilk2 238 232 205 #eee8cd
66      66                        cornsilk3 205 200 177 #cdc8b1
67      67                        cornsilk4 139 136 120 #8b8878
68      68                             cyan   0 255 255 #00ffff
69      69                            cyan1   0 255 255 #00ffff
70      70                            cyan2   0 238 238 #00eeee
71      71                            cyan3   0 205 205 #00cdcd
72      72                            cyan4   0 139 139 #008b8b
73      73                         darkblue   0   0 139 #00008b
74      74                         darkcyan   0 139 139 #008b8b
75      75                    darkgoldenrod 184 134  11 #b8860b
76      76                   darkgoldenrod1 255 185  15 #ffb90f
77      77                   darkgoldenrod2 238 173  14 #eead0e
78      78                   darkgoldenrod3 205 149  12 #cd950c
79      79                   darkgoldenrod4 139 101   8 #8b6508
80      80             darkgray or darkgrey 169 169 169 #a9a9a9
81      81                        darkgreen   0 100   0 #006400
83      83                        darkkhaki 189 183 107 #bdb76b
84      84                      darkmagenta 139   0 139 #8b008b
85      85                   darkolivegreen  85 107  47 #556b2f
86      86                  darkolivegreen1 202 255 112 #caff70
87      87                  darkolivegreen2 188 238 104 #bcee68
88      88                  darkolivegreen3 162 205  90 #a2cd5a
89      89                  darkolivegreen4 110 139  61 #6e8b3d
90      90                       darkorange 255 140   0 #ff8c00
91      91                      darkorange1 255 127   0 #ff7f00
92      92                      darkorange2 238 118   0 #ee7600
93      93                      darkorange3 205 102   0 #cd6600
94      94                      darkorange4 139  69   0 #8b4500
95      95                       darkorchid 153  50 204 #9932cc
96      96                      darkorchid1 191  62 255 #bf3eff
97      97                      darkorchid2 178  58 238 #b23aee
98      98                      darkorchid3 154  50 205 #9a32cd
99      99                      darkorchid4 104  34 139 #68228b
100    100                          darkred 139   0   0 #8b0000
101    101                       darksalmon 233 150 122 #e9967a
102    102                     darkseagreen 143 188 143 #8fbc8f
103    103                    darkseagreen1 193 255 193 #c1ffc1
104    104                    darkseagreen2 180 238 180 #b4eeb4
105    105                    darkseagreen3 155 205 155 #9bcd9b
106    106                    darkseagreen4 105 139 105 #698b69
107    107                    darkslateblue  72  61 139 #483d8b
108    108   darkslategray or darkslategrey  47  79  79 #2f4f4f
109    109                   darkslategray1 151 255 255 #97ffff
110    110                   darkslategray2 141 238 238 #8deeee
111    111                   darkslategray3 121 205 205 #79cdcd
112    112                   darkslategray4  82 139 139 #528b8b
114    114                    darkturquoise   0 206 209 #00ced1
115    115                       darkviolet 148   0 211 #9400d3
116    116                         deeppink 255  20 147 #ff1493
117    117                        deeppink1 255  20 147 #ff1493
118    118                        deeppink2 238  18 137 #ee1289
119    119                        deeppink3 205  16 118 #cd1076
120    120                        deeppink4 139  10  80 #8b0a50
121    121                      deepskyblue   0 191 255 #00bfff
122    122                     deepskyblue1   0 191 255 #00bfff
123    123                     deepskyblue2   0 178 238 #00b2ee
124    124                     deepskyblue3   0 154 205 #009acd
125    125                     deepskyblue4   0 104 139 #00688b
126    126     dimgray or dimgrey or grey41 105 105 105 #696969
128    128                       dodgerblue  30 144 255 #1e90ff
129    129                      dodgerblue1  30 144 255 #1e90ff
130    130                      dodgerblue2  28 134 238 #1c86ee
131    131                      dodgerblue3  24 116 205 #1874cd
132    132                      dodgerblue4  16  78 139 #104e8b
133    133                        firebrick 178  34  34 #b22222
134    134                       firebrick1 255  48  48 #ff3030
135    135                       firebrick2 238  44  44 #ee2c2c
136    136                       firebrick3 205  38  38 #cd2626
137    137                       firebrick4 139  26  26 #8b1a1a
138    138                      floralwhite 255 250 240 #fffaf0
139    139                      forestgreen  34 139  34 #228b22
140    140                        gainsboro 220 220 220 #dcdcdc
141    141                       ghostwhite 248 248 255 #f8f8ff
142    142                             gold 255 215   0 #ffd700
143    143                            gold1 255 215   0 #ffd700
144    144                            gold2 238 201   0 #eec900
145    145                            gold3 205 173   0 #cdad00
146    146                            gold4 139 117   0 #8b7500
147    147                        goldenrod 218 165  32 #daa520
148    148                       goldenrod1 255 193  37 #ffc125
149    149                       goldenrod2 238 180  34 #eeb422
150    150                       goldenrod3 205 155  29 #cd9b1d
151    151                       goldenrod4 139 105  20 #8b6914
152    152                     gray or grey 190 190 190 #bebebe
153    153                   gray0 or grey0   0   0   0 #000000
154    154                   gray1 or grey1   3   3   3 #030303
155    155                   gray2 or grey2   5   5   5 #050505
156    156                   gray3 or grey3   8   8   8 #080808
157    157                   gray4 or grey4  10  10  10 #0a0a0a
158    158                   gray5 or grey5  13  13  13 #0d0d0d
159    159                   gray6 or grey6  15  15  15 #0f0f0f
160    160                   gray7 or grey7  18  18  18 #121212
161    161                   gray8 or grey8  20  20  20 #141414
162    162                   gray9 or grey9  23  23  23 #171717
163    163                 gray10 or grey10  26  26  26 #1a1a1a
164    164                 gray11 or grey11  28  28  28 #1c1c1c
165    165                 gray12 or grey12  31  31  31 #1f1f1f
166    166                 gray13 or grey13  33  33  33 #212121
167    167                 gray14 or grey14  36  36  36 #242424
168    168                 gray15 or grey15  38  38  38 #262626
169    169                 gray16 or grey16  41  41  41 #292929
170    170                 gray17 or grey17  43  43  43 #2b2b2b
171    171                 gray18 or grey18  46  46  46 #2e2e2e
172    172                 gray19 or grey19  48  48  48 #303030
173    173                 gray20 or grey20  51  51  51 #333333
174    174                 gray21 or grey21  54  54  54 #363636
175    175                 gray22 or grey22  56  56  56 #383838
176    176                 gray23 or grey23  59  59  59 #3b3b3b
177    177                 gray24 or grey24  61  61  61 #3d3d3d
178    178                 gray25 or grey25  64  64  64 #404040
179    179                 gray26 or grey26  66  66  66 #424242
180    180                 gray27 or grey27  69  69  69 #454545
181    181                 gray28 or grey28  71  71  71 #474747
182    182                 gray29 or grey29  74  74  74 #4a4a4a
183    183                 gray30 or grey30  77  77  77 #4d4d4d
184    184                 gray31 or grey31  79  79  79 #4f4f4f
185    185                 gray32 or grey32  82  82  82 #525252
186    186                 gray33 or grey33  84  84  84 #545454
187    187                 gray34 or grey34  87  87  87 #575757
188    188                 gray35 or grey35  89  89  89 #595959
189    189                 gray36 or grey36  92  92  92 #5c5c5c
190    190                 gray37 or grey37  94  94  94 #5e5e5e
191    191                 gray38 or grey38  97  97  97 #616161
192    192                 gray39 or grey39  99  99  99 #636363
193    193                 gray40 or grey40 102 102 102 #666666
194    194      gray41 or dimgrey or grey41 105 105 105 #696969
195    195                 gray42 or grey42 107 107 107 #6b6b6b
196    196                 gray43 or grey43 110 110 110 #6e6e6e
197    197                 gray44 or grey44 112 112 112 #707070
198    198                 gray45 or grey45 115 115 115 #737373
199    199                 gray46 or grey46 117 117 117 #757575
200    200                 gray47 or grey47 120 120 120 #787878
201    201                 gray48 or grey48 122 122 122 #7a7a7a
202    202                 gray49 or grey49 125 125 125 #7d7d7d
203    203                 gray50 or grey50 127 127 127 #7f7f7f
204    204                 gray51 or grey51 130 130 130 #828282
205    205                 gray52 or grey52 133 133 133 #858585
206    206                 gray53 or grey53 135 135 135 #878787
207    207                 gray54 or grey54 138 138 138 #8a8a8a
208    208                 gray55 or grey55 140 140 140 #8c8c8c
209    209                 gray56 or grey56 143 143 143 #8f8f8f
210    210                 gray57 or grey57 145 145 145 #919191
211    211                 gray58 or grey58 148 148 148 #949494
212    212                 gray59 or grey59 150 150 150 #969696
213    213                 gray60 or grey60 153 153 153 #999999
214    214                 gray61 or grey61 156 156 156 #9c9c9c
215    215                 gray62 or grey62 158 158 158 #9e9e9e
216    216                 gray63 or grey63 161 161 161 #a1a1a1
217    217                 gray64 or grey64 163 163 163 #a3a3a3
218    218                 gray65 or grey65 166 166 166 #a6a6a6
219    219                 gray66 or grey66 168 168 168 #a8a8a8
220    220                 gray67 or grey67 171 171 171 #ababab
221    221                 gray68 or grey68 173 173 173 #adadad
222    222                 gray69 or grey69 176 176 176 #b0b0b0
223    223                 gray70 or grey70 179 179 179 #b3b3b3
224    224                 gray71 or grey71 181 181 181 #b5b5b5
225    225                 gray72 or grey72 184 184 184 #b8b8b8
226    226                 gray73 or grey73 186 186 186 #bababa
227    227                 gray74 or grey74 189 189 189 #bdbdbd
228    228                 gray75 or grey75 191 191 191 #bfbfbf
229    229                 gray76 or grey76 194 194 194 #c2c2c2
230    230                 gray77 or grey77 196 196 196 #c4c4c4
231    231                 gray78 or grey78 199 199 199 #c7c7c7
232    232                 gray79 or grey79 201 201 201 #c9c9c9
233    233                 gray80 or grey80 204 204 204 #cccccc
234    234                 gray81 or grey81 207 207 207 #cfcfcf
235    235                 gray82 or grey82 209 209 209 #d1d1d1
236    236                 gray83 or grey83 212 212 212 #d4d4d4
237    237                 gray84 or grey84 214 214 214 #d6d6d6
238    238                 gray85 or grey85 217 217 217 #d9d9d9
239    239                 gray86 or grey86 219 219 219 #dbdbdb
240    240                 gray87 or grey87 222 222 222 #dedede
241    241                 gray88 or grey88 224 224 224 #e0e0e0
242    242                 gray89 or grey89 227 227 227 #e3e3e3
243    243                 gray90 or grey90 229 229 229 #e5e5e5
244    244                 gray91 or grey91 232 232 232 #e8e8e8
245    245                 gray92 or grey92 235 235 235 #ebebeb
246    246                 gray93 or grey93 237 237 237 #ededed
247    247                 gray94 or grey94 240 240 240 #f0f0f0
248    248                 gray95 or grey95 242 242 242 #f2f2f2
249    249                 gray96 or grey96 245 245 245 #f5f5f5
250    250                 gray97 or grey97 247 247 247 #f7f7f7
251    251                 gray98 or grey98 250 250 250 #fafafa
252    252                 gray99 or grey99 252 252 252 #fcfcfc
253    253               gray100 or grey100 255 255 255 #ffffff
254    254                            green   0 255   0 #00ff00
255    255                           green1   0 255   0 #00ff00
256    256                           green2   0 238   0 #00ee00
257    257                           green3   0 205   0 #00cd00
258    258                           green4   0 139   0 #008b00
259    259                      greenyellow 173 255  47 #adff2f
362    362                         honeydew 240 255 240 #f0fff0
363    363                        honeydew1 240 255 240 #f0fff0
364    364                        honeydew2 224 238 224 #e0eee0
365    365                        honeydew3 193 205 193 #c1cdc1
366    366                        honeydew4 131 139 131 #838b83
367    367                          hotpink 255 105 180 #ff69b4
368    368                         hotpink1 255 110 180 #ff6eb4
369    369                         hotpink2 238 106 167 #ee6aa7
370    370                         hotpink3 205  96 144 #cd6090
371    371                         hotpink4 139  58  98 #8b3a62
372    372                        indianred 205  92  92 #cd5c5c
373    373                       indianred1 255 106 106 #ff6a6a
374    374                       indianred2 238  99  99 #ee6363
375    375                       indianred3 205  85  85 #cd5555
376    376                       indianred4 139  58  58 #8b3a3a
377    377                            ivory 255 255 240 #fffff0
378    378                           ivory1 255 255 240 #fffff0
379    379                           ivory2 238 238 224 #eeeee0
380    380                           ivory3 205 205 193 #cdcdc1
381    381                           ivory4 139 139 131 #8b8b83
382    382                            khaki 240 230 140 #f0e68c
383    383                           khaki1 255 246 143 #fff68f
384    384                           khaki2 238 230 133 #eee685
385    385                           khaki3 205 198 115 #cdc673
386    386                           khaki4 139 134  78 #8b864e
387    387                         lavender 230 230 250 #e6e6fa
388    388                    lavenderblush 255 240 245 #fff0f5
389    389                   lavenderblush1 255 240 245 #fff0f5
390    390                   lavenderblush2 238 224 229 #eee0e5
391    391                   lavenderblush3 205 193 197 #cdc1c5
392    392                   lavenderblush4 139 131 134 #8b8386
393    393                        lawngreen 124 252   0 #7cfc00
394    394                     lemonchiffon 255 250 205 #fffacd
395    395                    lemonchiffon1 255 250 205 #fffacd
396    396                    lemonchiffon2 238 233 191 #eee9bf
397    397                    lemonchiffon3 205 201 165 #cdc9a5
398    398                    lemonchiffon4 139 137 112 #8b8970
399    399                        lightblue 173 216 230 #add8e6
400    400                       lightblue1 191 239 255 #bfefff
401    401                       lightblue2 178 223 238 #b2dfee
402    402                       lightblue3 154 192 205 #9ac0cd
403    403                       lightblue4 104 131 139 #68838b
404    404                       lightcoral 240 128 128 #f08080
405    405                        lightcyan 224 255 255 #e0ffff
406    406                       lightcyan1 224 255 255 #e0ffff
407    407                       lightcyan2 209 238 238 #d1eeee
408    408                       lightcyan3 180 205 205 #b4cdcd
409    409                       lightcyan4 122 139 139 #7a8b8b
410    410                   lightgoldenrod 238 221 130 #eedd82
411    411                  lightgoldenrod1 255 236 139 #ffec8b
412    412                  lightgoldenrod2 238 220 130 #eedc82
413    413                  lightgoldenrod3 205 190 112 #cdbe70
414    414                  lightgoldenrod4 139 129  76 #8b814c
415    415             lightgoldenrodyellow 250 250 210 #fafad2
416    416           lightgray or lightgrey 211 211 211 #d3d3d3
417    417                       lightgreen 144 238 144 #90ee90
419    419                        lightpink 255 182 193 #ffb6c1
420    420                       lightpink1 255 174 185 #ffaeb9
421    421                       lightpink2 238 162 173 #eea2ad
422    422                       lightpink3 205 140 149 #cd8c95
423    423                       lightpink4 139  95 101 #8b5f65
424    424                      lightsalmon 255 160 122 #ffa07a
425    425                     lightsalmon1 255 160 122 #ffa07a
426    426                     lightsalmon2 238 149 114 #ee9572
427    427                     lightsalmon3 205 129  98 #cd8162
428    428                     lightsalmon4 139  87  66 #8b5742
429    429                    lightseagreen  32 178 170 #20b2aa
430    430                     lightskyblue 135 206 250 #87cefa
431    431                    lightskyblue1 176 226 255 #b0e2ff
432    432                    lightskyblue2 164 211 238 #a4d3ee
433    433                    lightskyblue3 141 182 205 #8db6cd
434    434                    lightskyblue4  96 123 139 #607b8b
435    435                   lightslateblue 132 112 255 #8470ff
436    436 lightslategray or lightslategrey 119 136 153 #778899
438    438                   lightsteelblue 176 196 222 #b0c4de
439    439                  lightsteelblue1 202 225 255 #cae1ff
440    440                  lightsteelblue2 188 210 238 #bcd2ee
441    441                  lightsteelblue3 162 181 205 #a2b5cd
442    442                  lightsteelblue4 110 123 139 #6e7b8b
443    443                      lightyellow 255 255 224 #ffffe0
444    444                     lightyellow1 255 255 224 #ffffe0
445    445                     lightyellow2 238 238 209 #eeeed1
446    446                     lightyellow3 205 205 180 #cdcdb4
447    447                     lightyellow4 139 139 122 #8b8b7a
448    448                        limegreen  50 205  50 #32cd32
449    449                            linen 250 240 230 #faf0e6
450    450                          magenta 255   0 255 #ff00ff
451    451                         magenta1 255   0 255 #ff00ff
452    452                         magenta2 238   0 238 #ee00ee
453    453                         magenta3 205   0 205 #cd00cd
454    454                         magenta4 139   0 139 #8b008b
455    455                           maroon 176  48  96 #b03060
456    456                          maroon1 255  52 179 #ff34b3
457    457                          maroon2 238  48 167 #ee30a7
458    458                          maroon3 205  41 144 #cd2990
459    459                          maroon4 139  28  98 #8b1c62
460    460                 mediumaquamarine 102 205 170 #66cdaa
461    461                       mediumblue   0   0 205 #0000cd
462    462                     mediumorchid 186  85 211 #ba55d3
463    463                    mediumorchid1 224 102 255 #e066ff
464    464                    mediumorchid2 209  95 238 #d15fee
465    465                    mediumorchid3 180  82 205 #b452cd
466    466                    mediumorchid4 122  55 139 #7a378b
467    467                     mediumpurple 147 112 219 #9370db
468    468                    mediumpurple1 171 130 255 #ab82ff
469    469                    mediumpurple2 159 121 238 #9f79ee
470    470                    mediumpurple3 137 104 205 #8968cd
471    471                    mediumpurple4  93  71 139 #5d478b
472    472                   mediumseagreen  60 179 113 #3cb371
473    473                  mediumslateblue 123 104 238 #7b68ee
474    474                mediumspringgreen   0 250 154 #00fa9a
475    475                  mediumturquoise  72 209 204 #48d1cc
476    476                  mediumvioletred 199  21 133 #c71585
477    477                     midnightblue  25  25 112 #191970
478    478                        mintcream 245 255 250 #f5fffa
479    479                        mistyrose 255 228 225 #ffe4e1
480    480                       mistyrose1 255 228 225 #ffe4e1
481    481                       mistyrose2 238 213 210 #eed5d2
482    482                       mistyrose3 205 183 181 #cdb7b5
483    483                       mistyrose4 139 125 123 #8b7d7b
484    484                         moccasin 255 228 181 #ffe4b5
485    485                      navajowhite 255 222 173 #ffdead
486    486                     navajowhite1 255 222 173 #ffdead
487    487                     navajowhite2 238 207 161 #eecfa1
488    488                     navajowhite3 205 179 139 #cdb38b
489    489                     navajowhite4 139 121  94 #8b795e
490    490                             navy   0   0 128 #000080
491    491                         navyblue   0   0 128 #000080
492    492                          oldlace 253 245 230 #fdf5e6
493    493                        olivedrab 107 142  35 #6b8e23
494    494                       olivedrab1 192 255  62 #c0ff3e
495    495                       olivedrab2 179 238  58 #b3ee3a
496    496                       olivedrab3 154 205  50 #9acd32
497    497                       olivedrab4 105 139  34 #698b22
498    498                           orange 255 165   0 #ffa500
499    499                          orange1 255 165   0 #ffa500
500    500                          orange2 238 154   0 #ee9a00
501    501                          orange3 205 133   0 #cd8500
502    502                          orange4 139  90   0 #8b5a00
503    503                        orangered 255  69   0 #ff4500
504    504                       orangered1 255  69   0 #ff4500
505    505                       orangered2 238  64   0 #ee4000
506    506                       orangered3 205  55   0 #cd3700
507    507                       orangered4 139  37   0 #8b2500
508    508                           orchid 218 112 214 #da70d6
509    509                          orchid1 255 131 250 #ff83fa
510    510                          orchid2 238 122 233 #ee7ae9
511    511                          orchid3 205 105 201 #cd69c9
512    512                          orchid4 139  71 137 #8b4789
513    513                    palegoldenrod 238 232 170 #eee8aa
514    514                        palegreen 152 251 152 #98fb98
515    515                       palegreen1 154 255 154 #9aff9a
516    516                       palegreen2 144 238 144 #90ee90
517    517                       palegreen3 124 205 124 #7ccd7c
518    518                       palegreen4  84 139  84 #548b54
519    519                    paleturquoise 175 238 238 #afeeee
520    520                   paleturquoise1 187 255 255 #bbffff
521    521                   paleturquoise2 174 238 238 #aeeeee
522    522                   paleturquoise3 150 205 205 #96cdcd
523    523                   paleturquoise4 102 139 139 #668b8b
524    524                    palevioletred 219 112 147 #db7093
525    525                   palevioletred1 255 130 171 #ff82ab
526    526                   palevioletred2 238 121 159 #ee799f
527    527                   palevioletred3 205 104 137 #cd6889
528    528                   palevioletred4 139  71  93 #8b475d
529    529                       papayawhip 255 239 213 #ffefd5
530    530                        peachpuff 255 218 185 #ffdab9
531    531                       peachpuff1 255 218 185 #ffdab9
532    532                       peachpuff2 238 203 173 #eecbad
533    533                       peachpuff3 205 175 149 #cdaf95
534    534                       peachpuff4 139 119 101 #8b7765
535    535                             peru 205 133  63 #cd853f
536    536                             pink 255 192 203 #ffc0cb
537    537                            pink1 255 181 197 #ffb5c5
538    538                            pink2 238 169 184 #eea9b8
539    539                            pink3 205 145 158 #cd919e
540    540                            pink4 139  99 108 #8b636c
541    541                             plum 221 160 221 #dda0dd
542    542                            plum1 255 187 255 #ffbbff
543    543                            plum2 238 174 238 #eeaeee
544    544                            plum3 205 150 205 #cd96cd
545    545                            plum4 139 102 139 #8b668b
546    546                       powderblue 176 224 230 #b0e0e6
547    547                           purple 160  32 240 #a020f0
548    548                          purple1 155  48 255 #9b30ff
549    549                          purple2 145  44 238 #912cee
550    550                          purple3 125  38 205 #7d26cd
551    551                          purple4  85  26 139 #551a8b
552    552                              red 255   0   0 #ff0000
553    553                             red1 255   0   0 #ff0000
554    554                             red2 238   0   0 #ee0000
555    555                             red3 205   0   0 #cd0000
556    556                             red4 139   0   0 #8b0000
557    557                        rosybrown 188 143 143 #bc8f8f
558    558                       rosybrown1 255 193 193 #ffc1c1
559    559                       rosybrown2 238 180 180 #eeb4b4
560    560                       rosybrown3 205 155 155 #cd9b9b
561    561                       rosybrown4 139 105 105 #8b6969
562    562                        royalblue  65 105 225 #4169e1
563    563                       royalblue1  72 118 255 #4876ff
564    564                       royalblue2  67 110 238 #436eee
565    565                       royalblue3  58  95 205 #3a5fcd
566    566                       royalblue4  39  64 139 #27408b
567    567                      saddlebrown 139  69  19 #8b4513
568    568                           salmon 250 128 114 #fa8072
569    569                          salmon1 255 140 105 #ff8c69
570    570                          salmon2 238 130  98 #ee8262
571    571                          salmon3 205 112  84 #cd7054
572    572                          salmon4 139  76  57 #8b4c39
573    573                       sandybrown 244 164  96 #f4a460
574    574                         seagreen  46 139  87 #2e8b57
575    575                        seagreen1  84 255 159 #54ff9f
576    576                        seagreen2  78 238 148 #4eee94
577    577                        seagreen3  67 205 128 #43cd80
578    578                        seagreen4  46 139  87 #2e8b57
579    579                         seashell 255 245 238 #fff5ee
580    580                        seashell1 255 245 238 #fff5ee
581    581                        seashell2 238 229 222 #eee5de
582    582                        seashell3 205 197 191 #cdc5bf
583    583                        seashell4 139 134 130 #8b8682
584    584                           sienna 160  82  45 #a0522d
585    585                          sienna1 255 130  71 #ff8247
586    586                          sienna2 238 121  66 #ee7942
587    587                          sienna3 205 104  57 #cd6839
588    588                          sienna4 139  71  38 #8b4726
589    589                          skyblue 135 206 235 #87ceeb
590    590                         skyblue1 135 206 255 #87ceff
591    591                         skyblue2 126 192 238 #7ec0ee
592    592                         skyblue3 108 166 205 #6ca6cd
593    593                         skyblue4  74 112 139 #4a708b
594    594                        slateblue 106  90 205 #6a5acd
595    595                       slateblue1 131 111 255 #836fff
596    596                       slateblue2 122 103 238 #7a67ee
597    597                       slateblue3 105  89 205 #6959cd
598    598                       slateblue4  71  60 139 #473c8b
599    599           slategray or slategrey 112 128 144 #708090
600    600                       slategray1 198 226 255 #c6e2ff
601    601                       slategray2 185 211 238 #b9d3ee
602    602                       slategray3 159 182 205 #9fb6cd
603    603                       slategray4 108 123 139 #6c7b8b
605    605                             snow 255 250 250 #fffafa
606    606                            snow1 255 250 250 #fffafa
607    607                            snow2 238 233 233 #eee9e9
608    608                            snow3 205 201 201 #cdc9c9
609    609                            snow4 139 137 137 #8b8989
610    610                      springgreen   0 255 127 #00ff7f
611    611                     springgreen1   0 255 127 #00ff7f
612    612                     springgreen2   0 238 118 #00ee76
613    613                     springgreen3   0 205 102 #00cd66
614    614                     springgreen4   0 139  69 #008b45
615    615                        steelblue  70 130 180 #4682b4
616    616                       steelblue1  99 184 255 #63b8ff
617    617                       steelblue2  92 172 238 #5cacee
618    618                       steelblue3  79 148 205 #4f94cd
619    619                       steelblue4  54 100 139 #36648b
620    620                              tan 210 180 140 #d2b48c
621    621                             tan1 255 165  79 #ffa54f
622    622                             tan2 238 154  73 #ee9a49
623    623                             tan3 205 133  63 #cd853f
624    624                             tan4 139  90  43 #8b5a2b
625    625                          thistle 216 191 216 #d8bfd8
626    626                         thistle1 255 225 255 #ffe1ff
627    627                         thistle2 238 210 238 #eed2ee
628    628                         thistle3 205 181 205 #cdb5cd
629    629                         thistle4 139 123 139 #8b7b8b
630    630                           tomato 255  99  71 #ff6347
631    631                          tomato1 255  99  71 #ff6347
632    632                          tomato2 238  92  66 #ee5c42
633    633                          tomato3 205  79  57 #cd4f39
634    634                          tomato4 139  54  38 #8b3626
635    635                        turquoise  64 224 208 #40e0d0
636    636                       turquoise1   0 245 255 #00f5ff
637    637                       turquoise2   0 229 238 #00e5ee
638    638                       turquoise3   0 197 205 #00c5cd
639    639                       turquoise4   0 134 139 #00868b
640    640                           violet 238 130 238 #ee82ee
641    641                        violetred 208  32 144 #d02090
642    642                       violetred1 255  62 150 #ff3e96
643    643                       violetred2 238  58 140 #ee3a8c
644    644                       violetred3 205  50 120 #cd3278
645    645                       violetred4 139  34  82 #8b2252
646    646                            wheat 245 222 179 #f5deb3
647    647                           wheat1 255 231 186 #ffe7ba
648    648                           wheat2 238 216 174 #eed8ae
649    649                           wheat3 205 186 150 #cdba96
650    650                           wheat4 139 126 102 #8b7e66
651    651             whitesmoke or grey96 245 245 245 #f5f5f5
652    652                           yellow 255 255   0 #ffff00
653    653                          yellow1 255 255   0 #ffff00
654    654                          yellow2 238 238   0 #eeee00
655    655                          yellow3 205 205   0 #cdcd00
656    656                          yellow4 139 139   0 #8b8b00
657    657                      yellowgreen 154 205  50 #9acd32
                                   family
1   black, gray & white (and some slates)
2                                    blue
3   black, gray & white (and some slates)
4   black, gray & white (and some slates)
5   black, gray & white (and some slates)
6   black, gray & white (and some slates)
7   black, gray & white (and some slates)
8                                   green
9                                   green
10                                  green
11                                  green
12                                  green
13                                   blue
14                                   blue
15                                   blue
16                                   blue
17                                   blue
18                        orange & yellow
19                        orange & yellow
20                        orange & yellow
21                        orange & yellow
22                        orange & yellow
23                        orange & yellow
24  black, gray & white (and some slates)
25                            brown & red
26                                   blue
27                                   blue
28                                   blue
29                                   blue
30                                   blue
31           blue | violet, purple & pink
32                            brown & red
33                            brown & red
34                            brown & red
35                            brown & red
36                            brown & red
37                        orange & yellow
38                        orange & yellow
39                        orange & yellow
40                        orange & yellow
41                        orange & yellow
42                                   blue
43                                   blue
44                                   blue
45                                   blue
46                                   blue
47                                  green
48                                  green
49                                  green
50                                  green
51                                  green
52                            brown & red
53                            brown & red
54                            brown & red
55                            brown & red
56                            brown & red
57                            brown & red
58                            brown & red
59                            brown & red
60                            brown & red
61                            brown & red
62                                   blue
63                        orange & yellow
64                        orange & yellow
65                        orange & yellow
66                        orange & yellow
67                        orange & yellow
68                                   blue
69                                   blue
70                                   blue
71                                   blue
72                                   blue
73                                   blue
74                                   blue
75                        orange & yellow
76                        orange & yellow
77                        orange & yellow
78                        orange & yellow
79                        orange & yellow
80  black, gray & white (and some slates)
81                                  green
83                        orange & yellow
84                  violet, purple & pink
85                          green | green
86                          green | green
87                          green | green
88                          green | green
89                          green | green
90                        orange & yellow
91                        orange & yellow
92                        orange & yellow
93                        orange & yellow
94                        orange & yellow
95                  violet, purple & pink
96                  violet, purple & pink
97                  violet, purple & pink
98                  violet, purple & pink
99                  violet, purple & pink
100                           brown & red
101                           brown & red
102                                 green
103                                 green
104                                 green
105                                 green
106                                 green
107                                  blue
108 black, gray & white (and some slates)
109 black, gray & white (and some slates)
110 black, gray & white (and some slates)
111 black, gray & white (and some slates)
112 black, gray & white (and some slates)
114                                  blue
115                 violet, purple & pink
116                 violet, purple & pink
117                 violet, purple & pink
118                 violet, purple & pink
119                 violet, purple & pink
120                 violet, purple & pink
121                                  blue
122                                  blue
123                                  blue
124                                  blue
125                                  blue
126 black, gray & white (and some slates)
128                                  blue
129                                  blue
130                                  blue
131                                  blue
132                                  blue
133                           brown & red
134                           brown & red
135                           brown & red
136                           brown & red
137                           brown & red
138 black, gray & white (and some slates)
139                                 green
140 black, gray & white (and some slates)
141 black, gray & white (and some slates)
142                       orange & yellow
143                       orange & yellow
144                       orange & yellow
145                       orange & yellow
146                       orange & yellow
147                       orange & yellow
148                       orange & yellow
149                       orange & yellow
150                       orange & yellow
151                       orange & yellow
152 black, gray & white (and some slates)
153 black, gray & white (and some slates)
154 black, gray & white (and some slates)
155 black, gray & white (and some slates)
156 black, gray & white (and some slates)
157 black, gray & white (and some slates)
158 black, gray & white (and some slates)
159 black, gray & white (and some slates)
160 black, gray & white (and some slates)
161 black, gray & white (and some slates)
162 black, gray & white (and some slates)
163 black, gray & white (and some slates)
164 black, gray & white (and some slates)
165 black, gray & white (and some slates)
166 black, gray & white (and some slates)
167 black, gray & white (and some slates)
168 black, gray & white (and some slates)
169 black, gray & white (and some slates)
170 black, gray & white (and some slates)
171 black, gray & white (and some slates)
172 black, gray & white (and some slates)
173 black, gray & white (and some slates)
174 black, gray & white (and some slates)
175 black, gray & white (and some slates)
176 black, gray & white (and some slates)
177 black, gray & white (and some slates)
178 black, gray & white (and some slates)
179 black, gray & white (and some slates)
180 black, gray & white (and some slates)
181 black, gray & white (and some slates)
182 black, gray & white (and some slates)
183 black, gray & white (and some slates)
184 black, gray & white (and some slates)
185 black, gray & white (and some slates)
186 black, gray & white (and some slates)
187 black, gray & white (and some slates)
188 black, gray & white (and some slates)
189 black, gray & white (and some slates)
190 black, gray & white (and some slates)
191 black, gray & white (and some slates)
192 black, gray & white (and some slates)
193 black, gray & white (and some slates)
194 black, gray & white (and some slates)
195 black, gray & white (and some slates)
196 black, gray & white (and some slates)
197 black, gray & white (and some slates)
198 black, gray & white (and some slates)
199 black, gray & white (and some slates)
200 black, gray & white (and some slates)
201 black, gray & white (and some slates)
202 black, gray & white (and some slates)
203 black, gray & white (and some slates)
204 black, gray & white (and some slates)
205 black, gray & white (and some slates)
206 black, gray & white (and some slates)
207 black, gray & white (and some slates)
208 black, gray & white (and some slates)
209 black, gray & white (and some slates)
210 black, gray & white (and some slates)
211 black, gray & white (and some slates)
212 black, gray & white (and some slates)
213 black, gray & white (and some slates)
214 black, gray & white (and some slates)
215 black, gray & white (and some slates)
216 black, gray & white (and some slates)
217 black, gray & white (and some slates)
218 black, gray & white (and some slates)
219 black, gray & white (and some slates)
220 black, gray & white (and some slates)
221 black, gray & white (and some slates)
222 black, gray & white (and some slates)
223 black, gray & white (and some slates)
224 black, gray & white (and some slates)
225 black, gray & white (and some slates)
226 black, gray & white (and some slates)
227 black, gray & white (and some slates)
228 black, gray & white (and some slates)
229 black, gray & white (and some slates)
230 black, gray & white (and some slates)
231 black, gray & white (and some slates)
232 black, gray & white (and some slates)
233 black, gray & white (and some slates)
234 black, gray & white (and some slates)
235 black, gray & white (and some slates)
236 black, gray & white (and some slates)
237 black, gray & white (and some slates)
238 black, gray & white (and some slates)
239 black, gray & white (and some slates)
240 black, gray & white (and some slates)
241 black, gray & white (and some slates)
242 black, gray & white (and some slates)
243 black, gray & white (and some slates)
244 black, gray & white (and some slates)
245 black, gray & white (and some slates)
246 black, gray & white (and some slates)
247 black, gray & white (and some slates)
248 black, gray & white (and some slates)
249 black, gray & white (and some slates)
250 black, gray & white (and some slates)
251 black, gray & white (and some slates)
252 black, gray & white (and some slates)
253 black, gray & white (and some slates)
254                                 green
255                                 green
256                                 green
257                                 green
258                                 green
259               green | orange & yellow
362                                 green
363                                 green
364                                 green
365                                 green
366                                 green
367                 violet, purple & pink
368                 violet, purple & pink
369                 violet, purple & pink
370                 violet, purple & pink
371                 violet, purple & pink
372                           brown & red
373                           brown & red
374                           brown & red
375                           brown & red
376                           brown & red
377                       orange & yellow
378                       orange & yellow
379                       orange & yellow
380                       orange & yellow
381                       orange & yellow
382                       orange & yellow
383                       orange & yellow
384                       orange & yellow
385                       orange & yellow
386                       orange & yellow
387                                  blue
388                                  blue
389                                  blue
390                                  blue
391                                  blue
392                                  blue
393                                 green
394                       orange & yellow
395                       orange & yellow
396                       orange & yellow
397                       orange & yellow
398                       orange & yellow
399                                  blue
400                                  blue
401                                  blue
402                                  blue
403                                  blue
404                           brown & red
405                                  blue
406                                  blue
407                                  blue
408                                  blue
409                                  blue
410                       orange & yellow
411                       orange & yellow
412                       orange & yellow
413                       orange & yellow
414                       orange & yellow
415     orange & yellow | orange & yellow
416 black, gray & white (and some slates)
417                                 green
419                 violet, purple & pink
420                 violet, purple & pink
421                 violet, purple & pink
422                 violet, purple & pink
423                 violet, purple & pink
424                           brown & red
425                           brown & red
426                           brown & red
427                           brown & red
428                           brown & red
429                                 green
430                                  blue
431                                  blue
432                                  blue
433                                  blue
434                                  blue
435                                  blue
436 black, gray & white (and some slates)
438                                  blue
439                                  blue
440                                  blue
441                                  blue
442                                  blue
443                       orange & yellow
444                       orange & yellow
445                       orange & yellow
446                       orange & yellow
447                       orange & yellow
448                                 green
449                       orange & yellow
450                 violet, purple & pink
451                 violet, purple & pink
452                 violet, purple & pink
453                 violet, purple & pink
454                 violet, purple & pink
455                 violet, purple & pink
456                 violet, purple & pink
457                 violet, purple & pink
458                 violet, purple & pink
459                 violet, purple & pink
460                                 green
461                                  blue
462                 violet, purple & pink
463                 violet, purple & pink
464                 violet, purple & pink
465                 violet, purple & pink
466                 violet, purple & pink
467                 violet, purple & pink
468                 violet, purple & pink
469                 violet, purple & pink
470                 violet, purple & pink
471                 violet, purple & pink
472                                 green
473                                  blue
474                                 green
475                                  blue
476   violet, purple & pink | brown & red
477                                  blue
478                                  blue
479                 violet, purple & pink
480                 violet, purple & pink
481                 violet, purple & pink
482                 violet, purple & pink
483                 violet, purple & pink
484                       orange & yellow
485 black, gray & white (and some slates)
486 black, gray & white (and some slates)
487 black, gray & white (and some slates)
488 black, gray & white (and some slates)
489 black, gray & white (and some slates)
490                                  blue
491                           blue | blue
492                       orange & yellow
493                                 green
494                                 green
495                                 green
496                                 green
497                                 green
498                       orange & yellow
499                       orange & yellow
500                       orange & yellow
501                       orange & yellow
502                       orange & yellow
503         brown & red | orange & yellow
504         brown & red | orange & yellow
505         brown & red | orange & yellow
506         brown & red | orange & yellow
507         brown & red | orange & yellow
508                 violet, purple & pink
509                 violet, purple & pink
510                 violet, purple & pink
511                 violet, purple & pink
512                 violet, purple & pink
513                       orange & yellow
514                                 green
515                                 green
516                                 green
517                                 green
518                                 green
519                                  blue
520                                  blue
521                                  blue
522                                  blue
523                                  blue
524   violet, purple & pink | brown & red
525   violet, purple & pink | brown & red
526   violet, purple & pink | brown & red
527   violet, purple & pink | brown & red
528   violet, purple & pink | brown & red
529                       orange & yellow
530                       orange & yellow
531                       orange & yellow
532                       orange & yellow
533                       orange & yellow
534                       orange & yellow
535                           brown & red
536                 violet, purple & pink
537                 violet, purple & pink
538                 violet, purple & pink
539                 violet, purple & pink
540                 violet, purple & pink
541                 violet, purple & pink
542                 violet, purple & pink
543                 violet, purple & pink
544                 violet, purple & pink
545                 violet, purple & pink
546                                  blue
547                 violet, purple & pink
548                 violet, purple & pink
549                 violet, purple & pink
550                 violet, purple & pink
551                 violet, purple & pink
552                           brown & red
553                           brown & red
554                           brown & red
555                           brown & red
556                           brown & red
557                           brown & red
558                           brown & red
559                           brown & red
560                           brown & red
561                           brown & red
562                                  blue
563                                  blue
564                                  blue
565                                  blue
566                                  blue
567                           brown & red
568                           brown & red
569                           brown & red
570                           brown & red
571                           brown & red
572                           brown & red
573                           brown & red
574                                 green
575                                 green
576                                 green
577                                 green
578                                 green
579 black, gray & white (and some slates)
580 black, gray & white (and some slates)
581 black, gray & white (and some slates)
582 black, gray & white (and some slates)
583 black, gray & white (and some slates)
584                           brown & red
585                           brown & red
586                           brown & red
587                           brown & red
588                           brown & red
589                                  blue
590                                  blue
591                                  blue
592                                  blue
593                                  blue
594                                  blue
595                                  blue
596                                  blue
597                                  blue
598                                  blue
599 black, gray & white (and some slates)
600 black, gray & white (and some slates)
601 black, gray & white (and some slates)
602 black, gray & white (and some slates)
603 black, gray & white (and some slates)
605 black, gray & white (and some slates)
606 black, gray & white (and some slates)
607 black, gray & white (and some slates)
608 black, gray & white (and some slates)
609 black, gray & white (and some slates)
610                                 green
611                                 green
612                                 green
613                                 green
614                                 green
615                                  blue
616                                  blue
617                                  blue
618                                  blue
619                                  blue
620                       orange & yellow
621                       orange & yellow
622                       orange & yellow
623                       orange & yellow
624                       orange & yellow
625                 violet, purple & pink
626                 violet, purple & pink
627                 violet, purple & pink
628                 violet, purple & pink
629                 violet, purple & pink
630                           brown & red
631                           brown & red
632                           brown & red
633                           brown & red
634                           brown & red
635                                  blue
636                                  blue
637                                  blue
638                                  blue
639                                  blue
640                 violet, purple & pink
641   violet, purple & pink | brown & red
642   violet, purple & pink | brown & red
643   violet, purple & pink | brown & red
644   violet, purple & pink | brown & red
645   violet, purple & pink | brown & red
646                       orange & yellow
647                       orange & yellow
648                       orange & yellow
649                       orange & yellow
650                       orange & yellow
651 black, gray & white (and some slates)
652                       orange & yellow
653                       orange & yellow
654                       orange & yellow
655                       orange & yellow
656                       orange & yellow
657               green | orange & yellow