こんにちは,shun(@datasciencemore)です!!
今回でついにbaseR編も完結です!
今回は関数についてです.
さて,関数とは何なのでしょうか?
意外と関数についてきちんと説明できる人って少ないと思います.
関数を使いこなせるとコードをきれいに書けるようになりますよ.
それでは,さっそく関数について学習していきましょう!
1.関数ってなに??
関数は,入力に対してあらかじめ定めた処理を適用することで出力を返す命令のことだよ!!
はい,また謎の説明ですね笑
関数の一番簡単な例として,1次関数 y = x + 1を考えてみましょう.
いうまでもないかもしれないですが,xが入力でyが出力です.
x = 1 ⇒ y = 2
x = 2 ⇒ y = 3
…
x = 9 ⇒ y = 10
とこのような感じで入力xに何か数を入れると,入力に1足された数が出力yとなります.
図にするとこんな感じ.
この簡単な例でも立派な関数です.
冒頭で説明した
関数は,入力に対してあらかじめ定めた処理を適用することで出力を返す命令のこと
というのもこの図を見ればイメージできると思います.
入力,処理,出力をまとめて関数って言ってるんですね.
よく関数は魔法の箱のようなものだという説明があります.
これも間違いではないです.
処理に焦点をあてると関数=処理です.
ここ,結構微妙なところで文脈によって関数 = 処理の場合と関数 = 入力,処理,出力をあわせたものの場合があります.
ただどちらにせよ上のようなイメージを常に持っていればそんなに混乱することはないはずです.
言葉の厳密な定義よりも入力,処理,出力が何かということを明確にすることを心がけましょう.
さて,この関数をRで書くとどのようになるのでしょうか?
次項でじっくり見ていきましょう.
2.関数の作成
さっそく実例を挙げます.
さきほどの超絶簡単なy = x + 1を関数にしてみましょう.
この関数の関数名をadd_1としましょう.
1 2 3 4 5 |
# 入力xに1を足す関数を定義 add_1 <- function(x) { y <- x + 1 return(y) } |
先ほどの図との対応を見てみましょう.
同じ色の対応をよく確認してくださいね.
Rでは,関数は次のように書きます.
関数名 = function(入力){
処理
return(出力)
}
そんなに難しくないですね.
実は関数はもっと柔軟に書くことができます.
先ほど使用した例は,入力も出力もスカラーの数値でしたが,べつに数値でなくても構いません.
文字列でもいいし,ファクターでもいいし,データフレームでもいいし,ベクトルでもいいです.
また,入力も1つではなく複数あってもOKです.(というか,そっちのほうが普通笑)
出力もリストを使用すれば,複数書けます.
例:return(list(y1, y2, y3))
意外と便利なので,一応紹介しておきます.
ぜひ様々な関数を自分で作成して,便利さを実感してくださいね!
3.関数を使う理由
関数の書き方についてはわかりました.
でも,関数って使わなくてもよくないですか?
関数使わなくても書けそうだし...
関数を使う理由は主に以下の2点だよ!!
・コードをきれいにするため.
・コードの修正を簡単にするため.
例えば,以下のコードは,3つのデータフレームからそれぞれ散布図を出力するものです.
コードの細かい意味は省略します
関数の有無で何が違うか把握することに集中してください.
3.1.関数を使用しない場合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
iris_setosa <- iris %>% tibble() %>% filter(Species == "setosa") iris_versicolor <- iris %>% tibble() %>% filter(Species == "versicolor") iris_virginica <- iris %>% tibble() %>% filter(Species == "virginica ") iris_setosa %>% ggplot( mapping = aes(x = Sepal.Length, y = Petal.Length) ) + geom_point() + geom_smooth(method = "lm", se = FALSE) + theme( axis.text = element_text(size = 25), axis.title = element_text(size = 25) ) iris_versicolor %>% ggplot( mapping = aes(x = Sepal.Length, y = Petal.Length) ) + geom_point() + geom_smooth(method = "lm", se = FALSE) + theme( axis.text = element_text(size = 25), axis.title = element_text(size = 25) ) iris_virginica %>% ggplot( mapping = aes(x = Sepal.Length, y = Petal.Length) ) + geom_point() + geom_smooth(method = "lm", se = FALSE) + theme( axis.text = element_text(size = 25), axis.title = element_text(size = 25) ) |
3.2.関数を使用する場合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
make_scatter = function(df, type){ df_Species = df %>% tibble() %>% filter(Species == type) scatter = df_Species %>% ggplot( mapping = aes(x = Sepal.Length, y = Petal.Length) ) + geom_point() + geom_smooth(method = "lm", se = FALSE) + theme( axis.text = element_text(size = 25), axis.title = element_text(size = 25) ) return(scatter) } make_scatter(iris, "setosa") make_scatter(iris, "versicolor") make_scatter(iris, "virginica") |
どうでしょうか??
明らかに関数を使用したほうがコードが短くなって,見やすくなっていますよね.
同じような処理を関数使わないで書くとコードが長くなってとても見づらいです.
また,もし,処理を変えることになった場合,
関数にしている場合は,関数だけを修正すればいいですが,関数を使用していない場合は,処理数(この例の場合,3個)だけコードを修正する必要があるので,とても大変です.
大変だけならまだいいですが,修正漏れの可能性も高まりますね...
ということで,同じような処理がたくさん出てくるようなときは関数にしましょう!!
4.関数の外部ファイル化
関数を使用するためには当然ですが,関数を定義する必要があります.
関数を定義する際,そのまま定義するのではなく,外部ファイルに定義すると見通しがよくなります.
以下の図を見比べてみてください.
左が外部ファイル化しない場合,右が外部ファイル化した場合です.
左の場合,関数の定義と処理が一緒になっているので,どこまでが関数の定義でどこまでが関数の処理かを判断するが難しいため,見づらいです.
一方,右の場合,関数の定義を外部ファイル化しているため,関数の定義と関数の実行が一目瞭然ですね!
これはコードや関数が長くなるほど効果を発揮します.
外部ファイル化したファイルは,.Rprofile内にて読み込んであげると便利です.
先ほど作成した散布図を出力する関数「make_scatter」を例にして,以下のように外部ファイル「my_functions.R」と.「Rprofile」を書いてあげましょう.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# 散布図出力 関数を使用する場合 make_scatter = function(df, type){ df_Species = df %>% tibble() %>% filter(Species == type) scatter = df_Species %>% ggplot( mapping = aes(x = Sepal.Length, y = Petal.Length) ) + geom_point() + geom_smooth(method = "lm", se = FALSE) + theme( axis.text = element_text(size = 25), axis.title = element_text(size = 25) ) return(scatter) } |
1 2 3 4 5 6 7 8 9 10 11 12 |
# パッケージ読み込み library(stats) library(tidyverse) library(GGally) library(patchwork) library(lubridate) # 可視化の設定 theme_set(theme_linedraw(base_size = 25, base_family = "Helvetica")) # my_functions.Rの読み込み source("my_functions.R", encoding = "utf8") |
まとめ
今回は関数について以下のことをやりました.
- 関数ってなに?
- 関数の書き方
- 関数を使う理由
- 関数の外部ファイル化
関数は,入力に対してあらかじめ定めた処理を適用することで出力を返す命令のことです.
関数を書くことで,コードをきれいにすることができ,修正の大変さも軽減されます.
同じような処理がたくさんある場合,関数にできないか考える癖をつけましょう.
ちなみに楽して生きるがモットーのぼくは常に関数化の機会をうかがっていますよ笑
関数を使いこなしてこの世知辛い世の中,少しでも楽に生きましょう!
これでbaseR編も終了です,お疲れさまでした!!
次回からいよいよtidyverse編です,前置きが長かった...
この講座も次回からが真骨頂なのでどうぞお楽しみに♪
それじゃ,お疲れ様でした!!
追記)次回,書きました⇒
-
【R前処理講座10】tidyverseってなに??【tidyverse】
こんにちは,shun(@datasciencemore)です!!前回まで環境構築編とbaseR編をやってきました.今まで学習してきたこと,きっちり理解できていますでしょうか??6割くらいできているなら ...
続きを見る