Разбить большой файл на маленькие файлы в R - PullRequest
0 голосов
/ 13 мая 2018

Мне нужно разбить большой файл (14 гигабайт) на файлы меньшего размера.Формат этого файла txt, вкладка ";"и я знаю, что это имеет 70 столбцов (строка, двойной).Я хотел бы прочитать 1 миллион и сохранить их в разных файлах, file1, file2 ... fileN.

после помощи @MKR

, но процесс был очень медленным, я пытался использовать fread,но это было невозможно.

Как мне оптимизировать этот код?

НОВЫЙ КОД

chunkSize <- 10000
conex <- file(description = db, open = "r")
data <- read.table(conex, nrows = chunkSize, header=T, fill=TRUE, sep =";")

index <- 0
counter <- 0
total <- 0
chunkSize <- 500000 
conex <- file(description=db,open="r")   
dataChunk <- read.table(conex, nrows=chunkSize, header=T, fill=TRUE,sep=";")

repeat {
dataChunk <- read.table(conex, nrows=chunkSize, header=FALSE, fill = TRUE, sep=";", col.names=db_colnames)
total <- total + sum(dataChunk$total)
counter <- counter + nrow(dataChunk)
write.table(dataChunk, file = paste0("MY_FILE_new",index),sep=";", row.names = FALSE)

  if (nrow(dataChunk) != chunkSize){
    print('linesok')
    break}
    index <- index + 1
  print(paste('lines', index * chunkSize))
}

Ответы [ 2 ]

0 голосов
/ 13 мая 2018

Не основанный на R ответ, но в этом случае я рекомендую решение на основе оболочки, использующее GNU split. Это должно быть значительно быстрее, чем решение R.

Чтобы разбить файл на куски, каждый из которых содержит 10^6 строк, вы должны сделать:

split -l 1000000 my_file.txt 

Подробнее о split см., Например, здесь .

0 голосов
/ 13 мая 2018

Вы находитесь на правильном пути, чтобы достичь решения.

The approach should be:

1. Read 1 million lines 
2. Write to new files
3. Read next 1 million lines
4. Write to another new files

Позволяет преобразовать вышеуказанную логику в цикл в строке попытки ОП:

index <- 0
counter <- 0
total <- 0
chunks <- 500000

repeat{
  dataChunk <- read.table(con, nrows=chunks, header=FALSE, fill = TRUE,                 
                          sep=";", col.names=db_colnames)

  # do processing on dataChunk (i.e adding header, converting data type) 

  # Create a new file name and write to it. You can have your own logic for file names 
  write.table(dataChunk, file = paste0("file",index))

  #check if file end has been reached and break from repeat
  if(nrow(dataChunk) < chunks){
    break
  }

  #increment the index to read next chunk
  index = index+1

}

Отредактировано: Изменено для добавлениядругой вариант - чтение файла с использованием data.table::fread в соответствии с запросом OP.

library(data.table)

index <- 0
counter <- 0
total <- 0
chunks <- 1000000
fileName <- "myfile"

repeat{
  # With fread file is opened in each iteration
  dataChunk <- fread(input = fileName, nrows=chunks, header=FALSE, fill = TRUE,                 
                          skip = chunks*index, sep=";", col.names=db_colnames)

  # do processing on dataChunk (i.e adding header, converting data type) 

  # Create a new file name and write to it. You can have your own logic for file names
  write.table(dataChunk, file = paste0("file",index))

  #check if file end has been reached and break from repeat
  if(nrow(dataChunk) < chunks){
    break
  }

  #increment the index to read next chunk
  index = index+1

}

Примечание: Приведенный выше код является просто pseudo code частичного фрагмента, чтобы помочьОП.Он не будет работать и давать результат сам по себе.

...