R:将非常大的数据帧分割成片

时间:2019-07-16 21:38:55

标签: r dataframe slice

我在R中有一个大数据框pyyaml<=3.13,其中包含my_df条记录。下面的示例代码行从25001开始获取1000行的块,进行一些处理,并将处理后的数据写入文件到本地磁盘。

1983000

以此类推:

my_df1 <- my_df[25001:26000,]
my_df1$end <- as.POSIXct(paste(my_df1$end,"23:59",sep = ""))
my_df1$year <- lubridate::year(my_df1$start)
str_data <- my_df1
setwd("path_to_local_dir/data25001_26000")
write.table(str_data, file = "data25001-26000.csv",row.names = F,col.names = F,quote = F)

我想自动执行此任务,以便处理1000条记录的大块并将其写入新目录。关于如何做到这一点有什么建议吗?

4 个答案:

答案 0 :(得分:2)

请考虑在函数 data_to_disk 中泛化您的进程,并使用诸如lapply之类的迭代器方法调用函数,并为随后的每千个变量传递一个seq()整数序列。另外,合并动态目录创建功能(但可能将所有1000多个文件转储到一个目录中,而不是1000多个目录中?)。

data_to_disk <- function(num) {
   str_data <- within(my_df[num:(num + 999)], {
                   end <- as.POSIXct(paste0(end, "23:59"))
                   year <- lubridate::year($start)
               })

   my_dir <- paste0("path_to_local_dir/data", num, "_", num + 999)
   if(!dir.exists(my_dir)) dir.create(my_dir)

   write.table(str_data, file = paste0(my_dir, "/", "data", num, "-", num + 999, ".csv"), 
               row.names = FALSE, col.names = FALSE, quote = FALSE)
   return(my_df)
}

seqs <- seq(25001, nrow(my_df), by=1000)
head(seqs)
# [1] 25001 26001 27001 28001 29001 30001
tail(seqs)
# [1] 1977001 1978001 1979001 1980001 1981001 1982001    

# LIST OF 1,958 DATA FRAMES
df_list <- lapply(seqs, data_to_disk)

答案 1 :(得分:1)

这是我的代码执行切片循环:

step1 = 1000
runto = nrow(my_df)
nsteps = ceiling(runto/step1)
for( part in seq_len(nsteps) ) { # part = 1
    cat( part, 'of', nsteps, '\n')
    fr = (part-1)*step1 + 1
    to = min(part*step1, runto)

    my_df1 = my_df[fr:to,]
    # ...
    write.table(str_data, file = paste0("data",fr,"-",to,".csv"))
}
rm(part, step1, runto, nsteps, fr, to)

答案 2 :(得分:1)

您可以先将分组变量添加到数据中(例如,每1000行标识一次),然后使用d_ply()拆分数据并写入文件。

df <- data.frame(var=runif(1000000))
df$fold <- cut(seq(1,nrow(df)),breaks=100,labels=FALSE)

df %>% filter(fold<=2) %>% # only writes first two files
  d_ply(.,.(fold), function(i){
    # make filenames 'data1.csv', 'data2.csv'
    write_csv(i,paste0('data',distinct(i,fold),'.csv')) 
    })

答案 3 :(得分:0)

这类似于@Parfait,但是从函数中删除了很多东西。具体来说,它将创建整个数据集的副本,然后执行时间操作功能。

my_df1 <- my_df
my_df1$end <- as.POSIXct(paste(my_df1$end,"23:59",sep = ""))
my_df1$year <- lubridate::year(my_df1$start)

lapply(seq(25001, nrow(my_df1), by = 1000),
       function(i) write.table(my_df1[i:i+1000-1,]
                               , file = paste0('path_to_logal_dir/data'
                                               , i, '-', i+1000-1, '.csv')
                               ,row.names = F,col.names = F,quote = F)
)

对我来说,我可能会做:

write.table(my_df1, file = ...)

并完成它。我看不到将其拆分的优势-一百万行的数目确实不多。