2016-12-01 12 views
1

У меня большой CSV-файл (более 6 ГБ). Предварительный просмотр файла приведен ниже:Найти разницу в двух столбцах в CSV и сохранить в третьем столбце в кусках

ID,NUM,MMSRATE,SMSRATE,DATARATE 
1,0100000109,623,233,331 
2,0200000109,515,413,314 
3,0600000109,611,266,662 
4,0700000109,729,490,927 
5,0800000109,843,637,736 
6,0600000109,578,367,875 

Я хочу, чтобы найти разницу MMSRATE И SMSRATE и сохранить его в новом PDRATE колонке в том же файле CSV. Предварительный просмотр приведен ниже:

ID,NUM,MMSRATE,SMSRATE,DATARATE,PDRATE 
1,0100000109,623,233,333,390 
2,0200000109,515,413,314,102 

У меня около 1 миллиона строк. Я хочу прочитать строки в кусках (скажем, 20000), выполнить разностную операцию, затем записать ее в выходной файл CSV, затем прочитать следующие 20000 строк, выполнить операции над этим и записать их в выходной CSV-файл и так далее ,

Я написал код для чтения строк в кусках (из 2 для случая простоты), но я не могу выполнить разницу в двух столбцах внутри моего скрипта. Код приведен ниже:

chunk_size <- 2 
con <- file("input.csv", open = "r") 
data_frame <- read.csv(con,nrows = chunk_size,quote="",header = TRUE,) 
header <- names(data_frame) 
print(header) 
print(data_frame) 
if(nrow(data_frame) == chunk_size) { 
repeat { 
    data_frame <- read.csv(con,nrows = chunk_size, header = FALSE, quote="") 
    names(data_frame)<-c(header) 
    print(header) 
    print(data_frame) 
    if(nrow(data_frame) < chunk_size) { 
    break 
    } 
} 
} 

close(con) 

Я довольно новичок в Rscript. Я запускаю R Studio IDE в Windows.

ПРИМЕЧАНИЕ: Ведущий нуль в столбце NUM следует сохранить в выходном файле CSV FILE. Обратите внимание, что это требование, что я работаю над CHUNKS строк из CSV, а не из CSV-файла в целом.

+0

Почему вы не можете сразу прочитать строку 1M? Это не так уж и много. то это всего лишь 'df $ PTDR <- df $ MMSRATE - df $ SMSRATE' за один проход. – Tensibai

+0

И если это всего лишь вопрос csv, вероятно, лучше всего подходит awk: 'awk -F", "-v OFS =", "'NR == 1 {print $ 0," PDRATE "} NR> 1 {end = $ 3 - $ 4; print $ 0, end} 'your_file.csv' – Tensibai

+0

@Tensibai Это было требование, данное мне, т. е. выполнить разностную операцию coloumn на кусках строк из csv. Поэтому я не могу прочитать весь CSV-файл в целом. Можете ли вы предложить возможные решения. – Raymond

ответ

3

Если я понял, сначала создайте выходной файл, затем выполните изменения и напишите результат на выходе, добавив на каждой итерации.

chunk_size <- 2 
con <- file("input.csv", open = "r") 
data_frame <- read.csv(con,nrows = chunk_size,quote="",colClasses = c("integer","character","integer","integer","integer"), header = TRUE,) 
header <- names(data_frame) 

outfile="out.csv" 
data_frame$PDRATE <- data_frame$MMSRATE - data_frame$SMSRATE 
write.csv(data_frame,outfile,row.names=FALSE) 

if(nrow(data_frame) == chunk_size) { 
repeat { 
    data_frame <- read.csv(con,nrows = chunk_size, colClasses = c("integer","character","integer","integer","integer"), header = FALSE, quote="") 
    names(data_frame)<-c(header) 

    data_frame$PDRATE <- data_frame$MMSRATE - data_frame$SMSRATE 
    # note parameters, append=TRUE and col.names=FALSE 
    write.table(data_frame,outfile,sep=",",append=TRUE,qmethod="double",col.names=FALSE,row.names=FALSE) 

    if(nrow(data_frame) < chunk_size) { 
    break 
    } 
} 
} 

close(con) 

Понимание выше код остается в качестве упражнения :)

примечания после комментариев: Вы не можете добавлять с write.csv, состояние документации:

Попытки изменить Append, Col .names, sep, dec или qmethod игнорируются с предупреждением.

Вы должны использовать write.table и указать разделитель и qmethod, чтобы соответствовать значениям по умолчанию write.csv.

+0

Предупреждающие сообщения: 1: В write.csv (data_frame, outfile, append = TRUE, col.names = FALSE,: попытка установки 'append' игнорируется. – Raymond

+0

Операция append не выполняется. csv сохраняет только значения, присутствующие в последней итерации. – Raymond

+0

И вы прочитали справку write.csv? – Tensibai

0

я наткнулся на интересный пакет chunked

Решение 1

require(chunked) 
data <- read_csv_chunkwise("Test.csv") %>% mutate(diff = MMSRATE - SMSRATE) 

    ID  NUM MMSRATE SMSRATE DATARATE diff 
    (int)  (int) (int) (int) (int) (int) 
1  1 100000109  623  233  331 390 
2  2 200000109  515  413  314 102 
3  3 600000109  611  266  662 345 
4  4 700000109  729  490  927 239 
5  5 800000109  843  637  736 206 
6  6 600000109  578  367  875 211 

вы можете указать размер порции, прочитайте документацию.

Решение 2

Если вы намеревались использовать datatable

использовать fread читать файл CSV

require(data.table) 
mydata <- fread("file.csv", sep = ",", header= TRUE) 

Fread создает data.table

Затем, вам необходимо сделать

mydata [ ,`:=`(Diffcol = MMSRATE-SMSRATE)] 
mydata 

ID  NUM MMSRATE SMSRATE DATARATE Diffcol 
1: 1 0100000109  623  233  331  390 
2: 2 0200000109  515  413  314  102 
3: 3 0600000109  611  266  662  345 
4: 4 0700000109  729  490  927  239 
5: 5 0800000109  843  637  736  206 
6: 6 0600000109  578  367  875  211 

Примечание: datatable - очень ручной инструмент для работы с большими файлами. Кроме того, вы можете группировать вывод таблицы и другие вычисления. Вы можете узнать больше об этом Cheat sheet

+2

Не редактируйте вопрос, чтобы сломать их mcve. Вход csv отлично подходит для mcve и более полезен, чем столбец. особенно когда Q идет о работе с csv-файлами. – Tensibai

+1

Я понял это после редактирования. Благодарю. Будем иметь в виду – user5249203

 Смежные вопросы

  • Нет связанных вопросов^_^