メモ:%<-%、%>>%
最近ちょっと気になる演算子。使い方をちょっと調べたのでメモ。
%<-%
これはzeallotというパッケージの演算子です。
値のparallel assignmentができます。parallel assignmentというのは、Pythonとかだと、
a, b, c = 1, 2, 3
みたいなことでできるじゃないですか。あれです。
library(zeallot) c(a, b, c) %<-% 1:3 c(a, b, c) #> [1] 1 2 3
もちろん値の入れ替えなんかもできます。
x <- 0 y <- 1 c(x, y) %<-% c(y, x) c(x, y) #> [1] 1 0
%>>%
これはlumberjackというパッケージの演算子です。
%>>%
は%>%
と同じような演算子で、lumberjackパッケージの他の関数と組み合わせて使うとデータ変形のログを取ることができます。
例えば、こんな感じの処理を、
library(dplyr, warn.conflicts = FALSE) mtcars %>% group_by(cyl) %>% summarise( disp = mean(disp), hp = mean(hp) ) #> # A tibble: 3 x 3 #> cyl disp hp #> <dbl> <dbl> <dbl> #> 1 4 105.1364 82.63636 #> 2 6 183.3143 122.28571 #> 3 8 353.1000 209.21429
ちょっと(?)変えると
library(lumberjack) out <- tempfile(fileext = ".csv") mtcars %>>% start_log() %>>% group_by(cyl) %>>% summarise( disp = mean(disp), hp = mean(hp) ) %>>% dump_log(file = out, stop = TRUE) #> Dumped a log at C:\Users\user1\AppData\Local\Temp\RtmpMZMA0t\file33e8672434bd.csv #> # A tibble: 3 x 3 #> cyl disp hp #> <dbl> <dbl> <dbl> #> 1 4 105.1364 82.63636 #> 2 6 183.3143 122.28571 #> 3 8 353.1000 209.21429
こんな感じのログが記録されます。
readr::read_csv(out) #> Parsed with column specification: #> cols( #> step = col_integer(), #> time = col_datetime(format = ""), #> expression = col_character(), #> changed = col_logical() #> ) #> # A tibble: 2 x 4 #> step time expression #> <int> <dttm> <chr> #> 1 1 2017-08-07 21:24:52 group_by(cyl) #> 2 2 2017-08-07 21:24:52 summarise(disp = mean(disp), hp = mean(hp)) #> # ... with 1 more variables: changed <lgl>
ということで、あんまり汎用的な演算子ではないんですけど、おもしろいなーと思ったのは%>>%
は、通常のオブジェクトに対しては%>%
と同じように働いて、LOGNAME
という属性があるオブジェクトが通った時だけログ記録が発動します。
lumberjack::`%>>%` #> function (lhs, rhs) #> { #> rhs <- substitute(rhs) #> out <- pipe(lhs, rhs, env = parent.frame()) #> meta <- list(expr = as.expression(rhs), src = as.character(as.expression(rhs))) #> if (has_log(lhs)) { #> log <- get_log(lhs) #> log$add(meta = meta, input = lhs, output = out) #> } #> out #> } #> <environment: namespace:lumberjack>
こういう感じで、%>%
(的なもの)にフックを仕掛けるという仕組みはもっと汎用的になれば面白いかも。その意気や良し、という感想でした。