2010-11-05 41 views
39

我有一個文件,其中每一行是一組實驗的特定重複中收集的結果。每個實驗中的結果數量(即每行中的列數)可能不同。對每行結果的順序也沒有重要性(第1行中的第一個結果和第一個結果2沒有比其他任何對更相關;這些結果是集合)。什麼是在R中逐行閱讀的好方法?

文件看起來是這樣的:

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 
    .... 

不應在課堂上整數?這是什麼模式?

+0

什麼樣的文件?你能舉個例子嗎? – 2010-11-05 14:31:27

+0

@Brandon Bertelsen:當然,看到更新後的帖子。 – 2010-11-05 14:49:38

回答

27

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的情況。但上面的例子會讓你非常接近。祝你好運!

+0

+ 1謝謝!將行轉換爲一個整數向量,我使用'as.integer(unlist(strsplit(oneLine,split =「」)))'。它有效,但我想知道是否有更好的方法?另外,你會如何建議將所有這些向量放在列表/向量中?另請注意,我向OP中添加了一個示例。 – 2010-11-05 14:53:27

+0

我真的不確定你的轉換是否比我的「更好」。我使用的方法是我在學習R時偶然發現的一種方法,而且我有一個習慣於學習單個習慣用法的壞習慣,然後即使存在「更好的方法」,也總是使用這一習語。 – 2010-11-05 15:20:27

17

是的,你可以使用readLinesJD Long has a good example,我稍微編輯並在下面提供。

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

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

close(con) 
+2

不錯。 「while」條件下我正在擺弄一會兒。奇怪我們沒有'isEOF()'或類似的東西。 – 2010-11-05 14:40:02

2

使用

line <- readLines(con, 1) 

讀取來自連接con一條線,其可以是作爲con <- file(filename, "r")一樣簡單。

5

或者:

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

,如果你知道該文件中的值是整數,則可以使用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) 

你會得到一個數值向量列表。

8

爲什麼要麻煩逐行閱讀?

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

給出整數向量的列表。

關於您的其他問題:看看?mode(簡稱 - mode是數字數字,typeof可以是整數或雙,和class數字或整數)。要查看是否有整數檢查str(results.list)lapply(results.list, class)

相關問題