R プログラミングの関数と例

⚡ スマートサマリー

R の関数は、一連の命令を 1 つの名前でパッケージ化するため、繰り返しのタスクは 1 つの呼び出しで実行できます。組み込みの数学および統計ヘルパー、ユーザー定義関数、環境スコアping条件付き引数については、ここでは具体的な例を用いて解説します。

  • 🔘 機能解剖学: 関数は、名前、オプションの引数リスト、本体、およびオプションの戻り値を組み合わせたものです。
  • 🧮 内蔵カバレッジ: Rには、数学や統計関数に加えて、diff()やlength()といった汎用的なヘルパー関数も付属しています。
  • 📐 再利用可能なリサイズ: normalize() 関数は、コピー&ペーストで繰り返し行うスケーリング処理を、再利用可能な 1 つの呼び出しに変換します。
  • 🧭 環境規則: すべての呼び出しはローカル環境を開き、Rは最も内側の定義から外側に向かって名前を解決します。
  • 🧪 条件付きロジック: split_data() 内の if/else 分岐は、トレーニングセットまたはテストセットのいずれかを返します。
  • 🛠️ 命名規則: ユーザー定義関数に組み込み関数とは異なる名前を付けることで、隠蔽や紛らわしいエラーを回避できます。

R プログラミングの関数

Rの関数とは何ですか?

A functionは、プログラミング環境では一連の命令です。 プログラマーは回避するための関数を構築します。 同じ作業を繰り返す、または減らす 複雑さ.

関数は次のようにする必要があります

  • 特定のタスクを実行するために書かれた
  • 引数を含めることも含めないこともできます
  • 体が入っている
  • 1つ以上の値を返す場合もあれば、返さない場合もある。

関数への一般的なアプローチは、引数部分を次のように使用することです。 入力、 フィード ボディ 一部を分割し、最後に返します 出力関数の構文は次のとおりです。

function (arglist)  {
  #Function body
}

R 重要な組み込み関数

R には多くの組み込み関数があります。R は、入力パラメーターと関数の引数を値または位置で照合し、関数本体を実行します。 関数の引数にはデフォルト値を指定できます。これらの引数を指定しない場合、R はデフォルト値を取得します。
お願い:
コンソールで関数自体の名前を実行すると、関数のソース コードを確認できます。

Typing 括弧のない関数名は、以下のコンソールの例のように、そのソースコードを表示します。

Rコンソールで組み込み関数のソースコードを表示する

XNUMX つの関数グループが実際に動作している様子を見ていきます。

  • 一般的な機能
  • 数学関数
  • 統計関数

一般的な機能

cbind()、rbind()、range() などの一般的な関数については既に知っています。 ソート()、および order()。これらの関数はそれぞれ特定のタスクを持ち、引数を受け取って出力を返します。以下は、知っておくべき重要な関数です。

diff()関数

あなたが取り組んでいる場合 時系列、シリーズを固定する必要があります。 ラグ値に直接影響を与えます。健全とされるのは 定常プロセス 平均、分散、自己相関を時間的に一定に保つことができます。これは主に時系列の予測精度を向上させます。これは diff() 関数で行うことができます。トレンドを持つランダムな時系列データを作成し、diff() 関数を使用して時系列を定常化することができます。diff() 関数は、ベクトルを引数として受け取り、適切なラグ付き反復差分を返します。

お願いランダムなデータを生成する必要がある場合が多いのですが、学習や比較のために、マシン間で数値が同一であることを望みます。すべてのマシンで同じデータが生成されるように、set.seed() 関数に任意の値 123 を指定します。set.seed() は擬似乱数生成器の開始点を固定するため、すべてのマシンで同じシーケンスが生成されます。set.seed() を使用しない場合、実行ごとに異なるシーケンスが返されます。

set.seed(123)
## Create the data
x = rnorm(1000)
ts <- cumsum(x)
## Stationary the serie
diff_ts <- diff(ts)
par(mfrow=c(1,2))
## Plot the series
plot(ts, type='l')
plot(diff(ts), type='l')

下の2つのパネルは、元の累積系列と差分系列を並べて表示したもので、差分系列は一定の平均値の周りで変動している。

差分定常系列の横に元の累積系列を示す。

length() 関数

多くの場合、計算のため、またはforループで使用するために、ベクトルの長さを知りたいことがあります。length()関数は、ベクトルxの行数をカウントします。以下のコードは、carsデータセットをインポートし、行数を返します。

お願い: length() はベクトルの要素数を返します。関数が渡された場合 マトリックス データフレームの場合は、列数が返されます。

dt <- cars
## number columns
length(dt)

出力:

## [1] 1
## number rows
length(dt[,1])

出力:

## [1] 50

波形演算

一般的なヘルパー関数に加えて、Rにはベクトルに対して要素ごとに演算を行う様々な数学関数が用意されています。

Operator 詳細説明
abs(x) xの絶対値を取ります
log(x、base = y) xを底yとする対数を取ります。 ベースが指定されていない場合、自然対数を返します
exp(x) xの指数を返します
sqrt(x) xの平方根を返します
階乗(x) x の階乗を返します (x!)
# sequence of number from 44 to 55 both including incremented by 1
x_vector <- seq(45,55, by = 1)
#logarithm
log(x_vector)

出力:

##  [1] 3.806662 3.828641 3.850148 3.871201 3.891820 3.912023 3.931826
##  [8] 3.951244 3.970292 3.988984 4.007333
#exponential
exp(x_vector)
#squared root
sqrt(x_vector)

出力:

##  [1] 6.708204 6.782330 6.855655 6.928203 7.000000 7.071068 7.141428
##  [8] 7.211103 7.280110 7.348469 7.416198
#factorial
factorial(x_vector)

出力:

##  [1] 1.196222e+56 5.502622e+57 2.586232e+59 1.241392e+61 6.082819e+62
##  [6] 3.041409e+64 1.551119e+66 8.065818e+67 4.274883e+69 2.308437e+71
## [11] 1.269640e+73

統計関数

数学関数が値を変換するのに対し、統計関数は値を要約します。Rの標準インストールには、幅広い統計関数が含まれています。このチュートリアルでは、最も重要な関数について簡単に見ていきます。

基本的な統計関数

Operator 詳細説明
平均(x) xの平均
中央値(x) x の中央値
var(x) xの分散
sd(x) xの標準偏差
スケール(x) x の標準スコア (z スコア)
分位数(x) x の四分位数
概要(x) x の概要: 平均、最小、最大など。
speed <- dt$speed
speed
# Mean speed of cars dataset
mean(speed)

出力:

## [1] 15.4
# Median speed of cars dataset
median(speed)

出力:

## [1] 15
# Variance speed of cars dataset
var(speed)

出力:

## [1] 27.95918
# Standard deviation speed of cars dataset
sd(speed)

出力:

## [1] 5.287644
# Standardize vector speed of cars dataset		
head(scale(speed), 5)

出力:

##           [,1]
## [1,] -2.155969
## [2,] -2.155969
## [3,] -1.588609
## [4,] -1.588609
## [5,] -1.399489
# Quantile speed of cars dataset
quantile(speed)

出力:

##   0%  25%  50%  75% 100%
##    4   12   15   19   25
# Summary speed of cars dataset
summary(speed)

出力:

##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.
##     4.0    12.0    15.0    15.4    19.0    25.0

ここまでで、多くの R 組み込み関数を学習してきました。

お願い: 注意してください 引数のクラスつまり、数値、ブール値、または文字列です。たとえば、文字列値を渡す必要がある場合は、文字列を引用符で囲む必要があります。「ABC」。

Rで関数を書く

特定のタスクを実行する必要があり、既製の関数が存在しない場合、独自の関数を作成する必要があることがあります。ユーザー定義関数には、 , 引数ボディ.

function.name <- function(arguments) 
{
    computations on the arguments	
    some other code
}		

お願い: ユーザー定義関数には、組み込み関数とは異なる名前を付けることをお勧めします。 混乱を避けることができます。

引数が XNUMX つの関数

次のスニペットでは、単純な二乗関数を定義します。 この関数は値を受け取り、その値の XNUMX 乗を返します。

square_function<- function(n) 
{
  # compute the square of integer `n`
  n^2
}  
# calling the function and passing value 4
square_function(4)

Code 説明

  • 関数の名前は square_function です。 好きなように呼ぶことができます。
  • 引数「n」を受け取ります。 私たちは ユーザーが整数、ベクトル、または行列を渡すことができるように変数のタイプを指定しませんでした
  • この関数は入力「n」を受け取り、入力の XNUMX 乗を返します。 関数の使用が完了したら、rm() 関数を使用して削除できます。

# 関数を作成した後

rm(square_function)
square_function

コンソールには、関数が存在しないことを示すエラー メッセージ :Error: object 'square_function' not found が表示されます。

環境スコアping

Rでは、 環境 関数、変数、データフレームなどのオブジェクトの集合です。

RはRStudioを起動するたびに環境を開きます。

利用可能なトップレベルの環境は、 地球環境R_GlobalEnv と呼ばれるものがあり、 ローカル環境.

現在の環境のコンテンツを一覧表示できます。

ls(environment())

出力

## [1] "diff_ts"         "dt"              "speed"           "square_function"
## [5] "ts"              "x"               "x_vector"

R_GlobalEnv で作成されたすべての変数と関数を確認できます。

上記のリストは、RStudioで実行する過去のコードによって異なる場合があります。

注意してください nsquare_function 関数の引数は、このグローバル環境には存在しません。

各関数ごとに新しい環境が作成されます。上記の例では、関数 square_function() は、 地球環境.

の違いを明確にするために、 全体的な (NAIST) と ローカル 環境について、次の例を研究してみましょう

これらの関数は値 x を引数として受け取り、それを関数の外側と内側で定義する y に追加します。

グローバル環境で定義された変数yを使用する関数f

関数 f は出力 15 を返します。これは、y がグローバル環境で定義されているためです。 グローバル環境で定義された変数はすべてローカルで使用できます。 変数 y は、すべての関数呼び出し中に値 10 を持ち、いつでもアクセスできます。

変数 y が関数内で定義されている場合に何が起こるかを見てみましょう。

rm r を使用してこのコードを実行する前に、「y」をドロップする必要があります。

関数fが自身のローカル環境内でyを定義する

f(15) を呼び出したときの出力も 5 ですが、値 y を出力しようとするとエラーが返されます。 変数 y はグローバル環境にありません。

最後に、R は最新の変数定義を使用して関数の本体内に渡します。次の例を考えてみましょう。

R 関数本体内で y の最も内側の定義を使用する

関数の本体内に y 変数を明示的に作成したため、R は関数の外で定義された y 値を無視します。

複数引数関数

複数の引数を持つ関数を作成できます。 「回」と呼ばれる関数を考えてみましょう。 これは XNUMX つの変数を乗算する単純な関数です。

times <- function(x,y) {
  x*y
	}
times(2,4)

出力:

## [1] 8

いつ関数を書けばよいのでしょうか?

データサイエンティストは多くの反復作業を行う必要があります。ほとんどの場合、コードの塊を繰り返しコピー&ペーストします。たとえば、変数の正規化は、実行前に強く推奨されます。 機械学習 アルゴリズム。 変数を正規化する式は次のとおりです。

変数を正規化する式

R で min() 関数と max() 関数を使用する方法はすでに知っています。ティブル ライブラリを使用してデータ フレームを作成します。 Tibble は、これまでのところ、データ セットを最初から作成するのに最も便利な関数です。

library(tibble)
# Create a data frame
data_frame <- tibble(  
  c1 = rnorm(50, 5, 1.5), 
  c2 = rnorm(50, 5, 1.5),    
  c3 = rnorm(50, 5, 1.5),    
)

上記の関数を計算するために、2つのステップで進めます。最初のステップでは、c1 をリスケールした c1_norm という変数を作成します。2番目のステップでは、c1_norm のコードをコピー&ペーストし、c2 と c3 に変更するだけです。

列 c1 の関数の詳細:

ノミネーター: : data_frame$c1 -min(data_frame$c1))

分母: max(data_frame$c1)-min(data_frame$c1))

したがって、これらを除算して列 c1 の正規化された値を取得できます。

(data_frame$c1 -min(data_frame$c1))/(max(data_frame$c1)-min(data_frame$c1))

c1_norm、c2_norm、c3_norm を作成できます。

Create c1_norm: rescaling of c1		
data_frame$c1_norm <- (data_frame$c1 -min(data_frame$c1))/(max(data_frame$c1)-min(data_frame$c1))
# show the first five values
head(data_frame$c1_norm, 5)

出力:

## [1] 0.3400113 0.4198788 0.8524394 0.4925860 0.5067991

それは動作します。 コピーして貼り付けることができます

data_frame$c1_norm <- (data_frame$c1 -min(data_frame$c1))/(max(data_frame$c1)-min(data_frame$c1))

次に、c1_norm を c2_norm に、c1 を c2 に変更します。 同じことを行って c3_norm を作成します

data_frame$c2_norm <- (data_frame$c2 - min(data_frame$c2))/(max(data_frame$c2)-min(data_frame$c2))
data_frame$c3_norm <- (data_frame$c3 - min(data_frame$c3))/(max(data_frame$c3)-min(data_frame$c3))

変数 c1、c2、c3 を完全に再スケーリングしました。

しかし、この方法は間違いを起こしやすい。コピーした後に列名を変更し忘れる可能性がある。そのため、同じコードを2回以上貼り付ける必要がある場合は、毎回関数を作成するのが良い方法である。コードを数式に並べ替えて、必要なときに呼び出すことができる。独自の関数を作成するには、次の情報を提供する必要がある。

  • 名前: 正規化。
  • 引数の数: 必要な引数は XNUMX つだけです。これは、計算で使用する列です。
  • 本体: これは単に返したい式です。

正規化関数の作成を段階的に進めていきます。

ステップ1) 分子は x – min(x) で表されます。R では、分子を次のように変数に格納できます。

nominator <- x-min(x)

ステップ2) 分母を計算します。max(x) – min(x)。ステップ1の考え方を再現し、計算結果を変数に格納します。

denominator <- max(x)-min(x)

ステップ3) 分母と分母の間で割り算を行います。

normalize <- nominator/denominator

ステップ4) 呼び出し元の関数に値を返すには、return() 内で Normalize を渡して関数の出力を取得する必要があります。

return(normalize)

ステップ5) wrap関数を使用する準備ができましたping 括弧内のすべて。

normalize <- function(x){
  # step 1: create the nominator
  nominator <- x-min(x)
  # step 2: create the denominator
  denominator <- max(x)-min(x)
  # step 3: divide nominator by denominator
  normalize <- nominator/denominator
  # return the value
  return(normalize)
}

変数 c1 を使用して関数をテストしてみましょう。

normalize(data_frame$c1)

完璧に機能します。 最初の関数を作成しました。

関数は、反復的なタスクを実行するためのより包括的な方法です。以下のように、正規化式を複数の列に適用できます。

data_frame$c1_norm_function <- normalize (data_frame$c1)
data_frame$c2_norm_function <- normalize	(data_frame$c2)
data_frame$c3_norm_function <- normalize	(data_frame$c3)

例は単純ですが、数式の威力を推測することができます。上記のコードは読みやすく、コードを貼り付ける際に起こりがちなミスを回避できます。

条件付き関数

normalize() 関数は常に同じ動作をします。しかし、コードが異なる出力を返すようにするためには、関数に条件を追加する必要がある場合があります。

機械学習タスクでは、データセットをトレーニング セットとテスト セットに分割する必要があります。 トレイン セットにより、アルゴリズムがデータから学習できるようになります。 モデルのパフォーマンスをテストするには、テスト セットを使用してパフォーマンスの測定値を返すことができます。 R には 0.8 つのデータセットを作成する機能はありません。 それを行うための独自の関数を作成できます。 この関数は 80 つの引数を取り、split_data() と呼ばれます。 背後にある考え方は単純で、データセットの長さ (つまり、観測値の数) に 20 を掛けます。 たとえば、データセットを 100/0.8 に分割し、データセットに 100 行が含まれる場合、関数は 80*80 = XNUMX を乗算します。トレーニング データとして XNUMX 行が選択されます。

大気質データセットを使用して、ユーザー定義関数をテストします。 大気質データセットには 153 行があります。 以下のコードでそれを確認できます。

nrow(airquality)

出力:

## [1] 153

以下のように進めていきます。

split_data <- function(df, train = TRUE)
Arguments:
-df: Define the dataset
-train: Specify if the function returns the train set or test set. By default, set to TRUE

この関数には 2 つの引数があります。引数 train はブール パラメーターです。これが TRUE に設定されている場合、関数はトレーニング データセットを作成し、それ以外の場合はテスト データセットを作成します。

normalize() 関数で行ったのと同じように進めることができます。一度だけ使用するコードであるかのようにコードを記述し、条件を含むすべてを本体で囲んで関数を作成します。

ステップ1:

データセットの長さを計算する必要があります。 これは関数 nrow() で行われます。 Nrow は、データセット内の行の合計数を返します。 これを可変長と呼びます。

length<- nrow(airquality)
length

出力:

## [1] 153

ステップ2:

長さに 0.8 を掛けます。 選択する行数を返します。 153*0.8 = 122.4 となります。

total_row <- length*0.8
total_row

出力:

## [1] 122.4

大気質データセット内の 122 行の中から 153 行を選択したいと考えています。 1 から total_row までの値を含むリストを作成します。 結果をsplitという変数に保存します。

split <- 1:total_row
split[1:5]

出力:

## [1] 1 2 3 4 5

Split はデータセットから最初の 122 行を選択します。 たとえば、変数 Split が値 1、2、3、4、5 などを収集していることがわかります。 これらの値は、返す行を選択するときのインデックスになります。

ステップ3:

分割変数に格納されている値に基づいて、大気質データセット内の行を選択する必要があります。 これは次のように行われます。

train_df <- airquality[split, ] 
head(train_df)

出力:

##[1]    Ozone Solar.R Wind Temp Month Day
##[2]  51    13     137 10.3   76     6  20
##[3]  15    18      65 13.2   58     5  15
##[4]  64    32     236  9.2   81     7   3
##[5]  27    NA      NA  8.0   57     5  27
##[6]  58    NA      47 10.3   73     6  27
##[7]  44    23     148  8.0   82     6  13

ステップ4:

残りの行 123:153 を使用してテスト データセットを作成できます。 これは、split の前に – を使用することで実行されます。

test_df <- airquality[-split, ] 
head(test_df)

出力:

##[1] Ozone Solar.R Wind Temp Month Day
##[2]  123    85     188  6.3   94     8  31
##[3]  124    96     167  6.9   91     9   1
##[4]  125    78     197  5.1   92     9   2
##[5]  126    73     183  2.8   93     9   3
##[6]  127    91     189  4.6   93     9   4
##[7]  128    47      95  7.4   87     9   5

ステップ5:

関数の本体内で条件を作成できます。 列車セットを返すためにデフォルトで TRUE に設定されたブール値である引数 train があることを思い出してください。 条件を作成するには、if 構文を使用します。

  if (train ==TRUE){ 
    train_df <- airquality[split, ] 
      return(train)		
  } else {
    test_df <- airquality[-split, ] 
      return(test)		
  }

これで関数を書くことができます。 関数を任意の環境で試したいため、airquality を df に変更するだけで済みます。 データフレーム空気の質だけではありません:

split_data <- function(df, train = TRUE){
  length<- nrow(df)
  total_row <- length *0.8
  split <- 1:total_row
  if (train ==TRUE){ 
    train_df <- df[split, ] 
      return(train_df)		
  } else {
    test_df <- df[-split, ] 
      return(test_df)		
  }
}

それでは、作成した関数を大気質データセットで試してみましょう。122行の訓練セットと31行のテストセットを用意する必要があります。

train <- split_data(airquality, train = TRUE)
dim(train)

出力:

## [1] 122   6
test <- split_data(airquality, train = FALSE)
dim(test)

出力:

## [1] 31  6

よくあるご質問

定義の中で値を指定します。例えば、`function(df, train = TRUE)` のように指定します。呼び出し元がその引数を省略した場合、R はデフォルト値を使用します。デフォルト値は遅延評価されるため、同じ関数の別の引数をデフォルト値が参照することもあります。

はい。関数は停止する限り自身を呼び出すことができます。ping 条件によって連鎖が終了します。たとえば、nが1に達したときに1を返す階乗などです。深い再帰は式のネストの制限に達する可能性があるため、反復処理の方が安全な場合が多いです。

いいえ。Rは最後に評価された式の値を自動的に返すため、square_function()はreturn()なしで動作します。return()は、早期終了が必要な場合、または明示的な結果によって関数が読みやすくなる場合に使用してください。

R は、まず完全一致で一致し、次に部分一致で一致し、最後に残りの部分について位置で一致します。引数を明示的に指定することで、例えば seq(45, 55, by = 1) のように、呼び出しが読みやすくなり、意図しない順序変更を防ぐことができます。

名前が割り当てられずに作成された関数で、通常は sapply() または lapply() に直接渡されます。R 4.1 ではバックスラッシュの省略形が追加されたため、\(x) x^2 は function(x) x^2 とほぼ同じ処理をはるかに少ない時間で実行できます。ping.

新しい定義では、その環境内の組み込み関数が隠蔽されるため、length() を呼び出すと、基本バージョンではなく独自のバージョンが実行される可能性があります。rm() でコピーを削除するか、最初から異なる名前を付けてください。

AIアシスタントは、平易な英語のコメントから関数の骨組みを作成し、適切な引数のデフォルト値を提案し、単体テストを生成します。生成されたコードは必ず実際のデータで実行してください。見た目はもっともらしく見えるR関数でも、実際には誤った値を返すことがあるからです。

Yes. Rstudio デスクトップ版2023.09.0以降ではオプトイン方式が採用されています。 GitHubコパイロット 統合機能。コメントから関数本体を補完しますが、データは参照できないため、各提案を必ず確認してください。