[R語言初學] R語言中的%>%是什麼?

0

Last Updated on 2023-10-05

Home » R語言教學 » R語言初學 » [R語言初學] R語言中的%>%是什麼?

你有沒有看過R語言裡面 %>% 這個奇怪的符號?解釋給你聽!


接觸R語言已經有一段時間,常常會看到%>%,一直覺得很奇怪不知道這是什麼意思嗎?看到別人的程式碼寫了好一長串,中間都用 %>% 串起來,想知道是怎麼運作的嗎?

我會在這篇文章介紹R語言程式碼中常見的管線運算子(pipe operator)%>%,配上實際程式碼,帶你成為R語言裡的水管達人。

前言

如果你剛開始接觸R語言,一定有機會看到 3 個長相奇特的符號連在一起:%>%

它到底是什麼奇怪的東西?

一份製作圖表的程式碼,裡面有許多 % data-recalc-dims=% 的蹤影” width=”700px”>

一份製作圖表的程式碼,裡面有許多 %>% 的蹤影

介紹管線運算子

magrittr套件中的管線運算子

管線運算子,出自於library(magrittr),是 tidyverse 裡面必備的元素。

顧名思義,它的作用有如水管,能夠把符號左方的物件傳送到右方的函數當中。

傳送到右方函數運算完畢後,物件不會停留定著,可以繼續傳送,不斷往後。

實際的 %>% 案例

我們利用鑽石資料集來解說 %>% 的用途。

library(tidyverse)
head(diamonds, 5)
#> # A tibble: 5 × 10
#>   carat cut     color clarity depth table price     x     y     z
#>   <dbl> <ord>   <ord> <ord>   <dbl> <dbl> <int> <dbl> <dbl> <dbl>
#> 1  0.23 Ideal   E     SI2      61.5    55   326  3.95  3.98  2.43
#> 2  0.21 Premium E     SI1      59.8    61   326  3.89  3.84  2.31
#> 3  0.23 Good    E     VS1      56.9    65   327  4.05  4.07  2.31
#> 4  0.29 Premium I     VS2      62.4    58   334  4.2   4.23  2.63
#> 5  0.31 Good    J     SI2      63.3    58   335  4.34  4.35  2.75

鑽石資料集裡面有 10 個欄位,包含克拉、顏色、價格等,在此不一一贅述。

如果我們想從中選取克拉、顏色、價格這 3 個欄位,可以利用 library(dplyr) 當中的 select()

# 不用 pipe
select(diamonds, carat, color, price)
#> # A tibble: 53,940 × 3
#>    carat color price
#>    <dbl> <ord> <int>
#>  1  0.23 E       326
#>  2  0.21 E       326
#>  3  0.23 E       327
#>  4  0.29 I       334
#>  5  0.31 J       335
#>  6  0.24 J       336
#>  7  0.24 I       336
#>  8  0.26 H       337
#>  9  0.22 E       337
#> 10  0.23 H       338
#> # &#x2139; 53,930 more rows
# 使用 pipe
diamonds %>% select(carat, color, price)
#> # A tibble: 53,940 × 3
#>    carat color price
#>    <dbl> <ord> <int>
#>  1  0.23 E       326
#>  2  0.21 E       326
#>  3  0.23 E       327
#>  4  0.29 I       334
#>  5  0.31 J       335
#>  6  0.24 J       336
#>  7  0.24 I       336
#>  8  0.26 H       337
#>  9  0.22 E       337
#> 10  0.23 H       338
#> # &#x2139; 53,930 more rows

從上面兩行程式碼對比,可以看出來,%>% 的意義就是,把 diamonds 這個資料集,向後傳送到 select() 裡面。

只看一行程式碼的差異不大,但如果我們在挑選欄位後,想要採取更多動作,例如增加欄位、篩選資料等,就能夠看出差異。

# 不用 pipe
filter(mutate(select(diamonds, carat, color, price), price_twd = price*30), price_twd >= 10000)
#> # A tibble: 53,937 × 4
#>    carat color price price_twd
#>    <dbl> <ord> <int>     <dbl>
#>  1  0.29 I       334     10020
#>  2  0.31 J       335     10050
#>  3  0.24 J       336     10080
#>  4  0.24 I       336     10080
#>  5  0.26 H       337     10110
#>  6  0.22 E       337     10110
#>  7  0.23 H       338     10140
#>  8  0.3  J       339     10170
#>  9  0.23 J       340     10200
#> 10  0.22 F       342     10260
#> # &#x2139; 53,927 more rows

上面這段程式碼的讀法是由內往外讀。

我們先從最裡面的 select() 開始,它幫助我們挑出了 3 個欄位。

下一步 mutate(),則是根據美元計價的 price 欄位,增加了以台幣計價的 price_twd 欄位。

再下一步 filter() 篩選台幣 1 萬元以上的鑽石,把不符條件的資料剔除。

我們很容易想像,如果接著還有 5 步、6 步,使用函數將原先的物件層層包裹,光是想要理解程式碼本身,就會十分困難。

改用 %>%,一切都會輕鬆許多。

# 使用 pipe
diamonds %>% 
  select(carat, color, price) %>%
  mutate(price_twd = price*30) %>%
  filter(price_twd >= 10000)
#> # A tibble: 53,937 × 4
#>    carat color price price_twd
#>    <dbl> <ord> <int>     <dbl>
#>  1  0.29 I       334     10020
#>  2  0.31 J       335     10050
#>  3  0.24 J       336     10080
#>  4  0.24 I       336     10080
#>  5  0.26 H       337     10110
#>  6  0.22 E       337     10110
#>  7  0.23 H       338     10140
#>  8  0.3  J       339     10170
#>  9  0.23 J       340     10200
#> 10  0.22 F       342     10260
#> # &#x2139; 53,927 more rows

diamonds 資料集從頭開始,經過一個又一個的函數,就像生產線一樣經過加工,而後呈現在我們面前。

不該使用 %>% 的時機

R for Data Science 書中,有提醒讀者不該使用管線運算子的時機。

第一,若超過 10 個步驟時,避免自己讀錯程式碼,也方便糾錯,可以考慮在中間停下腳步,先把運算結果儲存到變數中。

第二,如果同時有多個輸入(input)或輸出(output)時,也最好不要用 %>%

第三,若使用情境並非線性(linear),可能是環環相扣,或者有複雜的相依性時,最好不要使用 %>%

我們最後再延伸一下上面的案例,展示 %>% 的威力吧!

# 使用 pipe
diamonds %>% 
  select(carat, color, price) %>%
  mutate(price_twd = price*30) %>%
  filter(price_twd >= 10000) %>%
  group_by(color) %>%
  summarise(price_twd = mean(price_twd), carat = mean(carat)) %>%
  arrange(color) %>%
  slice(2:6) %>%
  mutate(p_per_c = price_twd/carat) %>%
  arrange(desc(p_per_c))
#> # A tibble: 5 × 4
#>   color price_twd carat p_per_c
#>   <ord>     <dbl> <dbl>   <dbl>
#> 1 G       119974. 0.771 155570.
#> 2 F       111747. 0.737 151719.
#> 3 I       152756. 1.03  148751.
#> 4 H       134600. 0.912 147620.
#> 5 E        92328. 0.658 140316.

%>% 的發音

在學校擔任助教的時候,曾有同學問過,要怎麼念出 %>%

查了之後才發現發音很多元,有人念 “then”,有人念 “pipe”,以前我都念「趴大於趴」,但其實沒有任何限制,要怎麼念都可以。

如果你對其他 R 語言中符號的發音有興趣,可以參考這篇討論。 趴趴熊非常可愛!

小結

我在這篇文中,介紹了 %>% 管線運算子的意義,還有派上用場的時機。之後的文章會繼續介紹 R語言當中的符號、函數以及套件,希望你喜歡這篇文章。

No Comments

Leave a Reply