# A tibble: 6 × 6
country continent year lifeExp pop gdpPercap
<fct> <fct> <int> <dbl> <int> <dbl>
1 Afghanistan Asia 1952 28.8 8425333 779.
2 Afghanistan Asia 1957 30.3 9240934 821.
3 Afghanistan Asia 1962 32.0 10267083 853.
4 Afghanistan Asia 1967 34.0 11537966 836.
5 Afghanistan Asia 1972 36.1 13079460 740.
6 Afghanistan Asia 1977 38.4 14880372 786.
付録 B — パイプ演算子 (R)
Rのコードを見ていると%>%
や|>
といった謎の記号を見かけます。これらはパイプ演算子と呼びますが、その正体を考えたいと思います。
B.1 パイプ演算子の機能
まずは、パイプ演算子の機能を確認します。まずは、普通にgapminder
のデータの冒頭を確認します。
これをパイプ演算子で書くと、このようになります。
# A tibble: 6 × 6
country continent year lifeExp pop gdpPercap
<fct> <fct> <int> <dbl> <int> <dbl>
1 Afghanistan Asia 1952 28.8 8425333 779.
2 Afghanistan Asia 1957 30.3 9240934 821.
3 Afghanistan Asia 1962 32.0 10267083 853.
4 Afghanistan Asia 1967 34.0 11537966 836.
5 Afghanistan Asia 1972 36.1 13079460 740.
6 Afghanistan Asia 1977 38.4 14880372 786.
|>
はR 4.1.0以降で備わっているパイプ演算子です。%>%
はtidyverse
に含まれているパイプ演算子です。
# A tibble: 6 × 6
country continent year lifeExp pop gdpPercap
<fct> <fct> <int> <dbl> <int> <dbl>
1 Afghanistan Asia 1952 28.8 8425333 779.
2 Afghanistan Asia 1957 30.3 9240934 821.
3 Afghanistan Asia 1962 32.0 10267083 853.
4 Afghanistan Asia 1967 34.0 11537966 836.
5 Afghanistan Asia 1972 36.1 13079460 740.
6 Afghanistan Asia 1977 38.4 14880372 786.
これらから分かるように、パイプ演算子は左辺のオブジェクトを右辺の関数に入れる機能を持っています。
- RStudioでは
Shift + Alt + M
でパイプ演算子を入力できます。
B.1.1 なにが嬉しいのか?
パイプ演算子を使うとなにが嬉しいのでしょうか。ご利益は再現性と可読性にあります。まず、パイプ演算子を使わずにコードを書いてみます。
- 1990年以降のアジアの国を取り出し、GDPを計算し、国ごとに平均値を求めてみます。
gapminder <- filter(gapminder, year > 1990)
gapminder <- filter(gapminder, continent == "Asia")
gapminder <- mutate(gapminder, GDP = pop * gdpPercap)
gapminder <- group_by(gapminder, country)
gdp_mean <- summarise(gapminder, GDP = mean(GDP))
head(gdp_mean)
# A tibble: 6 × 2
country GDP
<fct> <dbl>
1 Afghanistan 1.85e10
2 Bahrain 1.47e10
3 Bangladesh 1.45e11
4 Cambodia 1.28e10
5 China 3.82e12
6 Hong Kong, China 2.03e11
十分可読性はあり、このような書き方が良くないというわけではありません。しかし、よくあるミスは、どこまで分析をやったのか忘れてしまうというものです。
- 例えば、2行目までやって、少し集中が切れて、再開する時に4行目から実行してしまうと5行目でエラーが出ます。
また、何度も同じもの(今回の例ではgapminder
)を書いていると、スペルミスをするリスクが上がります。
パイプ演算子を使うと、次のように書くことができ、可読性を保ちつつ、一気に全ての処理を実行できます。
gdp_mean <- gapminder |>
filter(year > 1990) |>
filter(continent == "Asia") |>
mutate(GDP = pop * gdpPercap) |>
group_by(country) |>
summarise(GDP = mean(GDP))
head(gdp_mean)
# A tibble: 6 × 2
country GDP
<fct> <dbl>
1 Afghanistan 1.85e10
2 Bahrain 1.47e10
3 Bangladesh 1.45e11
4 Cambodia 1.28e10
5 China 3.82e12
6 Hong Kong, China 2.03e11
パイプ演算子を使うかどうかは個人の好みですが、どちらのコードを読めるようになっておかないと、他の人の分析が分からなくなります。
B.2 データの代入
パイプ演算子を使った場合、処理は上から下なのに、オブジェクトへの代入は再び上に戻るのは気持ち悪いかもしれません。その場合は、次のように書けます。ただし、あまり見かけない書き方です。
gapminder |>
filter(year > 1990) |>
filter(continent == "Asia") |>
mutate(GDP = pop * gdpPercap) |>
group_by(country) |>
summarise(GDP = mean(GDP)) -> gdp_mean
head(gdp_mean)
# A tibble: 6 × 2
country GDP
<fct> <dbl>
1 Afghanistan 1.85e10
2 Bahrain 1.47e10
3 Bangladesh 1.45e11
4 Cambodia 1.28e10
5 China 3.82e12
6 Hong Kong, China 2.03e11
|>
と%>%
のどちらを使っても大差はないですが、tiduverse
のパイプ演算子には次のようなものもあります。最初のオブジェクトを上書きます。
gdp_mean <- gapminder
gdp_mean %<>%
filter(year > 1990) %>%
filter(continent == "Asia") %>%
mutate(GDP = pop * gdpPercap) %>%
group_by(country) %>%
summarise(GDP = mean(GDP))
head(gdp_mean)
# A tibble: 6 × 2
country GDP
<fct> <dbl>
1 Afghanistan 1.85e10
2 Bahrain 1.47e10
3 Bangladesh 1.45e11
4 Cambodia 1.28e10
5 China 3.82e12
6 Hong Kong, China 2.03e11
B.3 代入の位置
基本的に左辺のオブジェクトは右辺の関数の最初の位置に代入されますが、%>%
の場合は>
によって位置を指定することができます。
Call:
lm(formula = lifeExp ~ gdpPercap, data = .)
Residuals:
Min 1Q Median 3Q Max
-22.200 -2.798 1.206 3.817 9.490
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 6.355e+01 6.836e-01 92.97 <2e-16 ***
gdpPercap 4.939e-04 4.421e-05 11.17 <2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 5.867 on 130 degrees of freedom
Multiple R-squared: 0.4898, Adjusted R-squared: 0.4859
F-statistic: 124.8 on 1 and 130 DF, p-value: < 2.2e-16
次のようにも書けるそうです。
Call:
lm(formula = lifeExp ~ gdpPercap)
Residuals:
Min 1Q Median 3Q Max
-22.200 -2.798 1.206 3.817 9.490
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 6.355e+01 6.836e-01 92.97 <2e-16 ***
gdpPercap 4.939e-04 4.421e-05 11.17 <2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 5.867 on 130 degrees of freedom
Multiple R-squared: 0.4898, Adjusted R-squared: 0.4859
F-statistic: 124.8 on 1 and 130 DF, p-value: < 2.2e-16