(R) zeallotパッケージがCRANに公開されていた(小追記あり)
ちょっとだけ書きます。
タイトルの通り、CRANにこのパッケージが登録されていました。まだ1週間たってませんね。
この情報は今rstudio::conf 2018が開催されていますが、そのツイートからでした。
For anyone interested, here is a link to my #rstudioconf slides on the zeallot 📦 and unpacking assignment in R. https://t.co/FmWGgaL1vS
— Nathan Teetor (@ntweetor) 2018年2月3日
このリンク先、githubのリポジトリからさらにGoogleスライドに飛ぶことが出来ます。
なお、github版はこちらにになりますね。 github.com
このtopのページやvignettesに良い例がありますのでご参考に。
しかし…このパッケージ、どこかで見たことが…?と思って調べると偉大なるあの方のブログに行きつきますね。
何が出来るのか
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パッケージの紹介でした。
まだできて間もないパッケージですが、かなり便利に使える気がしますね。問題もありそうですが(上の例の様に受け取る側の変数が多すぎるときとか)
追記
ちなみに最新バージョンが公開されたのは最近ですけど、パッケージ自体はけっこう前からある。 https://t.co/w0DODjHi4K
— Hiroaki Yutani (@yutannihilation) 2018年2月3日
ということで、見逃していました… 初版は1年前ですね。結構刻むなぁ…
Enjoy!!