3

stopifnot()私は有益なエラーを作りたいです。

私は読んだ:http: //r-pkgs.had.co.nz/tests.html(NSEを使用して、例の有益なテストエラーを出力することに関する最後のセクションは関連しているようです)および http://adv -r.had.co.nz/Computing-on-the-language.html しかし、これを簡潔なコードで有益なエラーを出力することはできません:

e <- new.env()
e$label <- c(1,2,3)
check_in_y <- function(x, z, e) {
  stopifnot(eval(bquote(.(x) %in% e[[.(z)]])))
}

check_in_y(5,"label", e)

出力はこれを示します(それほど有益ではありません)

エラー: eval(bquote(.(x) %in% e[[.(z)]])) は TRUE ではありません

次のように言って、エラーをより有益なものにしたい:

エラー: 5 %in% e[["label"]] は TRUE ではありません

どうすればこれを機能させることができますか? または、私が望むものを達成するための最良のアプローチは何ですか

真でない場合の条件を記述して、代わりに独自のエラーを出力できることはわかっていますが、余分なコードは面倒です。これを機能させるために NSE を取得する方法を理解したいと思います。

編集: このアプローチの動機は、hadley のコメント ( http://r-pkgs.had.co.nz/tests.html )を読んだことにあります。

ただし、期待が失敗した場合、これはあまり有益な出力を提供しません。

expect_floor_equal("year", "2008-01-01 00:00:00")
## Error: floor_date(base, unit) not equal to as.POSIXct(time, tz = "UTC")
## Mean absolute difference: 31622400

代わりに、少し非標準の評価を使用して、より有益なものを生成できます。重要なのは、bquote() と eval() を使用することです。以下の bquote() 呼び出しでは、.(x) の使用に注意してください。() の内容が呼び出しに挿入されます。

expect_floor_equal <- function(unit, time) {
  as_time <- function(x) as.POSIXct(x, tz = "UTC")
  eval(bquote(expect_equal(floor_date(base, .(unit)), as_time(.(time)))))
}
expect_floor_equal("year", "2008-01-01 00:00:00")
## Error: floor_date(base, "year") not equal to as_time("2008-01-01 00:00:00")
4

2 に答える 2

6

stopifnotは単なる便利な関数です

if(!all(condition)) stop(standard message)

カスタム メッセージの場合は、コードを記述するだけです。stopifnot呼び出しを次の 2 行に置き換えることができます。

check_in_y <- function(x, z, e) {
    b <- bquote(.(x) %in% e[[.(z)]])
    if(!eval(b)) stop(deparse(b), " is not TRUE", call. = FALSE)
}

check_in_y(5, "label", e)
# Error: 5 %in% e[["label"]] is not TRUE
于 2017-04-13T15:10:18.297 に答える