使用循环自动对R中的大数据进行分块

时间:2014-10-14 23:28:32

标签: r chunking

我试图将一个非常大的数据集分成块。我的代码看起来像这样:

#Chunk 1
data <- read.csv("/Users/admin/Desktop/data/sample.csv", header=T, nrow=1000000)
write.csv(data, "/Users/admin/Desktop/data/data1.csv")

#Chunk 2
data <- read.csv("/Users/admin/Desktop/data/sample.csv", header=F, nrow=1000000, skip=1000000)
write.csv(data, "/Users/admin/Desktop/data/data2.csv")

#Chunk 3
data <- read.csv("/Users/admin/Desktop/data/sample.csv", header=F, nrow=1000000, skip=2000000)
write.csv(data, "/Users/admin/Desktop/data/data3.csv")

我的数据集中有数亿行,所以我需要创建很多块,我真的想自动化这个过程。有没有办法循环这个命令,以便每个后续的块自动跳过比前一个块多1,000,000行,并且文件保存为&#34; dataN.csv&#34; (N表示后一个文件的后续编号)?

2 个答案:

答案 0 :(得分:1)

以下方式怎么样?为了演示,我创建了一个包含两列和十行的数据框,并在一个循环内读取两次,每次五行,将结果保存为文本文件:

f<-"C:/Users/MyPC/Desktop/"
for(i in 1:2){
    df <- read.table("C:/Users/MyPC/Desktop/df.txt", header=FALSE, nrow=5, skip=5*(i-1))
    file <- paste(f,sep="","df",i,".txt")
    write.table(df,file)
}

答案 1 :(得分:0)

对上述答案进行了一些改进。使用lapply()而不是read.table()而不是for循环,使用data.table :: fread()。

for loop vs. lapply 已经有很好的文档证明,如果可能的话,应该使用lapply而不是for循环。快速谷歌搜索将显示大量的论据和示例。 lapply更快,它返回一个列表而不是一个必须定义列表(或其他存储对象),并且它可以很容易并行运行,因为循环的每次迭代都是一个独立的函数调用,而不是&#上的循环34;顶级。&#34;在这种情况下,切换到lapply可以节省7秒(这是相当微不足道的,但最好养成良好的习惯)。

read.csv()vs data.table :: fread() fread()是对read.csv()的主要速度提升(我已经看到2-5倍的加速,取决于数据等。here是一篇显示加速度大约15倍的文章)旨在处理一些管理任务,如猜测分隔符。在这种情况下,为read.csv()交换fread()时有15秒的加速比例

> # Libraries and options ---------------------------------------------------
> 
> library(dplyr)

> library(data.table)

> # Helper parameters -------------------------------------------------------
> 
> out_dir = "C:/Users/taylor/Dropbox/R_programming/stackoverflow/data"

> obs = 5e5 

> # Create test data --------------------------------------------------------
> 
> test_df = data_frame(
+   x = rnorm(obs), 
+   y = 0.5 * obs + rnorm(length(x), 0, 0.25), 
+   groups = rep(letters[1:5], length.out = length(x))
+ )

> # export
> write.csv(test_df, paste0(out_dir, "/test_df.csv"), row.names = F)

> # clean memory
> rm(test_df)

> gc()
          used (Mb) gc trigger  (Mb)  max used   (Mb)
Ncells  596408 31.9    1907703 101.9  10636178  568.1
Vcells 9301642 71.0   27768113 211.9 218137457 1664.3

> # For loop and read.csv (read.table alias) -------------------------------------
> 
> system.time({
+   
+   for(i in 1:20){  
+     df = read.csv(paste0(out_dir, "/test_df.csv"))
+     write.csv(df, paste0(out_dir, "/test_df_export_original_example_", i, ".csv"), row.names = F)  
+   }  
+   
+ })
   user  system elapsed 
 130.28    2.70  148.60 

> # Lapply and read.csv -----------------------------------------------------
> 
> # clean memory
> rm(df, i)

> gc()
          used (Mb) gc trigger  (Mb)  max used   (Mb)
Ncells  596411 31.9    2185242 116.8  10636178  568.1
Vcells 9301647 71.0   27768113 211.9 218137457 1664.3

> system.time({
+   
+   lapply(1:20, function(i){
+     df = read.csv(paste0(out_dir, "/test_df.csv"))
+     write.csv(df, paste0(out_dir, "/test_df_export_lapply_", i, ".csv"), row.names = F)  
+   })  
+   
+ })
   user  system elapsed 
 123.33    2.07  140.03 

> # Lapply and fread() ------------------------------------------------------
> 
> system.time({
+   
+   lapply(1:20, function(i){
+     df = fread(paste0(out_dir, "/test_df.csv"))
+     write.csv(df, paste0(out_dir, "/test_df_export_lapply_fread_", i, ".csv"), row.names = F)  
+   })  
+   
+ })
   user  system elapsed 
 107.98    2.10  123.36