我在GB中有一个大型数据集,在分析之前我必须处理它们。 我尝试创建一个连接器,它允许我循环遍历大型数据集并一次提取块。这使我可以隔离满足某些条件的数据。
我的问题是我无法为规定它为null的连接器创建一个指示器,并且在达到数据集的末尾时执行close(连接器)。此外,对于第一个提取数据块,我必须跳过17行,因为该文件包含R无法读取的标题。
有效的手动尝试:
filename="nameoffile.txt"
con<<-file(description=filename,open="r")
data<-read.table(con,nrows=1000,skip=17,header=FALSE)
data<-read.table(con,nrows=1000,skip=0,header=FALSE)
.
.
.
till end of dataset
由于我想要避免手动键入上述命令,直到我到达数据集的末尾,我试图编写一个循环来自动化该过程,但这是不成功的。
我尝试使用失败的循环:
filename="nameoffile.txt"
con<<-file(description=filename,open="r")
data<-read.table(con,nrows=1000,skip=17,header=FALSE)
if (nrow(rval)==0) {
con <<-NULL
close(con)
}else{
if(nrow(rval)!=0){
con <<-file(description=filename, open="r")
data<-read.table(conn,nrows=1000,skip=0,header=FALSE)
}}
答案 0 :(得分:10)
看起来你走在正确的轨道上。只需打开一次连接(您不需要使用<<-
,只需<-
;使用更大的块大小,以便R的矢量化操作可用于有效地处理每个块),沿着
filename <- "nameoffile.txt"
nrows <- 1000000
con <- file(description=filename,open="r")
## N.B.: skip = 17 from original prob.! Usually not needed (thx @Moody_Mudskipper)
data <- read.table(con, nrows=nrows, skip=17, header=FALSE)
repeat {
if (nrow(data) == 0)
break
## process chunk 'data' here, then...
## ...read next chunk
if (nrow(data) != nrows) # last chunk was final chunk
break
data <- tryCatch({
read.table(con, nrows=nrows, skip=0, header=FALSE)
}, error=function(err) {
## matching condition message only works when message is not translated
if (identical(conditionMessage(err), "no lines available in input"))
data.frame()
else stop(err)
})
}
close(con)
在我看来,迭代似乎是一个很好的策略,特别是对于一个你要处理一次的文件,而不是像数据库一样反复引用。答案是修改,以便在检测文件末尾的读取时更加健壮。