如何使用R“readLines”命令从大文件中读取所选行并将其写入数据
我从事数据清理工作.我有一个函数可以识别大型输入文件中的坏行(对于我的ram大小来说,太大而无法一次读取)并将坏行的行号作为向量badRows返回.这个功能似乎有效.
我现在正试图将坏行读入数据帧,到目前为止还没有成功. 我当前的方法是在我的文件的打开连接上使用read.table,使用在读取的每一行之间跳过的行数向量.对于连续的坏行,此数字为零. 我将skipVec计算为: (badRowNumbers - c(0,badRowNumbers[1:(length(badRowNumbers-1]))-1 但目前我只是将我的函数交给一个全零的skipVec向量. 如果我的逻辑是正确的,这应该返回所有行.它不是.相反,我得到一个错误:
我目前的功能基于Miron Kursa(“mbq”)的功能,我找到了here. 我的问题有点重复,但我认为他的功能有效,所以我以某种方式打破了它.我仍然试图理解打开文件和打开文件连接之间的区别,我怀疑问题存在于某个地方,或者我使用了lapply. 我在RStudio 0.97.551下运行R 3.0.1,在一台老式的Windows XP SP3机器上运行3gig.石器时代,我知道. 以下是产生上述错误消息的代码: # Make a small small test data frame,write it to a file,and read it back in # a row at a time. testThis.DF <- data.frame(nnn=c(2,3,5),fff=c("aa","bb","cc")) testThis.DF # This function will work only if the number of bad rows is not too big for memory write.table(testThis.DF,"testThis.DF") con<-file("testThis.DF") open(con) skipVec <- c(0,0) badRows.DF <- lapply(skipVec,FUN=function(pass){ read.table(con,skip=pass,nrow=1,header=TRUE,sep="") }) close(con) 该错误发生在关闭命令之前.如果我将readLines命令从lapply和函数中拉出来并且只是将它自己粘在一起,我仍然会得到同样的错误. 解决方法
如果不是通过lapply运行read.table而是手动运行前几次迭代,您将看到发生了什么:
> read.table(con,skip=0,sep="") nnn fff 1 2 aa > read.table(con,sep="") X2 X3 bb 1 3 5 cc 因为header = TRUE,它不是每次迭代时读取的一行而是两行,所以你最终会比你想象的更快地用完行,这是第三次迭代: > read.table(con,sep="") Error in read.table(con,skip = 0,sep = "") : no lines available in input 现在,这可能仍然不是解决问题的有效方法,但这是您可以修复当前代码的方法: write.table(testThis.DF,"testThis.DF") con <- file("testThis.DF") open(con) header <- scan(con,what = character(),nlines = 1,quiet = TRUE) skipVec <- c(0,1,0) badRows <- lapply(skipVec,function(pass){ line <- read.table(con,header = FALSE,sep = "",row.names = 1) if (pass) NULL else line }) badRows.DF <- setNames(do.call(rbind,badRows),header) close(con) 一些提高速度的线索: >使用scan而不是read.table.将数据作为字符读取,并且仅在最后,将数据放入字符矩阵或data.frame后,将type.convert应用于每列.>如果它更短,则不要在skipVec上循环,而是在其rle上循环.因此,您将能够一次读取或跳过大量的行. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |