Filtrar arquivo CSV de 5GB no R – r

Pergunta:


Estou tentando de todas as formas mexer em um arquivo de 5GB para minha monografia.

O código que estou tentando entrar no R é o seguinte:

> write.csv(subset(read.csv("enem.csv", header=TRUE), UF_ESC=="SP"), "filtro.csv", row.nomes=FALSE)

Já testei com um arquivo modelo é deu tudo certo, mas no banco de dados original não. Imagino que seja pelo tamanho, pois, fica pensando e nada.

Se alguém tiver uma outra ideia para ajudar será de enorme ajuda.

Autor da pergunta André Oliveira

Resposta :

Aqui vão algumas dicas p/ resolver o seu problema:

1 – Leia o arquivo usando outra função:

> microbenchmark(
+   base = read.csv(file = "df-write-csv.csv", header = T),
+   readr = readr::read_csv("df-write-csv.csv"),
+   data.table = data.table::fread("df-write-csv.csv"),
+   rio = rio::import("df-write-csv.csv", format = "csv")
+ )
Unit: microseconds
       expr      min        lq      mean    median        uq      max neval
       base 1836.230 1912.1815 2253.6071 1980.3995 2282.1675 4148.787   100
      readr  823.960  881.3625 1072.4790  921.6605 1120.2365 3538.359   100
 data.table  327.759  364.4810  442.5933  402.3295  458.7895  920.436   100
        rio  312.317  351.2260  444.1087  382.9325  439.7960 2938.490   100

Veja que ler o arquivo com a função fread do data.table ou com a função importdo rio é 4x mais rápido do que com a função nativa do R.
Verifique se você realmente conseguiu ler.

2 – Verifique que você realmente conseguiu filtrar o seu banco de dados. Salve o resultado do subset em um objeto auxiliar.
Se o problema for esse, tente filtrar usando funções de outros pacotes como dplyr ou data.table.

Quando são operações longas, o data.table consegue ser muito mais rápido.

> df <- data.frame(x = 1:100000, y = 1:100000, l = sample(letters, size = 100, replace = T))
> microbenchmark(
+   base = subset(df, l == "a"),
+   dplyr = dplyr::filter(df, l == "a"),
+   data.table = data.table(df)[l == "a",]
+ )
Unit: milliseconds
       expr       min        lq      mean    median        uq      max neval
       base 10.329514 12.467143 14.962479 13.976907 17.171858  24.3761   100
      dplyr  7.331626  8.624356 10.063947  8.853807 11.140871  16.8939   100
 data.table  2.986519  4.580536  6.774548  4.824227  5.957255 119.9709   100

3 – Use a função write_csv do pacote readr ela é mais ou menos 2x mais rápida do que a função write.csv nativa do R.

microbenchmark(
  base = write.csv(df, file = "df-write-csv.csv", row.names = F),
  rio = rio::export(df, file = "df-rio.csv", format = "csv"),
  readr = readr::write_csv(df, path = "df-readr.csv")
)

Unit: microseconds
  expr     min       lq     mean    median       uq      max neval
  base 713.564 1097.534 2025.377 1467.4980 2996.136 4168.352   100
   rio 718.141 1156.998 2243.143 2011.5310 3106.479 7368.046   100
 readr 366.306  594.629 1265.297  734.0445 1793.405 5852.142   100

Enfim, se você conseguiu ler o arquivo de 5GB, é muito provável que você também consiga escrevê-lo, uma vez que ele já está na RAM do seu computador.

André, como você só vai filtrar o seu banco de dados e depois disso ele vai ficar muito menor, você pode lê-lo em chunks. Para isso você pode fazer da seguinte forma:

Só p/ testar criei o seguinte arquivo “grande”:

library(readr)
library(dplyr)
x <- data.frame(x = runif(3e6), y = 1:3e6)
write_csv(x, path = "test.csv")

O seguinte trecho de código lê o banco de dados em pequenas partes (tam_chunk), filtra essas partes e depois salva em um arquivo chamado filtrado.csv.

Veja se dessa forma funciona. Deve ser demorado, mas pelo menos você consegue passar pelo problema da memória:

# criando a conexão com o arquivo grande
arq_grande <- file("test.csv", "r")
tam_chunk <- 1e5 # tamanho do chunk
# lendo as 100 primeiras linhas do banco de dados e criando
# o arquivo filtrado
df1 <- read.csv(arq_grande, nrows = 100, header = T)
df_filtrado <- df1 %>% filter(x <= 0.5)
write.table(df_filtrado, "filtrado.csv", row.names = F, sep = ",", dec = ".")
# iniciando o loop de leitura em chunks
n_row <- 1
repeat {
  ## process data...
  ## ...then read the next chunk
  df <- read.csv(arq_grande, header=FALSE, col.names = names(df1), nrows = tam_chunk)
  cat("Read", nrow(df), "rowsn")
  if (nrow(df) == 0)                # done yet?
    break
  df_filtrado <- df %>% filter(x <= 0.5) # filtrar o data.frame
  # salvar o data.frame
  write.table(df_filtrado, "filtrado.csv", append = T, 
              col.names = F, row.names = F, sep = ",", dec = ".")
}
close(arq_grande)

Essa resposta foi muito inspirada nesta resposta do Stack Overflow em Inglês.

Fonte

Related Posts:

Qual a diferença entre AppCompatActivity e Activity? – android android-activity
Pergunta: Qual a diferença da AppCompatActivity para Activity ? A partir de qual versão a AppCompatActivity foi adicionada ao Android? Autor da pergunta Luhhh A diferença reside ...
Como abreviar palavras em PHP? – php string
Pergunta: Possuo informações comuns como nome de pessoas e endereços, e preciso que elas contenham no máximo 30 caracteres sem cortar palavras. Exemplo: 'Avenida Natalino João Brescansin' ...
Qual é a finalidade de um parêntese vazio numa declaração Lambda? – c# expressões-lambda característica-linguagem
Pergunta: Criei um exemplo de uma declaração Lambda sem argumentos, entretanto, estou com duvidas referente a omissão do parêntese vazio () na declaração. Veja o exemplo: class ...
Boas práticas para URI em API RESTful – api rest restful
Pergunta: Estou com dúvida em relação às URIs de alguns recursos da api que estou desenvolvendo. Tenho os recursos projetos e atividades com relação 1-N, ...
Dúvidas sobre a integração do MySQL com Java – java mysql netbeans
Pergunta: Estou criando um sistema no NetBeans, utilizando a linguagem Java e o banco de dados MySQL. Escrevi o seguinte código para realizar a conexão ...
Qual é a finalidade da pasta Model do framework Inphinit? – php inphinit
Pergunta: No Inphinit micro-framework existe a pasta Model que fica dentro da pasta application, e nela é onde ficam as classes, mas eu estou muito ...
Uso do ‘@’ em variáveis – javascript typescript coffeescript
Pergunta: Vejo em algumas linguagens que compilam para javascript, como TypeScript e CoffeeScript, o uso do @ em variáveis, como também, casos em que o ...
Qual tamanho máximo um arquivo JSON pode ter? – json arquivo
Pergunta: Vou dar um exemplo para conseguir explicar minha duvida: Preciso recuperar informação de imagens vindas de uma API, esse banco de imagens me retorna JSON's ...
O que é Teste de Regressão? – terminologia engenharia-de-software testes
Pergunta: Na matéria de Teste de Software o professor abordou um termo chamado Teste de Regressão, isto dentro da disciplina de teste de software. Sendo ...
O que é um construtor da linguagem? – php característica-linguagem
Pergunta: Em PHP, já li e ouvi várias vezes a respeito dos Construtores da Linguagem. Os casos que sempre ouvi falar deles foi em casos ...
Função intrínseca para converter numérico para string – cobol
Pergunta: Estou a tentar saber se existe alguma função intrínseca do COBOL para converter um data numérico para string sem precisar usar a cláusula REDEFINES: ( ...
Porque usar implements? – java android
Pergunta: Qual a diferença entre usar btn.setOnClickListener(new OnClickListener() { e public class MainActivity extends Activity implements OnClickListener{ Estive fazendo um curso de Android e meu professor falou que ...
O que é XHTML e quando deve ser usado? – html xml xhtml
Pergunta: O que eu sei é que o XHTML precisa ser XML válido. Isso implica, por exemplo, que todas as tags precisam ser fechadas. Por ...
Uma placa aceleradora de vídeo pode melhorar o desempenho não-gráfico? [fechada] – desempenho
Pergunta: Para desenvolver em Ruby on Rails, eu utilizo aqui uma máquina virtual do VirtualBox com Ubuntu Server 14.04 sem interface gráfica instalada. Recentemente descobri uma ...
Concat() VS Union() – c# .net
Pergunta: Qual a diferença entre Concat() e Union() ? Quando usar Concat() e quando usar Union() ? Somente pode ser usado em list ? ...

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *