Подтвердить что ты не робот

Каков хороший способ читать строки за строкой в ​​R?

У меня есть файл, где каждая строка представляет собой набор результатов, собранных в конкретной копии эксперимента. Количество результатов в каждом эксперименте (т.е. Количество столбцов в каждой строке) может отличаться. Также нет важности для порядка результатов в каждой строке (первый результат в строке 1 и первый результат 2 не связаны друг с другом, чем любая другая пара, это множество результатов).

Файл выглядит примерно так:

2141 0 5328 5180 357 5335 1 5453 5325 5226 7 4880 5486 0 
2650 0 5280 4980 5243 5301 4244 5106 5228 5068 5448 3915 4971 5585 4818 4388 5497 4914 5364 4849 4820 4370
2069 2595 2478 4941 
2627 3319 5192 5106 32 4666 3999 5503 5085 4855 4135 4383 4770 
2005 2117 2803 2722 2281 2248 2580 2697 2897 4417 4094 4722 5138 5004 4551 5758 5468 17361 
1914 1977 2414 100 2711 2171 3041 5561 4870 4281 4691 4461 5298 3849 5166 5578 5520 4634 4836 4905 5105 5089
2539 2326 0 4617 3735 0 5122 5439 5238 1
25 5316 21173 4492 5038 5944 5576 5424 5139 5184 5 5096 4963 2771 2808 2592 2
4963 9428 17152 5467 5202 6038 5094 5221 5469 5079 3753 5080 5141 4097 5173 11338 4693 5273 5283 5110 4503 51
2024 2 2822 5097 5239 5296 4561 

за исключением того, что каждая строка намного длиннее (до нескольких тысяч значений). Как видно, все значения являются целыми неотрицательными.

Короче говоря, это не обычная таблица, где столбцы имеют значения. Его просто куча результатов - каждый набор в строке.

Я хотел бы прочитать все результаты, затем выполнить некоторые операции над каждым экспериментом (строкой), например, вычислять ecdf. Я также хотел бы рассчитать среднее значение ecdf по всем репликам.

Моя проблема - как я должен прочитать этот странный файл? Я так привык к read.table, что я не уверен, что когда-либо пробовал что-нибудь еще... Должен ли я использовать некоторые низкоуровневые readlines? Я предполагаю, что предпочтительным выходом будет список (или вектор?) Векторов. Я посмотрел на scan, но, похоже, все векторы должны иметь одинаковую длину.

Любые предложения будут оценены.

UPDATE Следуя приведенным ниже предложениям, теперь я делаю что-то вроде этого:

con <- file('myfile') 
open(con);
results.list <- list();
current.line <- 1
while (length(line <- readLines(con, n = 1, warn = FALSE)) > 0) {
 results.list[[current.line]] <- as.integer(unlist(strsplit(line, split=" ")))
 current.line <- current.line + 1
} 
close(con)

Кажется, нужно работать. Это выглядит нормально?

Когда я summary(results.list) получаю: Режим класса длины

      Length Class  Mode  
 [1,] 1091   -none- numeric
 [2,] 1070   -none- numeric
   ....

Не должен ли класс быть целым? А что такое режим?

4b9b3361

Ответ 1

Пример Josh, связанный с тем, который я использую все время.

inputFile <- "/home/jal/myFile.txt"
con  <- file(inputFile, open = "r")

dataList <- list()
ecdfList <- list()

while (length(oneLine <- readLines(con, n = 1, warn = FALSE)) > 0) {
    myVector <- (strsplit(oneLine, " "))
    myVector <- list(as.numeric(myVector[[1]]))
    dataList <- c(dataList,myVector)

    myEcdf <- ecdf(myVector[[1]])
    ecdfList <- c(ecdfList,myEcdf)

  } 

close(con)

Я редактировал пример, чтобы создать два списка из ваших данных примера. dataList - это список, в котором каждый элемент в списке представляет собой вектор числовых значений из каждой строки в текстовом файле. ecdfList - это список, в котором каждый элемент является ecdf для каждой строки в текстовом файле.

Вероятно, вы должны добавить логику try() или trycatch() для правильной обработки ситуаций, когда ecdf не может быть создан из-за нулей или некоторых таких. Но приведенный выше пример должен сделать вас довольно близким. Удачи!

Ответ 2

Да, вы можете использовать readLines. JD Long имеет хороший пример, который я немного отредактировал и предоставил ниже.

con  <- file(inputFile, open = "r")

while (length(oneLine <- readLines(con, n = 1, warn = FALSE)) > 0) {
  # do stuff
} 

close(con)

Ответ 3

Зачем беспокоиться о строчном чтении?

results.list <- lapply(strsplit(readLines("myfile")," "), as.integer)

дает вам список целых векторов.

О дополнительных вопросах: взгляните на ?mode (вкратце - mode является числовым для чисел, typeof может быть целым или двойным, а class числовым или целочисленным). Чтобы проверить, есть ли целые числа, проверьте str(results.list) или lapply(results.list, class).

Ответ 4

Или:

df <- read.delim(file="whatever", header=F, sep = " ")

Ответ 5

Использование

line <- readLines(con, 1)

чтобы прочитать одну строку из соединения con, которая может быть такой же простой, как con <- file(filename, "r").

Ответ 6

если вы знаете, что значения в файле являются целыми числами, вы можете использовать scan() вместо readLines(), но также и в цикле:

open(con)
results.list <- list();
current.line <- 1
while( length(line <- scan(con,what=integer(0),nlines=1,quiet=TRUE))>0 ) {
  results.list[[current.line]] <- line
  current.line <- current.line + 1
}
close(con)

Вы получите список числовых векторов.