2015-07-01 38 views
3

我正在使用R的assertthat軟件包,並且希望(暫時)在斷言失敗時輸出警告而不是錯誤。使用assertthat包最簡單的方法是什麼?警告,而不是來自assert_that()的錯誤?

我意識到,要警告而不是錯誤的種類違背了什麼斷言應該用於。從長遠來看,我們的確希望在斷言失敗時輸出錯誤。在短期內,我們仍然希望代碼即使在輸入錯誤的情況下也能正常工作,因爲輸入錯誤的輸入現在仍然「足夠好」。

一個簡單的例子:假設我有一個將x作爲輸入並輸出x + 5的函數。如果x!= 3,我想輸出一個警告。因爲我們最終會使用assert_that,所以如果我們可以使用assert來包裝這個警告,那將會很好。

從長遠來看,我們將使用:

> x <- 3 
> fn <- function(x) {assert_that(x==3); return(x+5)} 
> fn(3) 
[1] 8 
> fn(4) 
Error: x not equal to 3 

在短期內,這裏是最好的我到目前爲止:

> fn <- function(x) {if(!see_if(x==3)) warning(validate_that(x==3)); return(x+5)} 
> fn(3) 
[1] 8 
> fn(4) 
[1] 9 
Warning message: 
In fn(4) : x not equal to 3 

我正在尋找一個更簡潔解決方案,如果可能的話(最好的情況是將「output_warning」參數傳遞給assert_that,但我認爲不存在)。

回答

2

我創建了一個用戶定義函數,它接受一個對應於您想要運行的表達式的字符串validate_that()(最終爲assert_that())。如果斷言失敗,該函數將打印警告,否則將保持沉默。請參閱下面的用法。如果需要,您可以輕鬆擴展此自定義函數以接受多個表達式。請注意,我還使用sys.calls()來獲取調用此輔助函數的函數的名稱。這是一條重要信息,因此您可以將警告與實際生成它們的代碼關聯起來。

assert_that_soft <- function(exp) { 
         if (!exp) { 
          print (paste("Error in function:", 
            parse(sys.calls()[[sys.nframe()-1]]))) # name of caller 
         } 
        } 

用法:

> fn <- function(x) { assert_that_soft(x==3); return(x+5) } 
> fn(3) 
[1] 8 
> fn(8) 
[1] "Error in function: fn(8)" 
[1] 13 
0

我想覆蓋功能的最簡單的方法是由同一個名稱,以便您複製大多數assert_that功能的原樣,並調用新功能進入錯誤模式時不需要更改所有代碼。

assert_that <- function(..., env=parent.frame()) { 
    res <- see_if(..., env=env) 
    if (res) 
     return(TRUE) 
    warning(attr(res, "msg")) 
    TRUE 
} 

fn <- function(x) { assert_that(x==3); return(x+5) } 
fn(3) 
# [1] 8 
fn(8) 
# [1] 13 
# Warning message: 
# In assert_that(x == 3) : x not equal to 3