[OFF-topic] Processar uma base de dados grande - ENEM 2012 - 6 milhões de registros - só 40 segundos

Saudações, Essa mensagem é apenas para compartilhar uma experiência que tive e considero que o problema aqui discutido não seja tão particular. Fui procurado por alguém que precisava processar um arquivo com resultados da prova do ENEM 2012 para aplicar teoria de resposta ao item. Precisava-se processar o arquivo original para chegar em um que tivesse apenas 5 das 80 colunas (notas para as competências sobre a redação) e somente às linhas que tivessem o conteúdo "P" (de presente) para a coluna "IN_STATUS_REDACAO". O arquivo é um csv, delimitador vírgula, aspas nas strings, 5791066 de linhas, 3.8 GB. Fiz o que me veio na cabeça de primeira: "dividir para conquistar". Lia porções de 30 mil linhas do arquivo (usando na read.table() o skip= e nrow=), separava as 5 colunas, mantinha só as linhas com registro P e escrevia para um arquivo com write.table(..., append=TRUE). Isso dentro de um for(). Na minha implementação, um tanto ingenua e corrida porque fiz enquanto era assistido a programar, quanto apliquei ao arquivo alvo levou 3h40. Esperava que fosse demorar mas não tanto. Minha máquina tem 16 GB de RAM. Sabendo que o bash do linux é muito eficiente para tarefas como operações em arquivos texto, eu fui buscar na internet como fazer o mesmo. Resultado é que tudo se resolveu com 37 segundos!!! É por isso que achei interessante compartilhar com a lista, inclusive para saber se alguem tem meios alternativos para solucionar o problema. Seguem os comandos que apliquei no terminal do Linux. Os dados fornecidos no exemplo são apenas as 10 mil primeiras linhas do arquivo original. ##----------------------------------------------------------------------------- ## 0. Aquisição dos dados. Apenas 10000 registros dos 5791066 do arquivo ## original. wget http://www.leg.ufpr.br/~walmes/data/DADOS_ENEM_2012_10millinhas.csv -O DADOS_ENEM_2012.csv ls wc -l DADOS_ENEM_2012.csv ##----------------------------------------------------------------------------- ## 1. Filtrar só às colunas de interesse. Da 74 à 79. Na 74 tem-se os ## valores P, F e outros. cut -d , -f 74-79 DADOS_ENEM_2012.csv > file.csv head -10 file.csv wc -l file.csv ##----------------------------------------------------------------------------- ## 2. Manter só as linhas com ocorrência do P. grep "P" file.csv > fileP.csv wc -l fileP.csv head -10 fileP.csv ##----------------------------------------------------------------------------- ## 3. Remover à colunas com P, ou seja, manter da 2 à 6. cut -d , -f 2-6 fileP.csv > file.csv head -10 file.csv wc -l file.csv ##----------------------------------------------------------------------------- ## 4. Remover as aspas para salvar espaço em disco. sed 's/\"//g' file.csv > fileP.csv head -10 fileP.csv ##----------------------------------------------------------------------------- ## 5. Como contar o número de linhas repetidas. Gerar tabela de frequência dos ## padrões de resposta. Economiza espaço e é a informação mínima ## necessária para ajustar TRI. Remover o cabeçalho. sed 1d fileP.csv > file.csv sort file.csv | uniq --count > fileP.csv head -10 fileP.csv tail -10 fileP.csv ##----------------------------------------------------------------------------- ## 6. Eliminar espaços no ínicio e colocar uma vírgula entre a ## frequência e o primeiro registro para que todos os campos sejam ## separados por `,`. sed -e 's/^ *//;s/ /,/' fileP.csv > fileFreq.csv head -10 fileFreq.csv wc -l fileFreq.csv ##----------------------------------------------------------------------------- À disposição. Walmes. ========================================================================== Walmes Marques Zeviani LEG (Laboratório de Estatística e Geoinformação, 25.450418 S, 49.231759 W) Departamento de Estatística - Universidade Federal do Paraná fone: (+55) 41 3361 3573 skype: walmeszeviani homepage: http://www.leg.ufpr.br/~walmes linux user number: 531218 ==========================================================================

Walmes, obrigado por compartilhar. Essas comparações de desempenho sempre são boas. Eu fiz um curso básico de shell script há um tempo atrás e o prof sempre comentava sobre essa característica do shell com arquivos. Agora eu tenho um exemplo mais prático e com número para exemplificar. [?] [?]s. Atenciosamente, David Feitosa (\_(\ (=°;°) (("")("") Em 24 de outubro de 2014 19:22, walmes . <walmeszeviani@gmail.com> escreveu:
Saudações,
Essa mensagem é apenas para compartilhar uma experiência que tive e considero que o problema aqui discutido não seja tão particular.
Fui procurado por alguém que precisava processar um arquivo com resultados da prova do ENEM 2012 para aplicar teoria de resposta ao item. Precisava-se processar o arquivo original para chegar em um que tivesse apenas 5 das 80 colunas (notas para as competências sobre a redação) e somente às linhas que tivessem o conteúdo "P" (de presente) para a coluna "IN_STATUS_REDACAO". O arquivo é um csv, delimitador vírgula, aspas nas strings, 5791066 de linhas, 3.8 GB. Fiz o que me veio na cabeça de primeira: "dividir para conquistar". Lia porções de 30 mil linhas do arquivo (usando na read.table() o skip= e nrow=), separava as 5 colunas, mantinha só as linhas com registro P e escrevia para um arquivo com write.table(..., append=TRUE). Isso dentro de um for(). Na minha implementação, um tanto ingenua e corrida porque fiz enquanto era assistido a programar, quanto apliquei ao arquivo alvo levou 3h40. Esperava que fosse demorar mas não tanto. Minha máquina tem 16 GB de RAM. Sabendo que o bash do linux é muito eficiente para tarefas como operações em arquivos texto, eu fui buscar na internet como fazer o mesmo. Resultado é que tudo se resolveu com 37 segundos!!! É por isso que achei interessante compartilhar com a lista, inclusive para saber se alguem tem meios alternativos para solucionar o problema. Seguem os comandos que apliquei no terminal do Linux. Os dados fornecidos no exemplo são apenas as 10 mil primeiras linhas do arquivo original.
##----------------------------------------------------------------------------- ## 0. Aquisição dos dados. Apenas 10000 registros dos 5791066 do arquivo ## original.
wget http://www.leg.ufpr.br/~walmes/data/DADOS_ENEM_2012_10millinhas.csv -O DADOS_ENEM_2012.csv ls wc -l DADOS_ENEM_2012.csv
##----------------------------------------------------------------------------- ## 1. Filtrar só às colunas de interesse. Da 74 à 79. Na 74 tem-se os ## valores P, F e outros.
cut -d , -f 74-79 DADOS_ENEM_2012.csv > file.csv head -10 file.csv wc -l file.csv
##----------------------------------------------------------------------------- ## 2. Manter só as linhas com ocorrência do P.
grep "P" file.csv > fileP.csv wc -l fileP.csv head -10 fileP.csv
##----------------------------------------------------------------------------- ## 3. Remover à colunas com P, ou seja, manter da 2 à 6.
cut -d , -f 2-6 fileP.csv > file.csv head -10 file.csv wc -l file.csv
##----------------------------------------------------------------------------- ## 4. Remover as aspas para salvar espaço em disco.
sed 's/\"//g' file.csv > fileP.csv head -10 fileP.csv
##----------------------------------------------------------------------------- ## 5. Como contar o número de linhas repetidas. Gerar tabela de frequência dos ## padrões de resposta. Economiza espaço e é a informação mínima ## necessária para ajustar TRI. Remover o cabeçalho.
sed 1d fileP.csv > file.csv sort file.csv | uniq --count > fileP.csv head -10 fileP.csv tail -10 fileP.csv
##----------------------------------------------------------------------------- ## 6. Eliminar espaços no ínicio e colocar uma vírgula entre a ## frequência e o primeiro registro para que todos os campos sejam ## separados por `,`.
sed -e 's/^ *//;s/ /,/' fileP.csv > fileFreq.csv head -10 fileFreq.csv wc -l fileFreq.csv
##-----------------------------------------------------------------------------
À disposição. Walmes.
========================================================================== Walmes Marques Zeviani LEG (Laboratório de Estatística e Geoinformação, 25.450418 S, 49.231759 W) Departamento de Estatística - Universidade Federal do Paraná fone: (+55) 41 3361 3573 skype: walmeszeviani homepage: http://www.leg.ufpr.br/~walmes linux user number: 531218 ==========================================================================
_______________________________________________ R-br mailing list R-br@listas.c3sl.ufpr.br https://listas.inf.ufpr.br/cgi-bin/mailman/listinfo/r-br Leia o guia de postagem (http://www.leg.ufpr.br/r-br-guia) e forneça código mínimo reproduzível.

Pessoal, eu fiz um teste com o MonetDB importando um arquivo csv do censo demográfico 2010 do estado de São Paulo, que tem 2.2 gb, 224 colunas e 4038218 linhas. Importou em 109.1149 segundos. Meu computador (MacBook Pro) tem processador i7 da primeira geração, 16 gb de ram e ssd. ##------------------------------------------------------ library(MonetDB.R) #criando um banco de dados startscript <- monetdb.server.setup( database.directory = paste0( getwd() , "/MonetDB" ) , "", dbname = "db1", dbport = 50002 ) pid <- monetdb.server.start(startscript) conn <- dbConnect(MonetDB.R(), "monetdb://localhost:50002/db1") # 224 colunas # 4038218 linhas # arquivo com 2.2 GB # 109.149 segundos system.time({ monetdb.read.csv(conn, 'censo00sp1.csv', "censo00sp", 4038218) }) ##------------------------------------------------------ Att Roney

Existe este pacote para o Windows? Tentei baixar e disse que não está disponível para a versão R 3.1 Pessoal, eu fiz um teste com o MonetDB importando um arquivo csv do censo demográfico 2010 do estado de São Paulo, que tem 2.2 gb, 224 colunas e 4038218 linhas. Importou em 109.1149 segundos. Meu computador (MacBook Pro) tem processador i7 da primeira geração, 16 gb de ram e ssd. ##------------------------------------------------------ library(MonetDB.R) #criando um banco de dados startscript <- monetdb.server.setup( database.directory = paste0( getwd() , "/MonetDB" ) , "", dbname = "db1", dbport = 50002 ) pid <- monetdb.server.start(startscript) conn <- dbConnect(MonetDB.R(), "monetdb://localhost:50002/db1") # 224 colunas # 4038218 linhas # arquivo com 2.2 GB # 109.149 segundos system.time({ monetdb.read.csv(conn, 'censo00sp1.csv', "censo00sp", 4038218) }) ##------------------------------------------------------ Att Roney --- Este email está limpo de vírus e malwares porque a proteção do avast! Antivírus está ativa. http://www.avast.com

Mauro, eu testei aqui em uma máquina virtual com Windows e funcionou. segue o código: http://dpaste.com/0Y260HW <http://dpaste.com/0Y260HW> Contudo, eu instalei o programa MonetDB no Windows. Segue link: https://www.monetdb.org/Home <https://www.monetdb.org/Home> Att Roney

Experimenta o pacote ff Edson Lira Estatístico Manaus-Amazonas Em Domingo, 26 de Outubro de 2014 16:22, Mauro Sznelwar <sznelwar@uol.com.br> escreveu: <!--#yiv1316119439 _filtered #yiv1316119439 {font-family:Calibri;panose-1:2 15 5 2 2 2 4 3 2 4;}#yiv1316119439 #yiv1316119439 p.yiv1316119439MsoNormal, #yiv1316119439 li.yiv1316119439MsoNormal, #yiv1316119439 div.yiv1316119439MsoNormal {margin:0cm;margin-bottom:.0001pt;font-size:12.0pt;font-family:"Times New Roman", "serif";}#yiv1316119439 a:link, #yiv1316119439 span.yiv1316119439MsoHyperlink {color:blue;text-decoration:underline;}#yiv1316119439 a:visited, #yiv1316119439 span.yiv1316119439MsoHyperlinkFollowed {color:purple;text-decoration:underline;}#yiv1316119439 span.yiv1316119439EstiloDeEmail17 {font-family:"Calibri", "sans-serif";color:#1F497D;}#yiv1316119439 .yiv1316119439MsoChpDefault {font-size:10.0pt;} _filtered #yiv1316119439 {margin:70.85pt 3.0cm 70.85pt 3.0cm;}#yiv1316119439 div.yiv1316119439Section1 {}-->Existeeste pacote para o Windows? Tentei baixar e disse que não está disponível paraa versão R 3.1 Pessoal, eu fiz um teste com o MonetDB importando um arquivocsv do censo demográfico 2010 do estado de São Paulo, que tem 2.2 gb, 224colunas e 4038218 linhas. Importou em 109.1149 segundos. Meu computador (MacBook Pro) tem processador i7 da primeirageração, 16 gb de ram e ssd. ##------------------------------------------------------ library(MonetDB.R) #criando um banco de dados startscript <- monetdb.server.setup( database.directory = paste0( getwd() , "/MonetDB" ) , "", dbname ="db1", dbport =50002 ) pid <- monetdb.server.start(startscript) conn <- dbConnect(MonetDB.R(), "monetdb://localhost:50002/db1") # 224 colunas # 4038218 linhas # arquivo com 2.2 GB # 109.149 segundos system.time({ monetdb.read.csv(conn, 'censo00sp1.csv',"censo00sp", 4038218) }) ##------------------------------------------------------ Att Roney | | Este email está limpo de vírus e malwares porque a proteção do avast! Antivírus está ativa. | _______________________________________________ R-br mailing list R-br@listas.c3sl.ufpr.br https://listas.inf.ufpr.br/cgi-bin/mailman/listinfo/r-br Leia o guia de postagem (http://www.leg.ufpr.br/r-br-guia) e forneça código mínimo reproduzível.

Se você tiver memória ram suficiente, experimente o fread do data.table. abçs M 2014-10-27 10:19 GMT-02:00 Edson Lira <edinhoestat@yahoo.com.br>:
Experimenta o pacote ff
Edson Lira Estatístico Manaus-Amazonas
Em Domingo, 26 de Outubro de 2014 16:22, Mauro Sznelwar < sznelwar@uol.com.br> escreveu:
Existe este pacote para o Windows? Tentei baixar e disse que não está disponível para a versão R 3.1
Pessoal, eu fiz um teste com o MonetDB importando um arquivo csv do censo demográfico 2010 do estado de São Paulo, que tem 2.2 gb, 224 colunas e 4038218 linhas. Importou em 109.1149 segundos.
Meu computador (MacBook Pro) tem processador i7 da primeira geração, 16 gb de ram e ssd.
##------------------------------------------------------ library(MonetDB.R)
#criando um banco de dados startscript <- monetdb.server.setup( database.directory = paste0( getwd() , "/MonetDB" ) , "", dbname = "db1", dbport = 50002 ) pid <- monetdb.server.start(startscript) conn <- dbConnect(MonetDB.R(), "monetdb://localhost:50002/db1")
# 224 colunas # 4038218 linhas # arquivo com 2.2 GB # 109.149 segundos system.time({ monetdb.read.csv(conn, 'censo00sp1.csv', "censo00sp", 4038218) }) ##------------------------------------------------------
Att Roney
------------------------------ <http://www.avast.com/> Este email está limpo de vírus e malwares porque a proteção do avast! Antivírus <http://www.avast.com/> está ativa.
_______________________________________________ R-br mailing list R-br@listas.c3sl.ufpr.br https://listas.inf.ufpr.br/cgi-bin/mailman/listinfo/r-br Leia o guia de postagem (http://www.leg.ufpr.br/r-br-guia) e forneça código mínimo reproduzível.
_______________________________________________ R-br mailing list R-br@listas.c3sl.ufpr.br https://listas.inf.ufpr.br/cgi-bin/mailman/listinfo/r-br Leia o guia de postagem (http://www.leg.ufpr.br/r-br-guia) e forneça código mínimo reproduzível.
-- Manoel Galdino https://sites.google.com/site/galdinomcz/

Uma antiga solução para arquivos grandes que já usei é ler de um texto comprimido. O R é muito eficiente em comprimir e descomprimir eles. Talvez, isso a seja a solução "nativa" mais simples, porém não tanto eficiente. read.table("dados.txt", sep=",") read.table("dados.txt.gz", sep=",") D 2014-10-27 11:05 GMT-02:00 Manoel Galdino <mcz.fea@gmail.com>:
Se você tiver memória ram suficiente, experimente o fread do data.table.
abçs M
2014-10-27 10:19 GMT-02:00 Edson Lira <edinhoestat@yahoo.com.br>:
Experimenta o pacote ff
Edson Lira Estatístico Manaus-Amazonas
Em Domingo, 26 de Outubro de 2014 16:22, Mauro Sznelwar <sznelwar@uol.com.br> escreveu:
Existe este pacote para o Windows? Tentei baixar e disse que não está disponível para a versão R 3.1
Pessoal, eu fiz um teste com o MonetDB importando um arquivo csv do censo demográfico 2010 do estado de São Paulo, que tem 2.2 gb, 224 colunas e 4038218 linhas. Importou em 109.1149 segundos.
Meu computador (MacBook Pro) tem processador i7 da primeira geração, 16 gb de ram e ssd.
##------------------------------------------------------ library(MonetDB.R)
#criando um banco de dados startscript <- monetdb.server.setup( database.directory = paste0( getwd() , "/MonetDB" ) , "", dbname = "db1", dbport = 50002 ) pid <- monetdb.server.start(startscript) conn <- dbConnect(MonetDB.R(), "monetdb://localhost:50002/db1")
# 224 colunas # 4038218 linhas # arquivo com 2.2 GB # 109.149 segundos system.time({ monetdb.read.csv(conn, 'censo00sp1.csv', "censo00sp", 4038218) }) ##------------------------------------------------------
Att Roney
________________________________ Este email está limpo de vírus e malwares porque a proteção do avast! Antivírus está ativa.
_______________________________________________ R-br mailing list R-br@listas.c3sl.ufpr.br https://listas.inf.ufpr.br/cgi-bin/mailman/listinfo/r-br Leia o guia de postagem (http://www.leg.ufpr.br/r-br-guia) e forneça código mínimo reproduzível.
_______________________________________________ R-br mailing list R-br@listas.c3sl.ufpr.br https://listas.inf.ufpr.br/cgi-bin/mailman/listinfo/r-br Leia o guia de postagem (http://www.leg.ufpr.br/r-br-guia) e forneça código mínimo reproduzível.
-- Manoel Galdino https://sites.google.com/site/galdinomcz/
_______________________________________________ R-br mailing list R-br@listas.c3sl.ufpr.br https://listas.inf.ufpr.br/cgi-bin/mailman/listinfo/r-br Leia o guia de postagem (http://www.leg.ufpr.br/r-br-guia) e forneça código mínimo reproduzível.

Walmes, Muito legal a dica de usar o shell para isso. O shell e' sempre mais rapido que qualquer coisa! Sobre ler dados do ENEM, usando fread() do pacote 'data.table' demorou 210 segundos no meu laptop para dados 2012 do ENEM. Eu nao gostei muito do INEP ter disponibilizado o formato .csv. Anteriormente, dados de 2010 por exemplo, usava-se o formato fixed width. Usando uma funcao (descrita em http://www.leg.ufpr.br/doku.php/disciplinas:ce223101:historico2010) demorou 238 segundos para ler os dados de 2010 (4.6 milhoes de linhas) e selecionar prova de matematica dos alunos do Parana. Essa funcao que usei para ler (e SELECIONAR linhas, colunas) fixed width usa a mesma ideia que voce fez usando read.table(). A diferenca e' que eu abro uma coneccao apenas e uso readLines(). O que voce fez com read.table() e' ineficiente porque ao ler cada bloco e' feita uma nova coneccao com o arquivo (via funcao scan()) e ao ler o i-e'simo bloco a funcao scan() precisa percorrer todos os dados dos blocos anteriores antes de comecar a ler. Assim, para ler os ultimos blocos demora-se um tempo enorme percorrendo... Abs, Elias. On 25/10/14 00:22, walmes . wrote:
Saudações,
Essa mensagem é apenas para compartilhar uma experiência que tive e considero que o problema aqui discutido não seja tão particular.
Fui procurado por alguém que precisava processar um arquivo com resultados da prova do ENEM 2012 para aplicar teoria de resposta ao item. Precisava-se processar o arquivo original para chegar em um que tivesse apenas 5 das 80 colunas (notas para as competências sobre a redação) e somente às linhas que tivessem o conteúdo "P" (de presente) para a coluna "IN_STATUS_REDACAO". O arquivo é um csv, delimitador vírgula, aspas nas strings, 5791066 de linhas, 3.8 GB. Fiz o que me veio na cabeça de primeira: "dividir para conquistar". Lia porções de 30 mil linhas do arquivo (usando na read.table() o skip= e nrow=), separava as 5 colunas, mantinha só as linhas com registro P e escrevia para um arquivo com write.table(..., append=TRUE). Isso dentro de um for(). Na minha implementação, um tanto ingenua e corrida porque fiz enquanto era assistido a programar, quanto apliquei ao arquivo alvo levou 3h40. Esperava que fosse demorar mas não tanto. Minha máquina tem 16 GB de RAM. Sabendo que o bash do linux é muito eficiente para tarefas como operações em arquivos texto, eu fui buscar na internet como fazer o mesmo. Resultado é que tudo se resolveu com 37 segundos!!! É por isso que achei interessante compartilhar com a lista, inclusive para saber se alguem tem meios alternativos para solucionar o problema. Seguem os comandos que apliquei no terminal do Linux. Os dados fornecidos no exemplo são apenas as 10 mil primeiras linhas do arquivo original.
##----------------------------------------------------------------------------- ## 0. Aquisição dos dados. Apenas 10000 registros dos 5791066 do arquivo ## original.
wget http://www.leg.ufpr.br/~walmes/data/DADOS_ENEM_2012_10millinhas.csv <http://www.leg.ufpr.br/%7Ewalmes/data/DADOS_ENEM_2012_10millinhas.csv> -O DADOS_ENEM_2012.csv ls wc -l DADOS_ENEM_2012.csv
##----------------------------------------------------------------------------- ## 1. Filtrar só às colunas de interesse. Da 74 à 79. Na 74 tem-se os ## valores P, F e outros.
cut -d , -f 74-79 DADOS_ENEM_2012.csv > file.csv head -10 file.csv wc -l file.csv
##----------------------------------------------------------------------------- ## 2. Manter só as linhas com ocorrência do P.
grep "P" file.csv > fileP.csv wc -l fileP.csv head -10 fileP.csv
##----------------------------------------------------------------------------- ## 3. Remover à colunas com P, ou seja, manter da 2 à 6.
cut -d , -f 2-6 fileP.csv > file.csv head -10 file.csv wc -l file.csv
##----------------------------------------------------------------------------- ## 4. Remover as aspas para salvar espaço em disco.
sed 's/\"//g' file.csv > fileP.csv head -10 fileP.csv
##----------------------------------------------------------------------------- ## 5. Como contar o número de linhas repetidas. Gerar tabela de frequência dos ## padrões de resposta. Economiza espaço e é a informação mínima ## necessária para ajustar TRI. Remover o cabeçalho.
sed 1d fileP.csv > file.csv sort file.csv | uniq --count > fileP.csv head -10 fileP.csv tail -10 fileP.csv
##----------------------------------------------------------------------------- ## 6. Eliminar espaços no ínicio e colocar uma vírgula entre a ## frequência e o primeiro registro para que todos os campos sejam ## separados por `,`.
sed -e 's/^ *//;s/ /,/' fileP.csv > fileFreq.csv head -10 fileFreq.csv wc -l fileFreq.csv
##-----------------------------------------------------------------------------
À disposição. Walmes.
========================================================================== Walmes Marques Zeviani LEG (Laboratório de Estatística e Geoinformação, 25.450418 S, 49.231759 W) Departamento de Estatística - Universidade Federal do Paraná fone: (+55) 41 3361 3573 skype: walmeszeviani homepage: http://www.leg.ufpr.br/~walmes <http://www.leg.ufpr.br/%7Ewalmes> linux user number: 531218 ==========================================================================
_______________________________________________ R-br mailing list R-br@listas.c3sl.ufpr.br https://listas.inf.ufpr.br/cgi-bin/mailman/listinfo/r-br Leia o guia de postagem (http://www.leg.ufpr.br/r-br-guia) e forneça código mínimo reproduzível.

com fread() e' possivel ainda selecionar colunas. Para trazer as respostas a prova de matematica, o gabarito e o escore demorou 14 segundos... system.time(all <- fread("../dados/dados2012/DADOS/DADOS_ENEM_2012.csv", select=c(64, 73, 78))) Read 5791065 rows and 3 (of 80) columns from 3.522 GB file in 00:00:12 user system elapsed 10.874 0.898 14.126 On 26/10/14 12:23, Elias T. Krainski wrote:
Walmes,
Muito legal a dica de usar o shell para isso. O shell e' sempre mais rapido que qualquer coisa!
Sobre ler dados do ENEM, usando fread() do pacote 'data.table' demorou 210 segundos no meu laptop para dados 2012 do ENEM. Eu nao gostei muito do INEP ter disponibilizado o formato .csv. Anteriormente, dados de 2010 por exemplo, usava-se o formato fixed width. Usando uma funcao (descrita em http://www.leg.ufpr.br/doku.php/disciplinas:ce223101:historico2010) demorou 238 segundos para ler os dados de 2010 (4.6 milhoes de linhas) e selecionar prova de matematica dos alunos do Parana.
Essa funcao que usei para ler (e SELECIONAR linhas, colunas) fixed width usa a mesma ideia que voce fez usando read.table(). A diferenca e' que eu abro uma coneccao apenas e uso readLines(). O que voce fez com read.table() e' ineficiente porque ao ler cada bloco e' feita uma nova coneccao com o arquivo (via funcao scan()) e ao ler o i-e'simo bloco a funcao scan() precisa percorrer todos os dados dos blocos anteriores antes de comecar a ler. Assim, para ler os ultimos blocos demora-se um tempo enorme percorrendo...
Abs, Elias.
On 25/10/14 00:22, walmes . wrote:
Saudações,
Essa mensagem é apenas para compartilhar uma experiência que tive e considero que o problema aqui discutido não seja tão particular.
Fui procurado por alguém que precisava processar um arquivo com resultados da prova do ENEM 2012 para aplicar teoria de resposta ao item. Precisava-se processar o arquivo original para chegar em um que tivesse apenas 5 das 80 colunas (notas para as competências sobre a redação) e somente às linhas que tivessem o conteúdo "P" (de presente) para a coluna "IN_STATUS_REDACAO". O arquivo é um csv, delimitador vírgula, aspas nas strings, 5791066 de linhas, 3.8 GB. Fiz o que me veio na cabeça de primeira: "dividir para conquistar". Lia porções de 30 mil linhas do arquivo (usando na read.table() o skip= e nrow=), separava as 5 colunas, mantinha só as linhas com registro P e escrevia para um arquivo com write.table(..., append=TRUE). Isso dentro de um for(). Na minha implementação, um tanto ingenua e corrida porque fiz enquanto era assistido a programar, quanto apliquei ao arquivo alvo levou 3h40. Esperava que fosse demorar mas não tanto. Minha máquina tem 16 GB de RAM. Sabendo que o bash do linux é muito eficiente para tarefas como operações em arquivos texto, eu fui buscar na internet como fazer o mesmo. Resultado é que tudo se resolveu com 37 segundos!!! É por isso que achei interessante compartilhar com a lista, inclusive para saber se alguem tem meios alternativos para solucionar o problema. Seguem os comandos que apliquei no terminal do Linux. Os dados fornecidos no exemplo são apenas as 10 mil primeiras linhas do arquivo original.
##----------------------------------------------------------------------------- ## 0. Aquisição dos dados. Apenas 10000 registros dos 5791066 do arquivo ## original.
wget http://www.leg.ufpr.br/~walmes/data/DADOS_ENEM_2012_10millinhas.csv <http://www.leg.ufpr.br/%7Ewalmes/data/DADOS_ENEM_2012_10millinhas.csv> -O DADOS_ENEM_2012.csv ls wc -l DADOS_ENEM_2012.csv
##----------------------------------------------------------------------------- ## 1. Filtrar só às colunas de interesse. Da 74 à 79. Na 74 tem-se os ## valores P, F e outros.
cut -d , -f 74-79 DADOS_ENEM_2012.csv > file.csv head -10 file.csv wc -l file.csv
##----------------------------------------------------------------------------- ## 2. Manter só as linhas com ocorrência do P.
grep "P" file.csv > fileP.csv wc -l fileP.csv head -10 fileP.csv
##----------------------------------------------------------------------------- ## 3. Remover à colunas com P, ou seja, manter da 2 à 6.
cut -d , -f 2-6 fileP.csv > file.csv head -10 file.csv wc -l file.csv
##----------------------------------------------------------------------------- ## 4. Remover as aspas para salvar espaço em disco.
sed 's/\"//g' file.csv > fileP.csv head -10 fileP.csv
##----------------------------------------------------------------------------- ## 5. Como contar o número de linhas repetidas. Gerar tabela de frequência dos ## padrões de resposta. Economiza espaço e é a informação mínima ## necessária para ajustar TRI. Remover o cabeçalho.
sed 1d fileP.csv > file.csv sort file.csv | uniq --count > fileP.csv head -10 fileP.csv tail -10 fileP.csv
##----------------------------------------------------------------------------- ## 6. Eliminar espaços no ínicio e colocar uma vírgula entre a ## frequência e o primeiro registro para que todos os campos sejam ## separados por `,`.
sed -e 's/^ *//;s/ /,/' fileP.csv > fileFreq.csv head -10 fileFreq.csv wc -l fileFreq.csv
##-----------------------------------------------------------------------------
À disposição. Walmes.
========================================================================== Walmes Marques Zeviani LEG (Laboratório de Estatística e Geoinformação, 25.450418 S, 49.231759 W) Departamento de Estatística - Universidade Federal do Paraná fone: (+55) 41 3361 3573 skype: walmeszeviani homepage: http://www.leg.ufpr.br/~walmes <http://www.leg.ufpr.br/%7Ewalmes> linux user number: 531218 ==========================================================================
_______________________________________________ R-br mailing list R-br@listas.c3sl.ufpr.br https://listas.inf.ufpr.br/cgi-bin/mailman/listinfo/r-br Leia o guia de postagem (http://www.leg.ufpr.br/r-br-guia) e forneça código mínimo reproduzível.
_______________________________________________ R-br mailing list R-br@listas.c3sl.ufpr.br https://listas.inf.ufpr.br/cgi-bin/mailman/listinfo/r-br Leia o guia de postagem (http://www.leg.ufpr.br/r-br-guia) e forneça código mínimo reproduzível.
participantes (8)
-
Daniel Marcelino
-
David Feitosa
-
Edson Lira
-
Elias T. Krainski
-
Manoel Galdino
-
Mauro Sznelwar
-
Roney Fraga Souza
-
walmes .