search
LoginSignup
1

More than 1 year has passed since last update.

posted at

updated at

生物系のためのR超入門 (9) 【自作関数の定義】

0. はじめに

Rにデフォルトで入っている関数やパッケージに含まれる関数は、引数を指定するだけで様々な処理を行ってくれる、大変便利なものですよね。
しかしながら、時には自分で関数を定義したい、長いコードを短くまとめたい、ということがでてくると思います。今回はそんな自作関数の定義についてまとめます。
第6回の記事でも自作関数を定義する機会が登場しているので、気になる方はご覧ください。

0-1. この記事の到達目標

  • 自分で新しく作った関数を定義できる

0-2. 初めて登場する関数

  • sprintf(%sを含んだ文字列,第2引数)
    • 第2引数を文字列として解釈し、第1引数の%sの部分に入力します。

1. とりあえず作ってみる

新たに関数を定義する際にはfunction(){}を使います。()には引数を、{}には関数が行う処理内容を記述します。

例として、「任意の数を3乗する計算」について考えます。
まず、この関数をcubedと命名します。
変数は「任意の数」1個だけなので、()には引数を1個、ここではxとしていますが変数名はなんでもOKです。
{}にはxを変数として「3乗する計算」のコードを書きます。

> cubed<-function(x){
+     x^3
+     }

これで自作関数の定義は完了しcubed()という関数が誕生しました。
あとは今まで通り、引数に数を指定するだけで利用可能です。
この関数はセッションが続く限り有効で、再起動等すると再定義が必要になることがあります。スクリプトファイル等に保存することをおすすめします。

> cubed(3)
[1] 27
> cubed(0.1)
[1] 0.001
> cubed(27)
[1] 19683

2. 引数を2つ以上指定する場合

引数を2つ以上指定したい場合も、前項とほとんど同様です。function(){}()に引数をカンマで区切って指定します。

例として「任意の数を任意乗する」関数を作ってみましょう。引数に底としてxを、冪指数としてnを指定しています。

> exponentiation<-function(x,n){
+   x^n
+ }

この関数は引数を2つ指定、と定義したので引数が1つだけだとエラーになってしまいます。
ちゃんと引数を2つ入れてあげると、しっかり動いてくれます。

> exponentiation(1)
 exponentiation(1) でエラー: 
   引数 "n" がありませんし省略時既定値もありません 
> exponentiation(2,3)
[1] 8
> exponentiation(10,-1)
[1] 0.1

3. こんにちはゲストさんをつくる

引数に任意の名前を指定すると、その人へ挨拶してくれる、ただし名前の指定がなかった場合「ゲストさん」として挨拶する関数を定義したいと思います。

そのためには、まずsprintf()関数の使い方を説明します。
これは文字列等を扱うときに便利な関数で、第1引数に特別な入力文字%sを含んだ文字列を指定し、第2引数に別の文字列を指定すると、%sに入力されます。
特別な入力文字にはいくつか種類があり使い分けがあるのですが、今回は割愛します。
百聞は一見に如かず、コードを見ていただくと第2引数に太郎を指定すると、%sの部分に太郎が入力されています。太郎を花子に変えることも容易にできます。

> sprintf("こんにちは %s さん", "太郎")
[1] "こんにちは 太郎 さん"
> sprintf("こんにちは %s さん", "花子")
[1] "こんにちは 花子 さん"

ここまでを、とりあえずfunction(){}で定義しておきます。

> Hello<-function(name){
+   sprintf("こんにちは %s さん", name)
+ }
+ > Hello("太郎")
[1] "こんにちは 太郎 さん"

引数に名前の指定がなかった場合は「ゲスト」と表示させたいのですが、このまま引数に何も指定しないとエラーが出てしまいます。
では、どうすればよいかといいますと、function(){}()内であらかじめ指定しておきます。こうすることで名前の指定がない場合に「ゲスト」と表示させることができます。

> #引数に何も指定しないとこのままではエラー
> Hello()
 sprintf("こんにちは %s さん", name) でエラー: 
   引数 "name" がありませんし省略時既定値もありません

> #()で予め指定しておく 
> Hello<-function(name="ゲスト"){
+   sprintf("こんにちは %s さん", name)
+ }
> Hello()
[1] "こんにちは ゲスト さん"

> #もちろん名前の指定があった場合はその人の名前になる
> Hello("太郎")
[1] "こんにちは 太郎 さん"

いかがでしたでしょうか?
自作関数を定義できるようになることで、なんだか幅が広がったような気がしますね!

4. 次回

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
What you can do with signing up
1