加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

如何使用R“readLines”命令从大文件中读取所选行并将其写入数据

发布时间:2020-12-14 04:46:26 所属栏目:大数据 来源:网络整理
导读:我从事数据清理工作.我有一个函数可以识别大型输入文件中的坏行(对于我的ram大小来说,太大而无法一次读取)并将坏行的行号作为向量badRows返回.这个功能似乎有效. 我现在正试图将坏行读入数据帧,到目前为止还没有成功. 我当前的方法是在我的文件的打开连接上
我从事数据清理工作.我有一个函数可以识别大型输入文件中的坏行(对于我的ram大小来说,太大而无法一次读取)并将坏行的行号作为向量badRows返回.这个功能似乎有效.

我现在正试图将坏行读入数据帧,到目前为止还没有成功.

我当前的方法是在我的文件的打开连接上使用read.table,使用在读取的每一行之间跳过的行数向量.对于连续的坏行,此数字为零.

我将skipVec计算为:

(badRowNumbers - c(0,badRowNumbers[1:(length(badRowNumbers-1]))-1

但目前我只是将我的函数交给一个全零的skipVec向量.

如果我的逻辑是正确的,这应该返回所有行.它不是.相反,我得到一个错误:

“Error in read.table(con,skip = pass,nrow = 1,header = TRUE,sep =
“”) : no lines available in input”

我目前的功能基于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上循环.因此,您将能够一次读取或跳过大量的行.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读