2013-08-30 42 views
4

我希望R包(S3樣式)中的最終用戶函數驗證其參數,並在特定有效性檢查失敗時爲用戶提供信息錯誤或警告。R函數的半自動化參數驗證

明顯(但繁瑣且難以維護)的方式來做到這一點是:

foo<-function(aa,bb,cc,dd){ 
    if(length(aa)!=1) stop("The argument 'aa' must have a single value"); 
    if(!is.numeric(aa)) stop("The argument 'aa' must be numeric"); 
    if(!is.character(bb)) stop("The argument 'bb' must be a character"); 
    if(length(bb)>=4||length(bb)<=2) stop("The argument 'bb' must be a vector with a length between 2 and 4"); 
    if(!is.recursive(cc)) stop("The argument 'cc' must be a list-like object"); 
    if(!is.integer(dd)) stop("The argument 'dd' must contain only integers"); 
    if(any(dd<aa)) stop("All values in the argument 'dd' must be greater than the value of argument 'aa'"); 
    ## ...and so on 
} 

我假設我遠遠不是第一個做到這一點。那麼,有沒有人可以建議一個能夠自動完成全部或部分驗證任務的軟件包?或者,如果不這麼做,那麼一些簡潔的通用成語會將每個函數中的醜化限制爲儘可能少的行數?

謝謝。

回答

5

stopifnot可能類似於您要查找的內容。該錯誤消息將不會非常好雖然

foo <- function(x){ 
    stopifnot(length(x) == 1, is.numeric(x)) 
    return(x) 
} 

這給

> foo(c(1,3)) 
Error: length(x) == 1 is not TRUE 
> foo("a") 
Error: is.numeric(x) is not TRUE 
> foo(3) 
[1] 3 
+2

另請參見[assertthat](https:// githu b.com/hadley/assertthat),它試圖像'stopifnot',但有更好的錯誤信息。 – hadley

1

你可以寫這樣的(基本的例子)的輔助功能:

validate <- function(x, ...){ 
    for(s in c(...)) switch(s, 
     lengthone = if(length(x)!=1) stop("argument has length != 1."), 
     numeric = if(!all(is.numeric(x))) stop("non-numeric arguments."), 
     positive = if(any(x <= 0)) stop("non-positive arguments."), 
     nonmissing = if(any(is.na(x))) stop("Missing values in arguments.") 
    ) 
} 

結果:

> validate(1, "numeric", "positive") 
> validate(0, "numeric", "positive") 
Error in validate(0, "numeric", "positive") : non-positive arguments.