R - 逐行读取STDIN

use*_*144 12 streaming r line readline

我想将一个大数据表流式传输到R LINE BY LINE,如果当前行具有特定条件(假设第一列> 15),则将该行添加到内存中的数据帧.我写了以下代码:

count<-1;
Mydata<-NULL;
fin <- FALSE;
while (!fin){
    if (count==1){
        Myrow=read.delim(pipe('cat /dev/stdin'), header=F,sep="\t",nrows=1);
        Mydata<-rbind(Mydata,Myrow);
        count<-count+1;
    }
    else {
        count<-count+1;
        Myrow=read.delim(pipe('cat /dev/stdin'), header=F,sep="\t",nrows=1);
        if (Myrow!=""){
        if (MyCONDITION){
            Mydata<-rbind(Mydata,Myrow);
        }
        }
        else
        {fin<-TRUE}
    }
}
print(Mydata);
Run Code Online (Sandbox Code Playgroud)

但我收到错误"数据不可用".请注意我的数据很大,我不想一次性阅读并应用我的条件(在这种情况下很容易).

Pau*_*tra 12

我认为使用像R这样的R函数会更明智readLines.readLines仅支持读取指定数量的行,例如1. file首先打开连接,然后readLines重复调用可以获得所需的内容.readLines多次调用时,n将从连接中读取下一行.在R代码中:

stop = FALSE
f = file("/tmp/test.txt", "r")
while(!stop) {
  next_line = readLines(f, n = 1)
  ## Insert some if statement logic here
  if(length(next_line) == 0) {
    stop = TRUE
    close(f)
  }
}
Run Code Online (Sandbox Code Playgroud)

附加评论:

  • R有一个将stdin视为文件的内部方法:stdin().我建议你使用它而不是使用它pipe('cat /dev/stdin').这可能使它更加强大,而且绝对更加跨平台.
  • Mydata在开始时初始化并继续使用它rbind.如果你rbind变大的行数,这将变得非常慢.这与以下事实有关:当对象增长时,操作系统需要为其找到新的内存位置,这最终会占用大量时间.更好的是预分配MyData,或使用应用样式循环.