2010-04-07 26 views
26

Tôi có một chức năng ví dụ dưới đây mà đọc trong một ngày như một chuỗi và trả về nó như là một đối tượng ngày tháng. Nếu nó đọc một chuỗi mà nó không thể chuyển đổi thành một ngày, nó sẽ trả về một lỗi.Làm thế nào để nói lapply để bỏ qua một lỗi và xử lý điều tiếp theo trong danh sách?

testFunction <- function (date_in) { 
    return(as.Date(date_in)) 
    } 

testFunction("2010-04-06") # this works fine 
testFunction("foo") # this returns an error 

Bây giờ, tôi muốn sử dụng lapply và áp dụng chức năng này trên một danh sách các ngày:

dates1 = c("2010-04-06", "2010-04-07", "2010-04-08") 
lapply(dates1, testFunction) # this works fine 

Nhưng nếu tôi muốn áp dụng các chức năng trên một danh sách khi một chuỗi ở giữa hai ngày tốt sẽ trả về lỗi, cách tốt nhất để giải quyết vấn đề này là gì?

dates2 = c("2010-04-06", "foo", "2010-04-08") 
lapply(dates2, testFunction) 

Tôi giả sử rằng tôi muốn thử bắt ở đó, nhưng có cách nào để bắt lỗi cho chuỗi "foo" trong khi yêu cầu lapply để tiếp tục và đọc ngày thứ ba không?

+1

Rất liên quan chặt chẽ: http://stackoverflow.com/questions/1395622/debugging-lapply-sapply-calls – Shane

Trả lời

44

Sử dụng một biểu thức tryCatch quanh chức năng mà có thể ném được thông báo lỗi:

testFunction <- function (date_in) { 
    return(tryCatch(as.Date(date_in), error=function(e) NULL)) 
} 

Những điều tốt đẹp về tryCatch chức năng là bạn có thể quyết định phải làm gì trong trường hợp của một lỗi (trong trường hợp này , trả lại NULL).

> lapply(dates2, testFunction) 
[[1]] 
[1] "2010-04-06" 

[[2]] 
NULL 

[[3]] 
[1] "2010-04-08" 
+0

Vào cuối ngày chúng tôi đều làm điều tương tự ở đây - và John không cần xử lý ngoại lệ. Nếu đó không phải là ngày, NA sẽ được trả lại. Tại sao làm cho vấn đề trở nên khó khăn hơn? –

+1

Vâng, điều đó chắc chắn đúng trong trường hợp này.Mặc dù nếu câu hỏi được khái quát hóa thì việc sử dụng 'tryCatch' có lẽ là cách tốt nhất để tiếp tục thông qua một lỗi trong' lapply'. Tôi nghĩ rằng ví dụ ngày chỉ là một ví dụ? – Shane

+0

Cảm ơn Dirk và Shane, thực sự việc xử lý ngoại lệ là những gì tôi đang tìm kiếm. Ngày tháng chỉ là một ví dụ về một chức năng phức tạp hơn, nhưng đó là điều đơn giản nhất mà tôi có thể nghĩ về điều đó sẽ trả về một lỗi từ một danh sách những thứ. – John

6

Người ta có thể cố gắng giữ cho nó đơn giản hơn là để làm cho nó phức tạp:

  • Sử dụng phân tích cú pháp ngày vectorised
R> as.Date(c("2010-04-06", "foo", "2010-04-08")) 
[1] "2010-04-06" NA   "2010-04-08" 

Bạn trivially có thể quấn na.omit() hoặc bất cứ thứ gì xung quanh nó. Hoặc tìm chỉ mục của NA và trích xuất tương ứng từ vectơ ban đầu hoặc sử dụng phần bổ sung của các Quốc hội để tìm ngày được phân tích cú pháp, hoặc, hoặc, hoặc. Đó là tất cả ở đây rồi.

  • Bạn có thể làm testFunction() làm điều gì đó. Sử dụng thử nghiệm ở đó - nếu ngày được trả về (phân tích cú pháp) là NA, hãy làm điều gì đó.

  • Thêm tryCatch() khối hoặc try() vào phân tích cú pháp ngày của bạn.

Toàn bộ mọi thứ là một chút kỳ lạ như bạn đi từ một cấu trúc dữ liệu một kiểu (vector của chars) để cái gì khác, nhưng bạn không thể dễ dàng pha trộn các loại, trừ khi bạn giữ chúng trong một loại list. Vì vậy, có thể bạn cần phải suy nghĩ lại điều này.

0

Giả sử testFunction() không nhỏ và/hoặc không thể thay đổi nó, nó có thể được gói trong một chức năng của riêng bạn, với khối tryCatch(). Ví dụ:

> FaultTolerantTestFunction <- function(date_in) { 
+ tryCatch({ret <- testFunction(date_in);}, error = function(e) {ret <<- NA}); 
+ ret 
+ } 
> FaultTolerantTestFunction('bozo') 
[1] NA 
> FaultTolerantTestFunction('2010-03-21') 
[1] "2010-03-21" 
Các vấn đề liên quan