找出CSV中两列的差异,并以块的形式存储在第三列中

时间:2016-12-01 13:23:06

标签: r csv chunks

我有一个大的CSV文件(大于6GB)。该文件的预览如下:

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的区别,并将其存储在同一csv文件中的新列PDRATE中。预览如下:

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

我有大约100万行。我想读取(例如20000)的行中的行,执行差异操作,然后将其写入输出CSV文件,然后读取下一行20000行,对其执行操作并将其写入输出CSV文件,依此类推

我编写了一个用于读取块中行的代码(简单情况下为2),但是我无法在脚本中执行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很新。我在Windows中运行R Studio IDE。

注意:NUM列中的前导零应保留在输出CSV文件中。请注意,我需要处理CSV中的CHUNKS行,而不是整个CSV文件。

2 个答案:

答案 0 :(得分: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默认值。

答案 1 :(得分: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

了解更多信息