Capítulo 5 Importando dados

Até agora, temos usado conjuntos de dados já disponibilizados como objetos do R. Entretanto, cientistas de dados raramente têm a mesma sorte e, geralmente, precisam importar dados no R de arquivos, bancos de dados ou outras fontes. Atualmente, uma das maneiras mais comuns de armazenar e compartilhar dados para análise é por meio de planilhas eletrônicas. Uma planilha armazena dados em linhas e colunas. Basicamente, é uma versão em arquivo de um data frame. Ao salvar essa tabela em um arquivo, é necessário definir como novas linhas e colunas começam e terminam. Isso, por sua vez, define as células nas quais os valores individuais são armazenados.

Ao criar planilhas com arquivos de texto, como aqueles criados com um editor de texto simples, uma nova linha é definida com uma quebra de linha (enter) e as colunas são separadas com um caractere especial predefinido. Os caracteres mais comuns são vírgulas (,), ponto e vírgula (;), espaço () e tabulação (um número predeterminado de espaços ou \t). Aqui está um exemplo da aparência de um arquivo separado por vírgula se o abrirmos com um editor de texto básico:

A primeira linha contém os nomes das colunas. Nos referimos a isso como o cabeçalho (header em inglês). Quando lemos dados de uma planilha, é importante saber se o arquivo tem um cabeçalho ou não. A maioria das funções de leitura assume que existe um cabeçalho. Para descobrir se o arquivo possui ou não cabeçalho, deve-se abrir o arquivo antes de tentar lê-lo. Isso pode ser feito usando um editor de texto ou usando o RStudio. No RStudio, podemos fazer isso abrindo o arquivo no editor ou navegando até o local do arquivo, clicando duas vezes sobre o arquivo e pressionando View File.

No entanto, nem todos os arquivos de planilha estão em formato de texto. O Google Sheets, por exemplo, permite acessar planilhas por um navegador. Outro exemplo é o formato proprietário usado pelo Microsoft Excel. Planilhas nesse formato não podem ser exibidas em um editor de texto. Apesar disso, devido à popularidade do Microsoft Excel, esse formato é amplamente utilizado.

Começamos este capítulo descrevendo as diferenças entre arquivos de texto (ASCII), Unicode e binários, mostrando como essa diferença afeta a maneira como importamos tais arquivos. Em seguida, explicamos os conceitos de caminhos de arquivos e diretórios de trabalho, que são essenciais para entender como importar dados de maneira eficaz. Então, apresentamos os pacotes readr e readxl, além das funções disponíveis para importar planilhas para o R. Por fim, oferecemos algumas recomendações sobre como armazenar e organizar dados em arquivos. Desafios mais complexos, no entanto, como extrair dados de páginas da Web ou documentos em PDF, serão discutidos na seção do livro Wrangling data.

5.1 Caminhos e diretório de trabalho

A primeira etapa na importação de dados de uma planilha é localizar o arquivo que contém os dados. Embora não seja muito recomendável, você pode usar uma abordagem semelhante à usada para abrir arquivos no Microsoft Excel, clicando no menu “Arquivo” (File) no RStudio, clicando em “Importar conjunto de dados” (Import Dataset) e depois navegando por pastas até encontrar o arquivo. Queremos que vocês estejam aptos a desenvolver códigos em vez de apenas selecionar e clicar em pastas. As chaves e os conceitos que precisaremos para aprender a fazer isso são descritos em detalhes na seção “Ferramentas de produtividade” deste livro. Aqui, fornecemos uma visão geral do básico.

O principal desafio desta primeira etapa é permitir que as funções R de importação saibam onde procurar o arquivo que contém os dados. A maneira mais fácil de fazer isso é ter uma cópia do arquivo na pasta em que as funções de importação pesquisam por padrão. Depois disso, basta fornecer o nome do arquivo para a função de importação.

O pacote dslabs inclui uma planilha contendo dados de assassinatos nos EUA. A localização desse arquivo não é óbvia, mas as seguintes linhas de código copiam o arquivo para a pasta que R procura por padrão. Abaixo, explicamos como essas linhas funcionam.

filename <- "murders.csv"
dir <- system.file("extdata", package = "dslabs")
fullpath <- file.path(dir, filename)
file.copy(fullpath, "murders.csv")

Esse código não importa os dados para o R, apenas copia um arquivo. Entretanto, uma vez que o arquivo é copiado, podemos importar os dados com apenas uma linha de código. Aqui, usamos a função read_csv do pacote readr, que faz parte do tidyverse.

library(tidyverse)
dat <- read_csv(filename)

Os dados são importados e armazenados em dat. O restante desta seção define alguns conceitos importantes e fornece uma visão geral de como escrevemos códigos para que o R possa encontrar os arquivos que queremos importar. O capítulo ?? fornece mais detalhes sobre esse tópico.

5.1.1 Sistema de arquivos

Você pode pensar no sistema de arquivos do seu computador como uma série de pastas aninhadas, cada uma contendo outras pastas e arquivos. Cientistas de dados se referem às pastas como diretórios. Nos referimos à pasta que contém todas as outras pastas como o diretório raiz (root). O diretório em que estamos localizados é chamado de diretório de trabalho (working directory). Portanto, o diretório de trabalho muda à medida que você percorre as pastas: pense nele como sua localização atual.

5.1.2 Caminhos relativos e absolutos

O endereço ou caminho (path em inglês) de um arquivo é uma lista de nomes de diretórios que podem ser considerados instruções sobre qual ordem de pastas clicar para localizar o arquivo. Se essas instruções forem para encontrar o arquivo no diretório raiz, vamos nos referir a elas como caminho absoluto (ou caminho completo). Se as instruções forem para encontrar o arquivo com base no diretório atual, nós referimos a isso como caminho relativo. A seção ?? oferece mais detalhes sobre esse tópico.

Para ver um exemplo de caminho completo em seu sistema, digite o seguinte:

system.file(package = "dslabs")

Os caracteres separados por barras são os nomes dos diretórios. A primeira barra representa o diretório raiz e sabemos que esse é um caminho completo porque começa com uma barra. Se o primeiro nome do diretório aparecer sem uma barra, R assume que o caminho é relativo. Podemos usar a função list.files para ver exemplos de rotas relativas:

dir <- system.file(package = "dslabs")
list.files(path = dir)
#>  [1] "data"        "DESCRIPTION" "extdata"     "help"       
#>  [5] "html"        "INDEX"       "Meta"        "NAMESPACE"  
#>  [9] "R"           "script"

Esses caminhos relativos nos fornecem a localização dos arquivos ou diretórios se iniciarmos no diretório com o caminho completo. Por exemplo, o caminho completo para o diretório help no exemplo acima, é: /Library/Frameworks/R.framework/Versions/3.5/Resources/library/dslabs/help.

Nota: você provavelmente não fará muito uso da função system.file no trabalho diário em análise de dados. Apresentamos isso nesta seção para facilitar o compartilhamento de planilhas, uma vez que as incluímos no pacote dslabs. Raramente você terá o luxo de dados sendo incluído nos pacotes já instalados. No entanto, você geralmente precisa navegar por caminhos completos e relativos e importar dados no formato de planilha.

5.1.3 O diretório de trabalho

Fortemente recomendamos escrever apenas caminhos relativos no seu código, pois os caminhos completos são exclusivos para o seu computador e você deve desejar que seu código seja portátil. Você pode obter o caminho completo do diretório de trabalho usando a função getwd:

wd <- getwd()

Se você precisar alterar o diretório de trabalho, poderá usar a função setwd ou pode alterá-lo através do RStudio, clicando em “Sessão” (Session).

5.1.4 Gerando nomes de caminhos

Outro exemplo de como obter um caminho completo sem escrever explicitamente foi apresentado acima quando criamos o objeto fullpath desta maneira:

filename <- "murders.csv"
dir <- system.file("extdata", package = "dslabs")
fullpath <- file.path(dir, filename)

A função system.file fornece o caminho completo da pasta que contém todos os arquivos e diretórios relevantes para o pacote especificado pelo argumento package. Ao procurar diretórios em dir, descobrimos que extdata contém o arquivo que queremos:

dir <- system.file(package = "dslabs")
filename %in% list.files(file.path(dir, "extdata"))
#> [1] TRUE

A função system.file permite que forneçamos um subdiretório como primeiro argumento, assim podemos obter o caminho completo do diretório extdata assim:

dir <- system.file("extdata", package = "dslabs")

A função file.path é usada para combinar os nomes dos diretórios para produzir o caminho completo do arquivo que queremos importar.

fullpath <- file.path(dir, filename)

5.1.5 Copiando arquivos usando caminhos

A última linha do código que utilizamos para copiar o arquivo em nosso diretório inicial usou a função file.copy. Isso requer dois argumentos: o nome do arquivo a ser copiado e o nome a ser usado no novo diretório.

file.copy(fullpath, "murders.csv")
#> [1] TRUE

Se o arquivo for copiado com sucesso, a função file.copy retorna a mensagem TRUE (verdadeiro). Note que estamos dando o mesmo nome ao arquivo, murders.csv, mas poderíamos ter dado qualquer outro nome a ele. Note também que, ao não iniciar a sequência com uma barra, R assume que esse é um caminho relativo e copia o arquivo para o diretório de trabalho.

Você deve poder visualizar o arquivo em seu diretório de trabalho usando:

list.files()

5.2 Os pacotes readr e readxl

Nesta seção, apresentamos as principais funções de importação do tidyverse. Vamos usar o arquivo murders.csv do pacote dslabs como um exemplo. Para simplificar a ilustração, copiaremos o arquivo para nosso diretório de trabalho usando o seguinte código:

filename <- "murders.csv"
dir <- system.file("extdata", package = "dslabs")
fullpath <- file.path(dir, filename)
file.copy(fullpath, "murders.csv")

5.2.1 readr

O pacote readr inclui funções para ler dados de planilhas armazenados em arquivos de texto. readr faz parte do pacote__tidyverse__, ou você pode carregá-lo diretamente assim:

library(readr)

As seguintes funções estão disponíveis para leitura de planilhas:

Função Formato Extensão
read_table valores separados por espaços em branco txt
read_csv valores separados por vírgula csv
read_csv2 valores separados por ponto e vírgula csv
read_tsv valores separados por tabulação tsv
read_delim formato geral de arquivo de texto, você deve definir delimitador txt

Embora a extensão geralmente nos diga que tipo de arquivo é, não há garantia de que eles sempre correspondam. Podemos abrir o arquivo para dar uma olhada ou usar a função read_lines para ver algumas linhas:

read_lines("murders.csv", n_max = 3)
#> [1] "state,abb,region,population,total"
#> [2] "Alabama,AL,South,4779736,135"     
#> [3] "Alaska,AK,West,710231,19"

Isso também mostra que existe um cabeçalho. Agora estamos prontos para ler dados em R. A partir da extensão .csv e da visualização das três primeiras linhas do arquivo, sabemos que precisamos usar read_csv:

dat <- read_csv(filename)
#> 
#> ── Column specification ────────────────────────────────────────────────
#> cols(
#>   state = col_character(),
#>   abb = col_character(),
#>   region = col_character(),
#>   population = col_double(),
#>   total = col_double()
#> )

Observe que recebemos uma mensagem informando que tipos de dados foram usados para cada coluna. Observe também que dat é um tibble, não apenas um data frame. Isso ocorre porque read_csv é um parser (analisador) do tidyverse. Podemos confirmar que os dados foram lidos da seguinte forma:

View(dat)

Por fim, note também que podemos usar o caminho completo para o arquivo:

dat <- read_csv(fullpath)

5.2.2 readxl

Você pode carregar o pacote readxl usando:

library(readxl)

O pacote oferece funções para a leitura de arquivos nos formatos do Microsoft Excel:

Função Formato Extensão
read_excel detecta automaticamente o formato xls, xlsx
read_xls formato original xls
read_xlsx novo formato xlsx

Os formatos do Microsoft Excel permitem que você tenha mais de uma planilha em um arquivo. As funções listadas acima leem por padrão a primeira folha, mas também podemos ler as outras. A função excel_sheets nos fornece os nomes de todas as planilhas em um arquivo do Excel. Esses nomes podem ser passados pelo argumento sheet das três funções apresentadas anteriormente, permitindo assim a leitura de outras planilhas do arquivo além da primeira.

5.3 Exercícios

1. Use a função read_csv para ler cada um dos arquivos que o código a seguir armazena no objeto files:

path <- system.file("extdata", package = "dslabs")
files <- list.files(path)
files

2. Observe que o último arquivo (olive), retorna um aviso. Isso ocorre porque a primeira linha do arquivo não contém o cabeçalho da primeira coluna.

Leia a página de ajuda para read_csv para aprender a ler o arquivo sem ler esse cabeçalho. Se você omitir o cabeçalho, você não deverá receber esse aviso. Salve o resultado em um objeto chamado dat.

3. Um problema com a abordagem acima é que não sabemos o que as colunas representam. Digite:

names(dat)

para confirmar que os nomes não são informativos.

Use a função readLines para ler apenas a primeira linha (mais tarde aprenderemos como extrair valores do output).

5.4 Como fazer download de arquivos

Outro local comum onde os dados residem é na internet. Quando esses dados estão em arquivos, podemos baixá-los e importá-los, ou mesmo lê-los diretamente da web. Por exemplo, observamos que, como o pacote dslabs está no GitHub, o arquivo que baixamos com o pacote tem uma URL:

url <- "https://raw.githubusercontent.com/rafalab/dslabs/master/inst/
extdata/murders.csv"

A função read_csv pode ler esses arquivos diretamente:

dat <- read_csv(url)

Se deseja ter uma cópia local do arquivo, você pode usar a função download.file:

download.file(url, "murders.csv")

Isso fará o download do arquivo e o salvará no seu sistema com o nome murders.csv. Você pode usar qualquer nome aqui, não necessariamente murders.csv. Tenha cuidado ao usar o comando download.file, pois ele irá substituir arquivos existentes com mesmo nome sem aviso prévio.

Duas funções que às vezes são úteis ao baixar dados da internet são tempdir e tempfile. A primeira cria um diretório com um nome aleatório e provavelmente único. Da mesma forma, tempfile também cria um nome aleatório que será usado para renomear o arquivo. Você pode executar o seguinte comando para excluir os arquivos temporários depois que os dados forem importados:

tmp_filename <- tempfile()
download.file(url, tmp_filename)
dat <- read_csv(tmp_filename)
file.remove(tmp_filename)

5.5 Funções básicas de importação do R

O pacote base do R também fornece funções de importação. Eles têm nomes semelhantes aos do tidyverse, por exemplo, read.table, read.csv e read.delim. No entanto, existem algumas diferenças importantes. Para mostrar isso, vamos ler os dados com uma função básica do R:

dat2 <- read.csv(filename)

Uma diferença importante é que os caracteres são convertidos em fatores (factors):

class(dat2$abb)
#> [1] "character"
class(dat2$region)
#> [1] "character"

Isso pode ser evitado definindo o argumento stringsAsFactors como FALSE.

dat <- read.csv("murders.csv", stringsAsFactors = FALSE)
class(dat$state)
#> [1] "character"

Em nossa experiência, isso pode ser motivo de confusão, uma vez que uma variável que foi salva como caracteres no arquivo se é obrigatoriamente convertida em factor, independente do que a variável represente. De fato, é altamente recomendável definir stringsAsFactors=FALSE para ser a abordagem padrão ao usar o parser da base R. Você pode facilmente converter colunas desejadas em fatores após a importação de dados.

5.5.1 scan

Ao ler planilhas, muitas coisas podem dar errado. O arquivo pode ter um cabeçalho de múltiplas linhas, algumas células podem estar ausentes ou o arquivo pode estar utilizando uma codificação inesperada17. Recomendamos que você leia este artigo sobre problemas comuns com caracteres: https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/.

Com a experiência, você aprenderá a lidar com diferentes desafios. Além disso, ler atentamente os arquivos de ajuda para as funções discutidas aqui poderá ser útil. Com a função scan você pode ler cada célula de um arquivo. Aqui está um exemplo:

path <- system.file("extdata", package = "dslabs")
filename <- "murders.csv"
x <- scan(file.path(path, filename), sep=",", what = "c")
x[1:10]
#>  [1] "state"      "abb"        "region"     "population" "total"     
#>  [6] "Alabama"    "AL"         "South"      "4779736"    "135"

Note que o tidyverse fornece read_lines, uma função igualmente útil.

5.6 Arquivos de texto versus arquivos binários

Na ciência de dados, arquivos geralmente podem ser classificados em duas categorias: arquivos de texto (também conhecidos como arquivos ASCII) e arquivos binários. Você já tem trabalhado com arquivos de texto. Todos os seus scripts R são arquivos de texto, assim como os arquivos R markdown usados para criar este livro. As tabelas csv que você leu também são arquivos de texto. Uma grande vantagem desses arquivos é que podemos facilmente “olhá-los,” sem precisar comprar nenhum tipo de software especial ou seguir instruções complicadas. Qualquer editor de texto pode ser usado para navegar em um arquivo de texto, incluindo editores disponíveis gratuitamente, como RStudio, Notepad, textEdit, vi, emacs, nano e pico. Para ver isso, tente abrir um arquivo csv com a ferramenta do RStudio “Open file” (abrir arquivo). Você deverá poder ver o conteúdo diretamente no editor. No entanto, se tentar abrir, digamos, um arquivo xls do Excel, ou imagem nos formatos jpg ou png, você não poderá ver nada imediatamente útil. Esses são arquivos binários. Os arquivos do Excel são, na verdade, pastas compactadas com vários arquivos de texto. A principal distinção aqui é que os arquivos de texto podem ser facilmente navegados.

Embora R inclua ferramentas para ler arquivos binários amplamente utilizados, como arquivos xls, geralmente é melhor encontrar conjuntos de dados armazenados em arquivos de texto. Da mesma forma, ao compartilhar dados, é melhor disponibilizá-los como arquivos de texto, desde que o armazenamento não seja um problema (os arquivos binários são mais eficientes para economizar de espaço em sua unidade de armazenamento). Em geral, os formatos de texto facilitam a troca de dados, pois não requerem software comercial para trabalhar com os dados.

Extrair dados de uma planilha armazenada como um arquivo de texto é talvez a maneira mais fácil de trazer dados de um arquivo para uma sessão R. Infelizmente, planilhas nem sempre estão disponíveis e o fato de você poder visualizar arquivos de texto não implica necessariamente que será fácil extrair dados dele. Na parte _ Data Wrangling_ do livro, aprenderemos como extrair dados de arquivos de texto mais complexos, como arquivos html.

5.7 Unicode versus ASCII

Uma armadilha na ciência de dados é assumir que um dado arquivo se trata de um arquivo de texto ASCII, quando na verdade é outra coisa que pode se parecer muito com um arquivo de texto ASCII: um arquivo de texto Unicode.

Para entender a diferença entre eles, lembre-se de que tudo no computador precisa ser convertido em 0s e 1s. ASCII é uma codificação que define uma correspondência entre caracteres e números. O ASCII usa 7 bits (0s e 1s), o que resulta em \(2^7 = 128\) elementos únicos, que é suficiente para codificar todos os caracteres de um teclado do idioma inglês. No entanto, outros idiomas, como o português, usam caracteres não incluídos nessa codificação. Por exemplo, o é na palavra México não é codificado em ASCII. Por esse motivo, foi definida uma nova codificação que usa mais do que 7 bits: Unicode. Ao usar o Unicode, você pode escolher entre as codificações UTF-8, UTF-16 ou UTF-32 que utilizam 8, 16 ou 32 bits, respectivamente. O RStudio usa a codificação UTF-8 por padrão.

Embora não entremos em detalhes sobre como lidar com diferentes codificações aqui, é importante que você saiba que existem codificações diferentes para que você possa diagnosticar melhor caso encontre um problema. Um exemplo de problema é quando surgem caracteres “de aparência estranha” e que você não esperava. Esta discussão do StackOverflow é um exemplo: https://stackoverflow.com/questions/18789330/r-on-windows-character-encoding-hell.

5.8 Como organizar dados com planilhas

Embora este livro se concentre quase exclusivamente na análise de dados, o gerenciamento de dados também é uma parte importante da ciência de dados. Como explicamos na introdução, não cobrimos esse tema. No entanto, muitas vezes analistas de dados precisam realizar coletas ou trabalhar com outras pessoas que coletam dados, portanto, a maneira mais conveniente de armazená-los é em uma planilha. Embora o preenchimento manual de uma planilha seja uma prática que não recomendamos e preferimos que o processo seja automatizado o máximo possível, às vezes não há outra opção. Portanto, nesta seção, oferecemos recomendações sobre como organizar dados em uma planilha. Embora existam pacotes R projetados para ler planilhas do Microsoft Excel, geralmente devemos evitar esse formato. Recomendamos o Google Sheets por ser uma ferramenta gratuita. Abaixo resumimos as recomendações feitas em um artigo publicado por Karl Broman e Kara Woo18. Para obter mais detalhes, leia o artigo completo.

  • Seja consistente - Antes de começar a inserir dados, tenha um plano. Depois de estabelecer o plano, seja consistente e siga-o.
  • Escolha bons nomes para as coisas: os nomes que você escolher para objetos, arquivos e diretórios devem ser memoráveis, fáceis de soletrar e descritivos. Esse é um equilíbrio difícil de alcançar e requer tempo e reflexão. Uma regra importante a seguir é não use espaços, use sublinhados _ ou hífens -. Além disso, evite símbolos e caracteres especiais (como acentos e cedilha); é melhor usar letras e números.
  • Insira as datas como AAAA-MM-DD - Para evitar confusão, recomendamos o uso do padrão global ISO 8601.
  • Evite células vazias - Preencha todas as células. Você pode usar algum código comum para representar dados ausentes.
  • Coloque apenas uma coisa em cada célula - É melhor adicionar colunas para armazenar informações adicionais em vez de ter mais de uma informação em uma célula.
  • Faça um retângulo - A planilha deve ser um retângulo.
  • Crie um dicionário de dados - Se você precisar explicar as coisas, por exemplo, quais são as colunas ou os rótulos usados para variáveis categóricas, faça isso em um arquivo separado.
  • Não faça cálculos em arquivos de dados brutos - O Excel permite que você faça cálculos. Não faça disso parte de sua planilha. Códigos para realização de cálculos devem estar em um script separado.
  • Não use cores ou realces como dados - A maioria das funções de importação não consegue importar essas informações. Em vez disso, codifique-as como variáveis.
  • Faça backup de suas informações: faça backup de seus dados com frequência.
  • Utilize a validação de dados para evitar erros - Aproveite as ferramentas de seu programa de edição de planilhas para tornar o processo o mais livre possível de erros e de lesões por esforço repetitivo.
  • Salve dados como arquivos de texto - Salve os arquivos para compartilhar em formato delimitado por vírgula ou tabulações.

5.9 Exercícios

1. Escolha uma medida que você possa mensurar regularmente. Por exemplo, seu peso diário ou quanto tempo leva para percorrer 8 km. Mantenha uma planilha que inclua data, hora, medida e outras variáveis informativas que considere valiosas. Faça isso por 2 semanas. Então faça um gráfico.