4

R パッケージ (S3 スタイル) のエンドユーザー関数が引数を検証し、特定の有効性チェックが失敗したときにユーザーに有益なエラーまたは警告を与えるようにしたいと考えています。

これを行うための明白な (しかし退屈で保守不可能な) 方法は次のようになります。

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
}

これを行うのは私が最初ではないと思います。では、そのような検証タスクのすべてまたは一部を自動化するパッケージを提案できる人はいますか? または、それに失敗して、醜さを各関数内でできるだけ少ない行に制限するいくつかの簡潔で一般的な慣用句はありますか?

ありがとう。

4

2 に答える 2

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
于 2013-08-30T20:58:21.937 に答える
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.
于 2013-08-30T22:58:24.373 に答える