2011-08-18 103 views
7

我正在使用getYahooData()功能TTR封裝相當激烈。所有連接正在使用中:執行停止

我有這樣一段代碼:

for(i in 1:nrow(symbol)){ 
    tryCatch(prices <- getYahooData(symbol$symbol[i], from, to, freq="daily", 
            type="price"), 
      warning=function(e) continue <- 0) 
    if (continue==0) next 
} 

這個循環週期長,我得到這個錯誤:

Error in file(file, "rt") : all connections are in use Calls: tryCatch ... doTryCatch -> getYahooData -> getYahooData -> read.table -> file Execution halted

我能做些什麼?

UPDATE:

如果我使用closeAllConnections()我得到:

I get: *** caught segfault *** address (nil), cause 'memory not mapped' Traceback: 1: getConnection(set[i]) 2: close(getConnection(set[i])) 3: closeAllConnections() aborting ... 
+2

在我的系統上不可重現。什麼是你使用的符號向量?嘗試'輸入(符號)'並給我們輸出。 –

+0

你是如何重現它的?我使用這個功能下載大約3000股股票價格 – Dail

+0

首先,我沒有。直到我發現我必須有一些錯誤和警告。所以我解決了你的問題,但你應該對發佈的代碼進行嚴格的打分。 ;) –

回答

13

第一:永遠不要在你的生活中繼續使用那個繼續構造。這是沒用的。 tryCatch()繼續如果您爲錯誤或警告定義處理程序。它將使用那個而不是「默認」error=function(e) stop(e)。這一個將停止你的功能。如果您定義了處理程序(warning=error=),您的腳本將不會停止,因此無需繼續。

此說:在這種情況下,正確使用tryCatch的是:

for(i in 1:nrow(symbol)){ 

tryCatch(prices <- getYahooData(symbol$symbol[i], from, to, freq="daily", 
            type="price"), error = function(e){}) 

} 

,或者,如果你在腳本中使用它,並希望在發生錯誤時要到下一個循環,你可以簡單地用途:

for(i in 1:nrow(symbol)){ 

    prices <- try(getYahooData(symbol$symbol[i], from, to, freq="daily", 
            type="price"), silent=TRUE) 

    if(inherits(prices,"try-error")) { next } # only true if an error occurs 
    ... # rest of calculations 
} 

如果你要使用tryCatch的這樣或嘗試,你就不必了,你在這裏報告的問題。

現在我可以重現你的情況,如果我使用不存在的符號。你錯誤地使用tryCatch()函數會給你帶來麻煩。 read.table返回錯誤(Error in file(file, "rt") : cannot open the connection)。這是一個錯誤,不是一個警告。你會得到一個額外的警告,說404文件沒有找到返回。

當警告與錯誤一起發出時,首先處理警告的處理函數。這是因爲在函數停止之前必須拋出警告。因此,它不會處理您收到的錯誤,這意味着read.table()中的on.exit(close(file))將不會被調用。因此,連接沒有正確關閉,仍然被認爲是開放的,儘管它不能被R(showAllConnections()顯示)找到。由於未處理錯誤,連接註冊時出現問題。由於連接無法打開,on.exit(close(...))將不起作用。 showConnections()不顯示連接,但不知何故R仍然認爲它在那裏。因此,所有地獄崩潰,你崩潰你的河。

感謝更正@Tommy

一個簡單的代碼的例子來說明這一點:

myfun <- function(x){ 
    if(x>1) warning("aWarning") 
    stop("aStop") 
    x 
} 

tryCatch(myfun(0.5), 
      warning=function(w)print("warning"), 
      error=function(e) print("stop")) 
[1] "stop"    

tryCatch(myfun(1.5), 
      warning=function(w)print("warning"), 
      error=function(e) print("stop")) 
[1] "warning" 

總結:

  • 檢查你使用的符號。他們可能是錯的。
  • 如果您希望發生錯誤,請不要再使用警告處理程序。

而且作爲一個額外的:你的循環只會返回最後調用的結果,因爲你每次都要經過循環時間覆蓋prices,如果你要使用正確的符號。

編輯:如果你想繼續行動

+0

Joris - 這簡直是非常出色的工作!如果我能我會給+10。 –

+0

我同意! ......但這表明了條件系統中的一個巨大缺陷! on.exit代碼必須保證始終被調用,否則我們都在深刻的dodo ... – Tommy

+0

嗯我說得太快了。它似乎on.exit是,一般來說,運行時發生警告並被捕獲?順便說一下,如果連接無法打開,則不需要關閉...... – Tommy

9

關閉一些連接?可以像在該循環體的末尾插入closeAllConnections()一樣簡單。

+0

以下寫了你,你的意思是在循環之前放置closeAllCOnnections()嗎? – Dail

+1

@迪文我得到:***抓段錯誤*** 地址(無),原因 '存儲器未被映射' 回溯: 1:的getConnection(將[I]) 2:關閉(的getConnection(組[I ])) 3:closeAllConnections() 正在中止... – Dail

8

這確實是關於如何連接的註冊將R源代碼中的錯誤。我在R Bugzilla網站上發佈了一些評論和補丁:http://bugs.r-project.org/bugzilla3/show_bug.cgi?id=14660。喬里斯的建議很有道理。但是,bug修復時,closeAllConnections()也可以工作。 (PS這是我的第一個StackOverflow的帖子,如果我違反了禮節,請原諒我)

+0

歡迎登機! –

0

在我過去的某處挖掘中,有人提到在read.table.url()函數中使用URL引用或url()調用了一個有點bug的本地R HTTP連接器。事實證明,錯誤連接的關閉更好地工作是在read.table()或等價的函數調用中顯式調用RCurl。舉例來說,這是給我的問題時,很多HTTP錯誤的累積:

result <- try (DF <- read.table(con <- url(url), col.names=colNames), 
silent=TRUE) 

我已經看到了良好的效果與RCurl變化下去,調用它的getURL功能:

result <- try (DF <- read.table(textConnection(getURL(url)), col.names=colNames), 
silent=TRUE) 

這是運行時R v2.15.3。