Então, eu tenho um arquivo de dados (separados por ponto-e-vírgula) que tem muitos detalhes e linhas incompletas (levando o Access e o SQL a engasgar). É o conjunto de dados em nível de condado dividido em segmentos, subsegmentos e subsegmentos (para um total de aproximadamente 200 fatores) por 40 anos. Resumindo, é enorme e não vai caber na memória se eu tentar simplesmente lê-lo.
Portanto, minha pergunta é esta, visto que quero todos os condados, mas apenas um único ano (e apenas o nível mais alto de segmento ... levando a cerca de 100.000 linhas no final), qual seria a melhor maneira de proceder para obter este rollup em R?
Atualmente estou tentando cortar anos irrelevantes com Python, contornando o limite de tamanho de arquivo lendo e operando em uma linha de cada vez, mas prefiro uma solução apenas R (pacotes CRAN OK). Existe uma maneira semelhante de ler arquivos um pedaço por vez no R?
Quaisquer ideias seriam muito apreciadas.
Atualizar:
- Restrições
- Precisa usar minha máquina, portanto, nenhuma instância EC2
- O mais R-only possível. Velocidade e recursos não são preocupações neste caso ... desde que minha máquina não exploda ...
- Como você pode ver abaixo, os dados contêm tipos mistos, que preciso operar mais tarde
- Dados
- Os dados são 3,5 GB, com cerca de 8,5 milhões de linhas e 17 colunas
- Alguns milhares de linhas (~ 2k) estão malformadas, com apenas uma coluna em vez de 17
- Estes são totalmente sem importância e podem ser descartados
- Eu só preciso de cerca de 100.000 linhas deste arquivo (veja abaixo)
Exemplo de dados:
County; State; Year; Quarter; Segment; Sub-Segment; Sub-Sub-Segment; GDP; ...
Ada County;NC;2009;4;FIRE;Financial;Banks;80.1; ...
Ada County;NC;2010;1;FIRE;Financial;Banks;82.5; ...
NC [Malformed row]
[8.5 Mill rows]
Quero cortar algumas colunas e escolher dois dos 40 anos disponíveis (2009-2010 de 1980-2020), para que os dados possam caber em R:
County; State; Year; Quarter; Segment; GDP; ...
Ada County;NC;2009;4;FIRE;80.1; ...
Ada County;NC;2010;1;FIRE;82.5; ...
[~200,000 rows]
Resultados:
Depois de mexer em todas as sugestões feitas, decidi que readLines, sugerido por JD e Marek, funcionaria melhor. Dei o cheque a Marek porque ele deu uma implementação de amostra.
Reproduzi uma versão ligeiramente adaptada da implementação de Marek para minha resposta final aqui, usando strsplit e cat para manter apenas as colunas que desejo.
Também deve ser notado que isso é MUITO menos eficiente do que Python ... como em, Python chomps através do arquivo de 3,5 GB em 5 minutos enquanto R leva cerca de 60 ... mas se tudo que você tem é R, então este é o bilhete.
## Open a connection separately to hold the cursor position
file.in <- file('bad_data.txt', 'rt')
file.out <- file('chopped_data.txt', 'wt')
line <- readLines(file.in, n=1)
line.split <- strsplit(line, ';')
# Stitching together only the columns we want
cat(line.split[[1]][1:5], line.split[[1]][8], sep = ';', file = file.out, fill = TRUE)
## Use a loop to read in the rest of the lines
line <- readLines(file.in, n=1)
while (length(line)) {
line.split <- strsplit(line, ';')
if (length(line.split[[1]]) > 1) {
if (line.split[[1]][3] == '2009') {
cat(line.split[[1]][1:5], line.split[[1]][8], sep = ';', file = file.out, fill = TRUE)
}
}
line<- readLines(file.in, n=1)
}
close(file.in)
close(file.out)
Falhas por abordagem:
- sqldf
- Definitivamente, é isso que usarei para esse tipo de problema no futuro, se os dados estiverem bem formados. No entanto, se não for, o SQLite engasga.
- MapReduce
- Para ser honesto, os médicos me intimidaram um pouco, então não tive tempo de tentar. Parecia que era necessário que o objeto estivesse na memória também, o que invalidaria o ponto se fosse esse o caso.
- grande memória
- Essa abordagem vincula claramente os dados, mas só pode lidar com um tipo de cada vez. Como resultado, todos os meus vetores de caracteres caíram quando colocados em uma tabela grande. Se eu precisar projetar grandes conjuntos de dados para o futuro, porém, consideraria usar apenas números apenas para manter essa opção viva.
- Varredura
- A digitalização parecia ter problemas de tipo semelhantes aos de grande memória, mas com toda a mecânica de readLines. Em suma, simplesmente não se encaixava no projeto desta vez.
sed
e / ouawk
criar uma versão reduzida do CSV que possa ser lida diretamente. Visto que isso é mais uma solução alternativa do que uma resposta, vou deixar como um comentário.