我有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,file = strwrap(sprintf("C:/custFiles/%s.csv",filename)))
exists = rbind(exists,curcust,deparse.level = 0) #add customer to list of existing files
}
}
}
Run Code Online (Sandbox Code Playgroud)
该脚本有效(至少,我很确定).问题是它非常慢.按照我要的速度,它需要一周或更长的时间才能完成,我没有那个时间.你们中的任何一个人在R中做得更好,更快捷吗?我应该尝试在像SQL这样的事情吗?我以前从未真正使用过SQL; 你们中的任何人都可以告诉我这样的事情会怎样吗?任何输入都非常感谢.
jan*_*cki 16
作为@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 db\n")
}
# 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)
Run Code Online (Sandbox Code Playgroud)
就这样.您使用SQL而不必通常需要做很多通常与数据库相关的开销.
如果您更喜欢使用帖子中的方法,我认为您可以write.csv通过在data.table中进行聚合时按组进行大幅加速.
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",monthfile,"written to csv\n")
}
Run Code Online (Sandbox Code Playgroud)
因此,您可以在data.table中使用快速唯一,并在分组时执行子集,这也是超快的.以下是该方法的工作示例.
library(data.table)
data.table(a=1:4,b=5:6)[,write.csv(.SD,file=paste0(b,".csv")),b]
Run Code Online (Sandbox Code Playgroud)
更新2016年12月5日:
从data.table开始1.9.8+你可以替换write.csv使用fwrite的,例如这个答案.
我想你已经有了答案.但要加强它,请参阅官方文件
那说明
通常,像R这样的统计系统并不特别适合于操纵大规模数据.其他一些系统比R更好,本手册的部分内容是建议不要在R中复制功能,而是让另一个系统完成工作!(例如,Therneau&Grambsch(2000)评论说,他们更喜欢在SAS中进行数据操作,然后在S中使用包生存进行分析.)数据库操作系统通常非常适合操作和提取数据:几个与DBMS交互的包在这里讨论.
因此,海量数据的存储显然不是R的主要优势,但它为几个专门用于此的工具提供了接口.在我自己的工作中,轻量级的SQLite解决方案就足够了,即使它在某种程度上是一个偏好的问题.搜索"使用SQLite的缺点",你可能找不到太多劝阻你.
您应该会发现SQLite的文档非常流畅.如果你有足够的编程经验,那么做一两个教程应该会让你在SQL前面快速进行.我没有在代码中看到任何过于复杂的内容,因此最常见的基本查询(如CREATE TABLE,SELECT ... WHERE)可能会满足您的所有需求.
编辑
使用DBMS的另一个优点是我没有提到,如果有人说,你可以views让其他数据组织容易访问schemas.通过创建视图,您可以返回"按月显示",而无需重写任何表,也不必复制任何数据.
| 归档时间: |
|
| 查看次数: |
375 次 |
| 最近记录: |