gpt4 book ai didi

r - 如何使用 R "readLines"命令从大文件中读取选定的行并将它们写入数据框?

转载 作者:行者123 更新时间:2023-12-04 19:08:12 26 4
gpt4 key购买 nike

我从事数据清洗。我有一个函数可以识别大型输入文件中的坏行(鉴于我的内存大小,太大而无法一次性读取)并将坏行的行号作为向量返回 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 在带有 3gig ram 的古怪的旧 Windows XP SP3 机器上。石器时代,我知道。

这是产生上述错误消息的代码:
# 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,0)
badRows.DF <- lapply(skipVec, FUN=function(pass){
read.table(con, skip=pass, nrow=1, header=TRUE, sep="") })
close(con)

错误发生在关闭命令之前。如果我从 lapply 和函数中拉出 readLines 命令,然后将其单独粘贴进去,我仍然会遇到相同的错误。

最佳答案

如果不是运行 read.table通过 lapply您只需手动运行前几次迭代,您就会看到发生了什么:

> read.table(con, skip=0, nrow=1, header=TRUE, sep="")
nnn fff
1 2 aa
> read.table(con, skip=0, nrow=1, header=TRUE, sep="")
X2 X3 bb
1 3 5 cc

因为 header = TRUE在每次迭代时读取的不是一行而是两行,因此您最终会比您想象的更快地用完行,在第三次迭代中:
> read.table(con, skip=0, nrow=1, header=TRUE, sep="")
Error in read.table(con, skip = 0, nrow = 1, header = TRUE, 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, nrow = 1, header = FALSE, sep = "",
row.names = 1)
if (pass) NULL else line
})
badRows.DF <- setNames(do.call(rbind, badRows), header)
close(con)

实现更高速度的一些线索:
  • 使用 scan而不是 read.table .读取数据为 character只有在最后,将数据放入字符矩阵或 data.frame 后,才应用 type.convert到每一列。
  • 而不是循环遍历 skipVec , 循环其 rle如果它更短。因此,您将能够一次读取或跳过大块的行。
  • 关于r - 如何使用 R "readLines"命令从大文件中读取选定的行并将它们写入数据框?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19204917/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com