2011-08-18 36 views
7

Tôi đang sử dụng chức năng getYahooData() trong gói TTR khá mạnh.Tất cả các kết nối đang được sử dụng: Thực hiện tạm dừng

Tôi có đoạn mã này:

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 
} 

Vòng lặp này là lâu tôi nhận được lỗi này:

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

tôi có thể làm gì?

UPDATE:

Nếu tôi sử dụng closeAllConnections() tôi nhận được:

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

không thể tái sản xuất trên hệ thống của tôi. Vector biểu tượng bạn đã sử dụng là gì? thử 'dput (symbol)' và cho chúng ta kết quả đầu ra. –

+0

bạn đã tái tạo nó như thế nào? tôi sử dụng chức năng này để tải về khoảng 3000 cổ phiếu giá – Dail

+0

đầu tiên, tôi không. Cho đến khi tôi tìm ra rằng tôi phải có một cái gì đó với một lỗi và một cảnh báo. Vì vậy, tôi đã giải quyết được vấn đề của bạn, nhưng bạn xứng đáng được đánh đòn nghiêm túc đối với mã bạn đã đăng. ;) –

Trả lời

13

Đầu tiên: không bao giờ trong cuộc sống của bạn sử dụng mà tiếp tục xây dựng lại. Nó không sử dụng. tryCatch()sẽ tiếp tục nếu bạn đã xác định trình xử lý cho một lỗi hoặc cảnh báo. Nó sẽ sử dụng một thay vì "mặc định" error=function(e) stop(e). Điều này sẽ dừng chức năng của bạn. Nếu bạn xác định một trình xử lý (hoặc là warning= hoặc error=), tập lệnh của bạn sẽ không bị dừng, do đó việc tiếp tục là không cần thiết.

này cho biết: Việc sử dụng đúng tryCatch trong trường hợp này sẽ là:

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

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

} 

hoặc, nếu bạn sử dụng nó trong một kịch bản và muốn đi đến vòng tiếp theo khi một lỗi xảy ra, bạn có thể đơn giản sử dụng:

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 
} 

Nếu bạn đã sử dụng cách này tryCatch hoặc thử, bạn sẽ không gặp vấn đề bạn báo cáo ở đây.

Bây giờ tôi có thể tạo lại trường hợp của bạn, nếu tôi sử dụng các biểu tượng không tồn tại. Việc sử dụng sai chức năng tryCatch() của bạn gây ra sự cố cho bạn. read.table trả về lỗi (Error in file(file, "rt") : cannot open the connection). Đây là lỗi , không phải là cảnh báo. Bạn nhận được cảnh báo bổ sung cho biết rằng không tìm thấy Tệp 404 được tìm thấy.

Khi cảnh báo được phát hành cùng với lỗi, hàm xử lý cảnh báo sẽ được xử lý trước tiên. Đó là bởi vì một cảnh báo phải được ném trước khi chức năng có thể được dừng lại. Vì vậy, nó sẽ không xử lý lỗi bạn nhận được, có nghĩa là on.exit(close(file)) trong read.table() sẽ không được gọi. Do đó, kết nối không đóng một cách chính xác và vẫn được coi là mở, mặc dù nó không thể được tìm thấy nữa bởi R (showAllConnections() cho thấy không có gì). Khi lỗi không được xử lý, có sự cố trong đăng ký kết nối. Vì không thể mở kết nối, on.exit(close(...)) sẽ không có hiệu lực. showConnections() không hiển thị kết nối, nhưng bằng cách nào đó R vẫn nghĩ rằng nó ở đó. Do đó, tất cả các địa ngục phá vỡ lỏng lẻo và bạn sụp đổ R. của bạn

cảm ơn cho sự điều chỉnh để @Tommy

Một ví dụ mã đơn giản để minh họa điều này:

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" 

Nói tóm lại:

  • kiểm tra những biểu tượng bạn sử dụng. Chúng có thể sai.
  • không bao giờ sử dụng trình xử lý cảnh báo nếu bạn gặp lỗi.

Và như thêm: vòng lặp của bạn sẽ chỉ trả lại kết quả của cuộc gọi cuối cùng, khi bạn ghi đè prices mỗi lần bạn đi qua vòng lặp, trong trường hợp bạn đã sử dụng đúng biểu tượng.

Chỉnh sửa: trong trường hợp bạn muốn tiếp tục hành động

+0

Joris - đây chỉ là công việc tuyệt vời! Nếu tôi có thể cho +10. –

+0

Tôi đồng ý! ... nhưng điều này cho thấy một lỗ hổng lớn trong hệ thống điều kiện! mã on.exit phải được đảm bảo LUÔN LUÔN được gọi, nếu không tất cả chúng ta đều nằm trong dodo sâu ... – Tommy

+0

Hmm Tôi đã nói quá sớm. Có vẻ như on.exit, nói chung, chạy khi một cảnh báo xảy ra và bị bắt? Và btw, nếu kết nối không thể mở được, nó không cần phải đóng ... – Tommy

9

Đóng một số kết nối? Có thể dễ dàng như chèn closeAllConnections() vào cuối thân vòng lặp đó.

+0

bạn có nghĩa là đặt closeAllCOnnections() trước khi} của vòng lặp? – Dail

+1

@ Dwin Tôi nhận được: *** bị bắt vi phạm *** địa chỉ (nil), gây ra 'bộ nhớ không được ánh xạ' Traceback: 1: getConnection (set [i]) 2: close (getConnection (set [i ])) 3: closeAllConnections() hủy bỏ ... – Dail

8

Đây thực sự là lỗi trong mã nguồn R về cách kết nối được đăng ký. Tôi đã đăng một số nhận xét và bản vá tại trang web R Bugzilla tại đây: http://bugs.r-project.org/bugzilla3/show_bug.cgi?id=14660. Đề xuất của Joris là âm thanh. Tuy nhiên, closeAllConnections() cũng sẽ hoạt động, khi lỗi được sửa. (PS đây là bài đăng StackOverflow đầu tiên của tôi. Xin lỗi tôi nếu tôi đã vi phạm nghi thức.)

+0

Chào mừng bạn! –

0

Một nơi nào đó trong quá khứ của tôi, ai đó đã đề cập rằng việc sử dụng tham chiếu URL trong một hàm như read.table.url() hoặc url() đã gọi một trình kết nối R HTTP gốc có lỗi. Những gì đã được chứng minh để làm việc tốt hơn cho việc đóng các kết nối về lỗi là gọi một cách rõ ràng RCurl bên trong của một cuộc gọi hàm read.table() hoặc tương đương. Ví dụ, điều này đã đem lại cho tôi những vấn đề khi rất nhiều lỗi HTTP tích lũy:

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

Tôi đã thấy kết quả tốt sẽ có sự thay đổi RCurl, gọi hàm getURL của nó:

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

này được khi đang chạy R v2.15.3.

Các vấn đề liên quan