LoginSignup
31
22

More than 3 years have passed since last update.

tidylog::でどんどんドーナツ、ドーンと行こう

Last updated at Posted at 2019-03-14

tidylog::でdplyr::関数のフィードバック

初めましての記事です。最近は、SHIROBAKO見てます。
Rの入り口はRstudioやtidyverseの誕生によって敷居がかなり低くなったと言いますが、普通に難しいです。プログラミング初心者で統計よくわからなければちゅらいです。(主はR歴1年弱)

なれないプログラミングですら難しいのに、データをどういう風に使いこなすかのイメージしながらがら操作するのが個人的には非常に難しい。

オブジェクトに入れたり、こまめにprint()しなければ、基本的にはローデータと成果物(分析結果、プロット)しかよく見ないなんてことも...

処理関数実行による前後が分からなければRで楽しくなれない!!
tidyverse::は分かりやすいとかいうけど分からないやい!!


そんなあなたにtidylog::


dplyr::使ったことがあれば難しいことは何もありません。
何それっていう人は宇宙本を読むのが一番いいです。
(僕は初めてRに触れたとき、教授から当然のように%>%を使われて、は?ってなりました)

tidylog::については英語読めなくても開発者のGithub見れば分かります。
要するにdplyr::の関数を実行する際にコンソール上でフィードバックをくれるのです。

百聞は一見に如かず。同じコードで比較してみましょう。

環境

R version 3.5.1 (2018-07-02) -- "Feather Spray"
Copyright (C) 2018 The R Foundation for Statistical Computing
Platform: x86_64-w64-mingw32/x64 (64-bit)

tidyverse::を使ったとき

> library(tidyverse)
-- Attaching packages --------------------------------------- tidyverse 1.2.1 --
 ggplot2 3.0.0      purrr   0.2.5
 tibble  1.4.2      dplyr   0.7.6
 tidyr   0.8.1      stringr 1.4.0
 readr   1.1.1      forcats 0.3.0
-- Conflicts ------------------------------------------ tidyverse_conflicts() --
x dplyr::filter() masks stats::filter()
x dplyr::lag()    masks stats::lag()
Warning message:
 パッケージ stringr はバージョン 3.5.2  R の下で造られました  

> data <- mtcars %>% 
+   select(mpg,cyl,hp,am) %>% 
+   filter(mpg > 15) %>% 
+   mutate(mpg_round = round(mpg)) %>% 
+   group_by(cyl, mpg_round, am) %>% 
+   tally() %>% 
+   filter(n >= 1)

head(data)
# A tibble: 6 x 4
# Groups:   cyl, mpg_round [5]
    cyl mpg_round    am     n
  <dbl>     <dbl> <dbl> <int>
1     4        21     1     1
2     4        22     0     1
3     4        23     0     1
4     4        23     1     1
5     4        24     0     1
6     4        26     1     1

素晴らしいですね。このスマートさがtidyverse()の真骨頂。

tidylog::を使ったとき

インストールはCRANから普通にできます

> library(tidylog)

 次のパッケージを付け加えます: tidylog 

 以下のオブジェクトは package:dplyr からマスクされています: 

     add_count, add_tally, anti_join, count, distinct, filter,
    filter_all, filter_at, filter_if, full_join, group_by,
    group_by_all, group_by_at, group_by_if, inner_join, left_join,
    mutate, mutate_all, mutate_at, mutate_if, right_join, select,
    select_all, select_at, select_if, semi_join, summarise,
    summarise_all, summarise_at, summarise_if, summarize,
    summarize_all, summarize_at, summarize_if, tally, top_n,
    transmute, transmute_all, transmute_at, transmute_if 

 以下のオブジェクトは package:stats からマスクされています: 

     filter 

> data <- mtcars %>% 
+   select(mpg,cyl,hp,am) %>% 
+   filter(mpg > 15) %>% 
+   mutate(mpg_round = round(mpg)) %>% 
+   group_by(cyl, mpg_round, am) %>% 
+   tally() %>% 
+   filter(n >= 1)
select: dropped 7 variables (disp, drat, wt, qsec, vs, )
filter: removed 6 out of 32 rows (19%)
mutate: new variable 'mpg_round' with 15 unique values and 0% NA
group_by: 3 grouping variables (cyl, mpg_round, am)
tally: now 20 rows and 4 columns, 2 group variables remaining (cyl, mpg_round)
filter (grouped): no rows removed

head(data)
# A tibble: 6 x 4
# Groups:   cyl, mpg_round [5]
    cyl mpg_round    am     n
  <dbl>     <dbl> <dbl> <int>
1     4        21     1     1
2     4        22     0     1
3     4        23     0     1
4     4        23     1     1
5     4        24     0     1
6     4        26     1     1

え、好き...

+ filter(n >= 1)以下を見てください。それぞれの実行した関数のフィードバックが記載されています。

  • select()でどの行が落とされたか
  • filter()でデータの全行のうち何行(データの何%)取り除かれたか
  • mutate()で何種類の値が挿入されたか(そのうちNA:欠損値は何%あるか)
  • group_by()group_by()
  • tally()で集計したよ
  • 最後のfilter()は該当する条件なし

といったように、各関数ごとにフィードバックをくれるのでデータがどんな足跡をたどったか分かりやすい。データハンドリングを行っている途中でもデータがどんな形をしているかイメージしやすい気がします。どっちがいいのかはユーザー次第ですが、こういう選択肢があるのも知ってほしいです。

開発者のGithubに他の例もあるので見てみてください。


追記{tidylog}1.0.0

{tidylog}のアプデが入って、最新の{dplyr},{tidyr}の関数に対応したそうです。

中でも、_join()のフィードバックが感動的。

> iris2 <- 
+   iris %>% 
+   as_tibble() %>% 
+   rowid_to_column() %>% 
+   select(rowid,Petal.Length,Petal.Width)
select: dropped 3 variables (Sepal.Length, Sepal.Width, Species)
> 
> iris %>% 
+   as_tibble() %>%
+   rowid_to_column() %>% 
+   select(rowid,Sepal.Length, Sepal.Width, Species) %>% 
+   left_join(iris2,by = "rowid")
select: dropped 2 variables (Petal.Length, Petal.Width)
left_join: added 2 columns (Petal.Length, Petal.Width)
           > rows only in x     0
           > rows only in y  (  0)
           > matched rows     150
           >                 =====
           > rows total       150

joinによって「追加された変数」と「マッチした要素数」を返してくれる。
※githubには、pivot_に対応してるけど、なんかうまくいかないのでここでは割愛。詳しくは{tidylog}のページを確認してください。


補足

  • tidylog::が真価を発揮するのはmutate(name = purrr::map(data, fundtion()))をつかったり、filter()の中でstringr::関数を使う時、複雑な処理による結果を一目で理解できます。

  • また、ビッグデータを扱う時、つまり%>%で繋いだ一つ一つの関数の処理に時間がかかるとき、フィードバックが関数の実行完了ごとに吐かれるので、データのトレースをたどりやするくなります。エラーが出てもどこまで走ってたか分かります。

最後まで、読んでいただきありがとうございました。

31
22
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
31
22