2012-03-26 3 views
11

Я хочу передать большую таблицу данных в R LINE BY LINE, а если текущая строка имеет конкретное условие (скажем, первые столбцы> 15), добавьте строку в данные кадр в памяти. Я написал следующий код:R - Чтение STDIN по строкам

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); 

Но я получаю сообщение об ошибке «данные недоступны». Обратите внимание, что мои данные большие, и я не хочу читать все это раз и применять свое условие (в этом случае это было легко).

+0

Вы можете быть заинтересованы в ответы и комментарии по этому Q: http://stackoverflow.com/questions/9352887/strategies-for-reading-in-csv-files-in-pieces –

+0

см 'сканирования ','? readLines', 'nrows'' read.table', и имейте в виду, что ваше решение будет ** очень медленным в R - можете ли вы использовать Perl или даже awk для предварительной обработки? –

+1

Как мой ответ ниже тарифа с точки зрения скорости? По сути, я открываю файл и продолжаю извлекать строки из него, не закрывая файл. –

ответ

11

Я думаю, было бы разумнее использовать функцию 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) 
    } 
} 

Дополнительные комментарии:

  • R имеет внутренний способ обработки стандартного ввода в файл: stdin(). Я предлагаю вам использовать это вместо использования pipe('cat /dev/stdin'). Это, вероятно, делает его более надежным и, безусловно, более кросс-платформенным.
  • Вы инициализируете Mydata в начале и продолжаете расти с помощью rbind. Если количество линий, которое вы rbind, станет больше, это будет очень медленным. Это связано с тем, что, когда объект растет, ОС необходимо найти для него новую ячейку памяти, которая в конечном итоге принимает времени. Лучше предварительно выделить MyData или использовать циклы стиля приложения.
+0

Спасибо за ответ. Но у меня есть вопросы по этому поводу: как я уже упоминал, мои данные очень БОЛЬШИЕ, и я не хочу читать их в памяти. В строке 3 вашего кода кажется, что вы читаете целые данные, а затем просматриваете его строки. Я прав? – user1250144

+0

Нет, я открываю соединение, а затем читаю его. 'next_line' содержит только текущую строку. Использование 'file' открывает только соединение, оно еще ничего не читает. –

+0

Ахан. Благодарю. что я должен писать вместо «/tmp/test.txt», первый аргумент файла()? – user1250144

Смежные вопросы