sql – R中大文件的操作
发布时间:2020-12-12 06:21:32 所属栏目:MsSql教程 来源:网络整理
导读:我有15个数据文件,每个大约4.5GB.每个文件是大约17,000个客户的数月数据.总之,这些数据代表了15个月内17,000名客户的信息.我想重新格式化这些数据,而不是每个表示一个月的15个文件,每个客户及其所有数据都有17,000个文件.我写了一个脚本来做到这一点: #the v
我有15个数据文件,每个大约4.5GB.每个文件是大约17,000个客户的数月数据.总之,这些数据代表了15个月内17,000名客户的信息.我想重新格式化这些数据,而不是每个表示一个月的15个文件,每个客户及其所有数据都有17,000个文件.我写了一个脚本来做到这一点:
#the variable 'files' is a vector of locations of the 15 month files exists = NULL #This vector keeps track of customers who have a file created for them for (w in 1:15){ #for each of the 15 month files month = fread(files[w],select = c(2,3,6,16)) #read in the data I want custlist = unique(month$CustomerID) #a list of all customers in this month file for (i in 1:length(custlist)){ #for each customer in this month file curcust = custlist[i] #the current customer newchunk = subset(month,CustomerID == curcust) #all the data for this customer filename = sprintf("cust%s",curcust) #what the filename is for this customer will be,or is if ((curcust %in% exists) == TRUE){ #check if a file has been created for this customer. If a file has been created,open it,add to it,and read it back custfile = fread(strwrap(sprintf("C:/custFiles/%s.csv",filename)))#read in file custfile$V1 = NULL #remove an extra column the fread adds custfile= rbind(custfile,newchunk)#combine read in data with our new data write.csv(custfile,file = strwrap(sprintf("C:/custFiles/%s.csv",filename))) } else { #if it has not been created,write newchunk to a csv write.csv(newchunk,filename))) exists = rbind(exists,curcust,deparse.level = 0) #add customer to list of existing files } } } 该脚本有效(至少,我很确定).问题是它非常慢.按照我要的速度,它需要一周或更长时间才能完成,我没有那个时间.你们中的任何一个人在R中做得更好,更快捷吗?我应该尝试在像SQL这样的事情吗?我以前从未真正使用过SQL;你们中的任何人都可以告诉我这样的事情会怎样吗?非常感谢任何输入. 解决方法作为@Dominic Comtois,我也建议使用SQL.R可以处理相当大的数据 – 有20亿行的好基准比python好 – 但是因为R主要在内存中运行,所以你需要有一台好的机器来使它工作.您的情况仍然不需要一次加载超过4.5GB的文件,所以它应该在个人计算机上可行,请参见快速非数据库解决方案的第二种方法. 您可以使用R将数据加载到SQL数据库,稍后从数据库中查询它们. 如果您不了解SQL,可能需要使用一些简单的数据库. R的最简单方法是使用RSQLite(不幸的是,从v1.1开始它不再是精简版).您无需安装或管理任何外部依赖项. RSQLite包中包含嵌入的数据库引擎. library(RSQLite) library(data.table) conn <- dbConnect(dbDriver("SQLite"),dbname="mydbfile.db") monthfiles <- c("month1","month2") # ... # write data for(monthfile in monthfiles){ dbWriteTable(conn,"mytablename",fread(monthfile),append=TRUE) cat("data for",monthfile,"loaded to dbn") } # query data df <- dbGetQuery(conn,"select * from mytablename where customerid = 1") # when working with bigger sets of data I would recommend to do below setDT(df) dbDisconnect(conn) 就这样.您使用SQL而不必通常与数据库相关的开销很大. 如果您更喜欢使用帖子中的方法,我认为通过在data.table中进行聚合时按组执行write.csv可以大大加快速度. library(data.table) monthfiles <- c("month1","month2") # ... # write data for(monthfile in monthfiles){ fread(monthfile)[,write.csv(.SD,file=paste0(CustomerID,".csv"),append=TRUE),by=CustomerID] cat("data for","written to csvn") } 因此,您可以在data.table中使用快速唯一,并在分组时执行子集,这也是超快的.以下是该方法的工作示例. library(data.table) data.table(a=1:4,b=5:6)[,file=paste0(b,".csv")),b] 更新2016-12-05: (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |