niszetの日記

アナログCMOS系雑用エンジニアが頑張る備忘録系日記

(R) zeallotパッケージがCRANに公開されていた(小追記あり)

ちょっとだけ書きます。

タイトルの通り、CRANにこのパッケージが登録されていました。まだ1週間たってませんね。

CRAN - Package zeallot

この情報は今rstudio::conf 2018が開催されていますが、そのツイートからでした。

このリンク先、githubリポジトリからさらにGoogleスライドに飛ぶことが出来ます。

github.com

なお、github版はこちらにになりますね。 github.com

このtopのページやvignettesに良い例がありますのでご参考に。

しかし…このパッケージ、どこかで見たことが…?と思って調べると偉大なるあの方のブログに行きつきますね。

notchained.hatenablog.com

notchained.hatenablog.com

何が出来るのか

yutannihilationさんの最初の記事の方に書かれていますが、Rでは代入先に複数の変数を指定することが出来ません。

どういうこと?

c(a,b)<-c(1,2)
#> Error in c(a, b) <- c(1, 2) : could not find function "c<-"

こういうことですね。

zeallotを使えば、出来ます。

library(zeallot)
c(x, y) %<-% c(1, 2) 
x
#> [1] 1
y
#> [1] 2

なお、左辺のc()はとることが出来ません。Rの文法的に仕方がないのですが…。スライド中ではLeft-hand side of darknessと表現されていますね。闇…。

このパッケージ、含まれている関数は3つしかありません。

%<-%
%->%
destructure

です。先の2つは左辺に代入するのか右辺に代入するのかの違いですね。

ここからが新しい情報

スライド中ではunpackingと表現されていますが、ベクトルの要素やlistの要素を取り出す形で使うことが出来ます。

まぁ、そのままやっても面白くないので、tibbleの要素にlistを持つ、あるいはlistの要素のtibbleを持つような複雑なデータ構造を持つデータセットが多数含まれているrepurrrsiveパッケージに使ってみます。

repurrrsive::got_charsはlistの要素にlist、その要素に文字列などを持っています。例えば下記のように書くと、listの中にある要素の1つめのlistを、その第一要素をaに、残りをrestに代入し、他を捨てることになります。

c(c(a,...rest) , ...) %<-% repurrrsive::got_chars
a
#> [1] "https://www.anapioficeandfire.com/api/characters/1022"

なお、.で1つの要素、...は残りの全要素を表すがそれぞれデータは代入せずに捨てられます、...hogeは変数hogeに代入するという意味になります(任意の変数名でよい)

スライドの例では、quosureには対応していないので、destructure.quosureを作りましょうと書かれていますね。

あまり良い例が思い浮かびませんでしたが、例として環境を与えてみます

x <- new.env()
x
#> <environment: 0x0000000021775bc0>
c(y,o=NULL) %<-% x
#> Error: invalid `%<-%` right-hand side, incorrect number of values
destructure.environment <- function(x){list(get_env(x))}
c(y,o=NULL) %<-% x
y
#> <environment: 0x0000000021775bc0>

こんな感じ。destructure.environmentを新たに定義することで、エラーを回避しています。また、受け取り側にダミーの変数oを置いています(%<-%なので複数あった方が良いかなと思いまして)
初期値としてNULLを与えています。これを設定しないと、oに値が入らないのでエラーになってしまいます。

c(y,o) %<-% x
#> Error: node stack overflow

R落ちた…。この悪例を試すのはやめた方が良いです。

pipeについて

これだけはスライドにしか情報がなかったのですが、pipe、%>%と組み合わせる場合、全体を()で囲う必要があるそうです。ただし、%->%であればそのまま使えるそうなので、そっちを使いますかね…。

ということで、簡単ですがzeallotパッケージの紹介でした。

まだできて間もないパッケージですが、かなり便利に使える気がしますね。問題もありそうですが(上の例の様に受け取る側の変数が多すぎるときとか)

追記

ということで、見逃していました… 初版は1年前ですね。結構刻むなぁ…

Enjoy!!