読者です 読者をやめる 読者になる 読者になる

Rでアサートする系のパッケージ:ensurer, assertthat, assertr

R ensurer assertthat assertr

なんか去年くらいから、アサートする系のパッケージがいろいろ出てるなあと思いながら眺めていました。自分のためにもちょっと使ってメモっとこうと思います。

ensurer

magrittrのひと、バーチェさんのパッケージ。主にパイプ(%>%)と一緒につかうことを想定しているようです。

github.com

使い方

ensure_that()ensures_that()があって、前者がアサートするための関数、後者がアサートする関数をつくる関数です(ややこしい…)。

パイプの中で使うことを想定しているので、アサートを通っていれば渡された値をそのまま返します

library(ensurer)

set.seed(1)
matrix(runif(16), 4, 4) %>%
  ensure_that(ncol(.) == nrow(.), all(. <= 1))
#>           [,1]      [,2]       [,3]      [,4]
#> [1,] 0.2655087 0.2016819 0.62911404 0.6870228
#> [2,] 0.3721239 0.8983897 0.06178627 0.3841037
#> [3,] 0.5728534 0.9446753 0.20597457 0.7698414
#> [4,] 0.9082078 0.6607978 0.17655675 0.4976992

~を使うと、エラーメッセージを指定することができます。

diag(4) %>%
    ensure_that(all(. != 0) ~ "Some value is not zero!")
#> Error: conditions failed for call 'diag(4) %>% ensure_that(all( .. ~ "Some value is not zero!")':
#>         * Some value is zero!

よく使うアサートは、ensures_that()で関数化することができます。

ensure_square <- ensures_that(NCOL(.) == NROW(.))

A <-
  diag(4) %>%
  ensure_square

ちなみに、ドキュメントではensure_that()内でもパイプを使えるっぽく書いてあるんですが、これはうまく動かないみたいでした...。メンテされてない感。

letters %>% is.character %>% all
#> [1] TRUE
letters %>% ensure_that(. %>% is.character %>% all)
#> Error: conditions failed for call 'letters %>% ensure_that(. %>% is.character %>% all)':
#>          * . %>% is.character %>% all

assert_that

羽鳥作。これはけっこう前からあったんでしょうか?

  • stopifnot()の強化版assert_that()を使える
  • アサートに便利な関数(is.*()とか)が豊富

というのが特徴みたいです。

github.com

使い方

何のひねりもなくこんな感じで使います。

library(assertthat)

assert_that(is.character(letters))
#> [1] TRUE

エラーは出さず、自分で処理を選びたいときはvalidate_that()とかsee_if()を使います。

assert_that(is.number(letters))
#> Error: letters is not a number (a length one numeric vector).

validate_that(is.number(letters))
#> [1] "letters is not a number (a length one numeric vector)."

see_if(is.number("1"))
#> [1] FALSE
#> attr(,"msg")
#> [1] "\"1\" is not a number (a length one numeric vector)."

エラーメッセージを変えたい場合はon_failure()を使います。

on_failure(is.number) <- function(call, env) { "This is my error message" }
assert_that(is.number(letters))
#> Error: This is my error message

assertr

なんか去年末くらいに出たパッケージ。これもパイプといっしょに使うことを想定してるらしいです。あと、data.frame前提のアサートがいろいろあるっぽい。

github.com

使い方

これはなんかがんばりすぎてる感あって、覚えるの大変そうなので諦めました。。通常はverify()を使っとけばよくて、複数のカラムに同じアサートを描けるときはassert()を使うらしいです。

Assertive R Programming with assertr

まとめ

assertthatが無難かなーという気がしました。pipe-friendlyなのも便利そうですけど、深入りしないでおこう...。