7 Dados no R

Pode-se entrar com dados no R de diferentes formas. O formato mais adequado vai depender do formato e tamanho do conjunto de dados, Uma importante diferença é se os dados já existem em formato do R ou outro formato para serem importados ou se serão digitados diretamente no R.

A seguir são descritas formas de entrada de dados com indicação de quando cada uma das formas deve ser usada. Iniciamos com a entrada de dados diretamente no Rcomo se não tivessemos ainda dados em algum formato eletrônico. A seguir descreve-se como importar dados já disponíveis eletronicamente de um arquivo texto, em outro sistema ou no próprio R. Ao final discutios diferentes formas de exportar/importar objetos do R.

7.1 Entrando com dados diretamente no R

7.1.1 Definindo vetores

Podemos entrar com dados definindo vetores com o comando c() ("c" corresponde a concatenate) ou usando funções que criam vetores. Veja e experimente com os seguintes exemplos.

> a1 <- c(2,5,8)    # cria vetor a1 com os dados 2, 5 e 8 
> a1                # exibe os elementos de a1

[1] 2 5 8

> (a1 <- c(2,5,8))  # cria e exibe vetor a1 com os dados 2, 5 e 8

[1] 2 5 8

> (a2 <- c(23,56,34,23,12,56))

[1] 23 56 34 23 12 56

Esta forma de entrada de dados é conveniente quando se tem um pequeno número de dados.

Quando os dados têm algum "padrão" tal como elementos repetidos ou números sequenciais pode-se usar mecanismos do R para facilitar a entrada dos dados na forma de vetores. Examine os seguintes exemplos.

> (a3 <- 1:10)                # vetor com números sequenciais de 1 a 10

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

> (a4 <- (1:10)*10)           # vetor com elementos 10, 20, ..., 100

 [1]  10  20  30  40  50  60  70  80  90 100

> (a5 <- rep(3, 5))           # vetor com elemento 3 repetido 5 vezes

[1] 3 3 3 3 3

> (a6 <- rep(c(5,8), 3))      # vetor repetindo 3 vezes 5 e 8 alternadamente

[1] 5 8 5 8 5 8

> (a7 <- rep(c(5,8), each=3)) # vetor repetindo 3 vezes 5 e depois 8

[1] 5 5 5 8 8 8

7.1.2 Entrada via teclado

Usando a função scan() Esta função lê dados diretamente do console, isto é, coloca o R em modo prompt onde o usuário deve digitar cada dado seguido da tecla <ENTER>. Para encerrar a entrada de dados basta digitar <ENTER> duas vezes consecutivas. Veja o seguinte resultado:

y <- scan() 
1: 11 
2: 24 
3: 35 
4: 29 
5: 39 
6: 47 
7: 
Read 6 items 
 
> y 
[1] 11 24 35 29 39 47

Este formato é mais ágil que o anterior e é conveniente para digitar vetores longos. Esta função pode também ser usada para ler dados de um arquivo ou conexão, aceitando inclusive endereços de URL’s (endereços da web) o que iremos mencionar em mais detalhes mais adiante.

Usando textConnection() Esta função generaliza a anterior permitindo que se entre com mais de um campo por linha, gravando o resultado em um data.frame(). O seguinte exemplo foi postado por Henrique Dallazuanna na lista R-STAT e ilustra este uso.

d <- read.table(textConnection("trat resposta 
 a 10 
 a 12 
 b 15 
 b 20 
 c 12 
 c 5 
 d 8 
 d 10"), header = TRUE, stringsAsFactors = TRUE) 
str(d) 
'data.frame':        8 obs. of  2 variables: 
 $ trat    : Factor w/ 4 levels "a","b","c","d": 1 1 2 2 3 3 4 4 
 $ resposta: int  10 12 15 20 12 5 8 10

Uso da função readLines() Este função é particularmente útil para ler entradas na forma de texto (strings). Por exemplo, para ler uma linha a ser digitada na tela do R siga o comando abaixo e digite o texto indicado. Ao terminar pressione a tecla ENTER e o texto será armazenado no objeto texto.

> texto <- readLines(n=1) 
> ## Este é um texto de exemplo 
> texto

Um possível uso é dentro de funções que solicitem que o usuário responda e/ou entre com informações à medida que são solicitadas. Experimente definir e rodar a função a seguir.

> rL.ex <- function(){ 
+   cat("digite o nome do time de futebol de sua preferencia (em letras minúsculas)\n") 
+   time <- readLines(n=1) 
+   if(time == "cruzeiro") cat("BOA ESCOLHA!!!\n") 
+   else cat("Ihh, tá mal de escolha...\n") 
+   return(invisible()) 
+ } 
> rL.ex()

Nesse exemplo readLines() foi utilizada para efetuar via teclado mas a função permite ainda entrada de dados por conexões com outros dispositivos de input. Por exemplo, pode ser utilizada para ler texto de um arquivo. Consulte a documentação da função para maiores detalhes e exemplos.

Corrigindo e/ou alterando dados Suponha que tenhamos digitado algum dado errado que desejamos corrigir. Por exemplo, suponha que o correto seja 25 no lugar de 35. Para corrigir basta selecionar a posição do dado atribuindo o valor correto

> y[3] <- 25 
> y

[1] 11 24 25 29 39 47

Vejamos ainda um outro exemplo onde todos dados iguais ou acima de 30 têm seu valor alterado para 30.

> y[y >= 30] <- 30 
> y

[1] 11 24 25 29 30 30

7.1.3 Usando a função edit()

O comando edit(data.frame()) abre uma planilha para digitação de dados que são armazenados como data.frames. Data-frames são o análogo no R a uma planilha.

Portanto digitando

a8 <- edit(data.frame())

será aberta uma planilha na qual os dados devem ser digitados. Quando terminar de entrar com os dados note que no canto superior direito da planilha existe um botão <QUIT>. Pressionando este botão a planilha será fechada e os dados serão gravados no objeto indicado (no exemplo acima no objeto a8).

Se você precisar abrir novamente planilha com os dados, para fazer correções e/ou inserir mais dados use o comando fix(). No exemplo acima você digitaria fix(a8).

Esta forma de entrada de dados é adequada quando você tem dados que não podem ser armazenados em um único vetor, por exemplo quando há dados de mais de uma variável para serem digitados.

7.2 Lendo dados de um arquivo texto

Se os dados já estão disponíveis em formato eletrônico, isto é, já foram digitados em outro programa, você pode importar os dados para o R sem a necessidade de digitá-los novamente.

A forma mais fácil de fazer isto é usar dados em formato texto (arquivo do tipo ASCII). Por exemplo, se seus dados estão disponíveis em uma planilha eletrônica como EXCEL ou similar, você pode na planilha escolher a opção <SALVAR COMO> e gravar os dados em um arquivo em formato texto.

No R usa-se scan() mencionada anteriormente, ou então a função mais flexível read.table() (e variantes) para ler os dados de um arquivo texto e armazenar no formato de uma data.frame.

Exemplo 1: Como primeiro exemplo considere importar para o R os dados deste arquivo texto. Clique no link para visualizar o arquivo. Agora copie o arquivo para sua área de trabalho (working directory do R). Para importar e visualizar os dados deste arquivo usamos:

(ex01 <- read.table("gam01.txt"))

Exemplo 2: Em um segundo exemplo considere importar para o R os dados deste arquivo texto. Clique no link para visualizar o arquivo. Agora copie o arquivo para sua área de trabalho (working directory do R).

Note que este arquivo difere do anterior em um aspecto: os nomes das variáveis estão na primeira linha. Para que o R considere isto corretamente temos que informá-lo disto com o argumento header=TRUE. Portanto para importar este arquivo usamos:

(ex02 <- read.table("exemplo02.txt", header=TRUE))

Exemplo 3: Para o terceiro exemplo considere importar para o R os dados deste arquivo texto. Clique no link para visualizar o arquivo. Agora copie o arquivo para sua área de trabalho (working directory do R).

Note que este arquivo difere do primeiro em outros aspectos: além dos nomes das variáveis estarem na primeira linha, os campos agora não são mais separados por tabulação e sim pelo caractere : separador de valores. Além disto os caracteres decimais estão separados por vírgula, sendo que o R usa ponto, pois é um programa escrito em língua inglesa. Portanto para importar corretamente este arquivo usamos então os argumentos sep e dec:

> (ex03 <- read.table("dadosfic.csv", head=TRUE, sep=":", dec=","))

Para maiores informações consulte a documentação desta função com ?read.table.

Embora read.table() seja provavelmente a função mais utilizada existem outras que podem ser úteis em determinadas situações.

Exemplo 4: Um caso particular é quando os dados estão em formato de largura fixa (fixed width format), sem nenhum caractere separando os campos – cada variável ocupa sempre a mesma quantidade de colunas no arquivo. Nestes casos read.table() não funciona e deve-se usar read.fwf(), informando a largura de cada campo através do argumento widths. Considere por exemplo o arquivo fwf01.txt com o seguinte conteúdo:

001M23
002F31
003M45
004F29

onde as três primeiras colunas correspondem a um código, a quarta ao sexo e as duas últimas à idade, sem nenhum espaço ou símbolo separando os campos. Para importar estes dados usamos:

> read.fwf("fwf01.txt", widths = c(3, 1, 2), 
+          col.names = c("codigo", "sexo", "idade"))

Exemplo 5: As funções permitem ler ainda dados diretamente disponíveis na web. Por exemplo os dados dos exemplos 1, 2 e 3 poderiam ser lidos diretamente com o comando a seguir, sem a necessidade de copiar primeiro os dados para algum local no computador do usuário:

> ex1 <- read.table("http://www.leg.ufpr.br/Rembrapa/dados/gam01.txt") 
> ex02 <- read.table("http://www.leg.ufpr.br/Rembrapa/dados/exemplo02.txt", header=TRUE) 
> ex03 <- read.table("http://www.leg.ufpr.br/Rembrapa/dados/dadosfic.csv", 
+                    head=TRUE, sep=":", dec=",") 
> ex03 <-read.csv2("http://www.leg.ufpr.br/Rembrapa/dados/dadosfic.csv", sep = ":")

7.3 Lendo dados através da área de transferência

Um mecanismo comum para copiar dados de um programa para o outro é usando a área de transferência. Tipicamente isto é feito com o mecanismo de recorta-e-cola, ou seja, marca-se os dados desejados em algum aplicativo (editor, planilha, página web, etc), usa-se o mecanismo de COPIAR (opção no menu do programa que muitas vezes corresponde ao teclar CTRL-C), o que transfere os dados para a área de transferência. Funções como scan(), read.table() e outras podem ser usadas para ler os dados diretamente da área de transferência passando-se a opção "clipboard" ao primeiro argumento. Por exemplo, os seguintes dados:

  ID  Grupo  Gasto  Ano
  23      A  25,4   11
  12      B  12,3   09
  23      A  19,8   07

podem ser marcados e copiados para área de transferência e lidos diretamente com:

> read.table("clipboard", header=TRUE, dec=",")

7.4 Carregando dados já disponíveis no R

Para carregar conjuntos de dados que são já disponibilizados com o R use o comando data(). Por exemplo, abaixo mostramos como carregar o conjunto mtcars que está no pacote datasets e depois como localizar e carregar o conjunto de dados topo.

> data(mtcars) 
> head(mtcars)

                   mpg cyl disp  hp drat    wt  qsec vs am gear carb 
Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4 
Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4 
Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1 
Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1 
Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2 
Valiant           18.1   6  225 105 2.76 3.460 20.22  1  0    3    1

> require(MASS)

Carregando pacotes exigidos: MASS

> data(topo) 
> find("topo")

[1] ".GlobalEnv"   "package:MASS"

> head(topo)

    x   y   z 
1 0.3 6.1 870 
2 1.4 6.2 793 
3 2.4 6.1 755 
4 3.6 6.2 690 
5 5.7 6.2 800 
6 1.6 5.2 800

O conjunto mtcars está no pacote datasets que é carregado automaticamente quando iniciamos o R, portanto os dados estão prontamente disponíveis. Ao carregar os dados é criado um objeto mtcars no seu workspace.

Já o conjunto topo está no pacote MASS que não é automaticamente carregado ao iniciar o R e portanto deve ser carregado com require() para depois podermos acessar os dados.

A função data() pode ainda ser usada para listar os conjuntos de dados disponíveis. A primeira chamada a seguir lista os conjuntos de dados dos pacotes carregados. A segunda lista os conjuntos de dados de um pacote específico (no exemplo do pacote nlme).

> data() 
> data(package="nlme")

7.5 Importando dados de outros programas

É possível ler dados diretamente de outros formatos que não seja texto (ASCII). Isto em geral é mais eficiente e requer menos memória do que converter para formato texto. Há funções para importar dados diretamente de EpiInfo, Minitab, S-PLUS, SAS, SPSS, Stata, Systat e Octave. Além disto é comum surgir a necessidade de importar dados de planilhas eletrônicas. Muitas funções que permitem a importação de dados de outros programas são implementadas no pacote foreign.

> require(foreign)

A seguir listamos (mas não todas!) algumas destas funções

Para mais detalhes consulte a documentação de cada função e/ou o manual R Data Import/Export.

Um mecanismo genérico O pacote rio contém uma função import() que é capaz de importar dados de uma diversidade de formatos incluindo todas as opções mencionadas anteriormente e muitas outras. A vinheta de apresentação do pacote descreve este poderoso e versátil recurso.

7.6 Acesso a planilhas e bancos de dados relacionais

É comum que dados estejam armazenados em planilhas eletrônicas tais como MS-Excel ou LibreOffice Spreadsheet. Nestes caso, embora seja possível exportar a partir destes aplicativos os dados para o formato texto para depois serem lidos no R, possivelmente com read.table(), pode ser necessário ou conveniente ler os dados diretamente destes formatos. Vamos colocar aqui algumas opções para importar dados do MS-Excel para o R.

Estruturas de dados mais complexas são tipicamente armazenadas em dbms’s (database management system) ou rdbms’s (relational database management system). Alguns exemplos são Oracle, Microsoft SQL server, MySQL, PostgreSQL, Microsoft Access, dentre outros. O R possui ferramentas implementadas em pacotes para acesso a estes sistemas gerenciadores e esse é um tópico especializado que não abordaremos aqui. Para mais detalhes consulte o manual R Data Import/Export e a documentação dos pacotes que implementam tal funcionalidade. Alguns deles disponíveis por ocasião da redação deste texto eram: odbc, DBI, RMySQL, RPostgreSQL, ROracle, RNetCDF, RSQLite, dentre outros. Certamente as opções atuais são diferentes.

7.7 Exportando dados para arquivos

Assim como podemos importar dados de arquivos externos, muitas vezes é necessário o processo inverso: gravar em um arquivo os dados que estão em um objeto do R, por exemplo um data-frame resultante de alguma manipulação ou análise.

As funções mais usadas para isto são write.table(), write.csv() e write.csv2(), análogas às funções read.table(), read.csv() e read.csv2() vistas anteriormente e que seguem as mesmas convenções. Por exemplo, write.csv2() grava o arquivo usando ponto-e-vírgula como separador de campos e vírgula como separador decimal, mais comum no formato csv usado no Brasil.

> df <- data.frame(trat = c("A","A","B","B"), resposta = c(10, 12, 15, 20)) 
> write.table(df, "dadosExp.txt") 
> write.csv(df, "dadosExp.csv", row.names = FALSE) 
> write.csv2(df, "dadosExp2.csv", row.names = FALSE)

Os arquivos com os noems entre aspas nos comandos acima são gravados no diretório local, a menos que algum outro caminho seja especificado no nome dos arquivos. Note que por default estas funções gravam também os nomes das linhas (row names) do objeto, o que na maioria das vezes não é desejado. Para evitar isto usa-se o argumento row.names = FALSE como no exemplo acima.

Para exportar diretamente para uma planilha do MS-Excel pode-se usar, por exemplo, a função write_xlsx() do pacote writexl, que é o equivalente para gravação do pacote readxl mencionado anteriormente.

> require(writexl) 
> write_xlsx(df, "planilhaExp.xlsx")

7.8 Salvando e restaurando objetos e o workspace do R

Além de importar e exportar dados em formato texto ou de outros programas, o R possui mecanismos próprios para salvar e restaurar objetos. Isto é conveniente por preservar a classe e os atributos do objeto original. Dessa forma fatores continuam fatores e listas continuam listas. Estes mecanismos se distinguem em dois aspectos independentes: o número de objetos tratados por vez (um único, vários, ou todo o workspace) e o formato do arquivo gerado.

Quanto ao formato, saveRDS(), save() e save.image() gravam em formato binário. É um formato compacto e rápido de gravar/ler, porém ilegível diretamente por humanos e pouco amigável a sistemas de controle de versão como o git já que não consegue mostrar diferenças significativas entre duas versões do arquivo.

Alterenativamente dput() e dump(), suas contrapartes vistas a seguir junto com saveRDS() e save(), gravam em formato texto (ASCII). Nesse formato o arquivo contém o próprio código R (obtido por deparse) que, ao ser executado, recria o objeto. Por isso pode ser lido, editado e comparado como qualquer outro script, embora seja mais lento e ocupe mais espaço para objetos grandes, mas pode ser comprimido usando ferramentas como zip, tar ou similar.

Exemplo 1 Vamos considerar que desejamos exportar para uma representação do R um único objeto usando saveRDS()/readRDS() (binário) ou dput()/dget() (texto)

Estas funções gravam e restauram um único objeto do R por vez, tipicamente em um arquivo com extensão .rds no caso de saveRDS(). Uma característica importante é que o nome do objeto não é gravado junto com os dados. Ao restaurar, o resultado deve ser atribuído a um objeto, que pode inclusive ter um nome diferente do original.

> saveRDS(df, "df.rds") 
> rm(df) 
> df.novo <- readRDS("df.rds") 
> df.novo

  trat resposta 
1    A       10 
2    A       12 
3    B       15 
4    B       20

O equivalente em formato texto é dado por dput() e dget(), que funcionam da mesma forma:

> dput(df.novo, "df.R") 
> d.novo2 <- dget("df.R") 
> d.novo2

  trat resposta 
1    A       10 
2    A       12 
3    B       15 
4    B       20

Note no arquivo d.R gerado que o seu conteúdo é o próprio comando R que constrói o objeto d.novo (uma chamada a structure()), e não os dados em formato de tabela.

Exemplo 2 Vamos agora considerar que desejamos exportar uma representação do R de vários objetos: save()/load() (binário) e dump()/source() (texto).

As funções save() e load() permitem gravar vários objetos de uma só vez, tipicamente em um arquivo com extensão .RData ou .rda. Diferentemente de saveRDS(), aqui os nomes dos objetos são gravados junto com os dados e restaurados automaticamente com estes mesmos nomes ao usar load(). Não há como atribuir o resultado a um nome diferente e objetos já existentes com o mesmo nome são sobrescritos.

> a1 <- 1:5 
> a2 <- c("x", "y", "z") 
> save(a1, a2, file = "objetos.RData") 
> rm(a1, a2) 
> load("objetos.RData") 
> a1

[1] 1 2 3 4 5

> a2

[1] "x" "y" "z"

O equivalente em formato texto é dado por dump() e source(): a primeira grava, em um único arquivo texto, o código R que recria cada um dos objetos indicados; a segunda simplesmente executa este código, recriando-os com os mesmos nomes originais – exatamente como fazemos ao rodar (source) qualquer outro script do R.

> dump(c("a1", "a2"), file = "meus-objetos.R") 
> rm(a1, a2) 
> source("meus-objetos.R") 
> a1

[1] 1 2 3 4 5

> a2

[1] "x" "y" "z"

Exemplo 3 Por fim, é possível salvar todos os objetos criados na sessão de uma só vez com save.image(), que por default grava um arquivo chamado .RData no diretório de trabalho. Este é o mesmo arquivo que o R oferece para gravar ao ser fechado (a pergunta "Save workspace image?") e que, se existir, é automaticamente recarregado na próxima vez que o R for iniciado no mesmo diretório.

> save.image()  # grava .RData no diretório de trabalho

Nota: embora conveniente, esse carregamento automático do .RData prejudica a reprodutibilidade do trabalho, pois o resultado de uma sessão passa a depender de objetos “invisíveis” criados em sessões anteriores. Por isso muitos usuários preferem desabilitar este mecanismo, recriando sempre os objetos necessários a partir dos scripts.