R言語

【R言語】applyファミリーの使い方を詳しく見ていく

  1. HOME >
  2. R言語 >

【R言語】applyファミリーの使い方を詳しく見ていく

スポンサーリンク

今回はR言語におけるapplyファミリーをみていきます。

applyファミリーとは、関数apply、mapply、lapply、sapply、tapplyを含む関数族のことです。

これらの関数を用いることで、ベクトル、行列・データフレーム、リストの各要素に対して、高速に演算を行うことが可能となります。

Rを使ったことがあるなら誰しもが「for文やwhile文が遅すぎて、実行できない!」、「ベクトルや行列単位の演算が高速で優れているのに、各要素の探索・演算に弱すぎる!」と不満を抱いたことがあると思います。

今回紹介するapplyファミリーを用いることで、これらの実行時間を解消することができます。

ぜひ例を参考にして、applyファミリーを使ってみてください。

今回紹介するコードも下のリンクからダウンロードすることができます。自由に使ってください。

統計学初学者向けの教材です
¥2,970 (2022/06/01 17:41時点 | Amazon調べ)

applyファミリー

applyファミリーはapply、mapply、lapply、sapply、tapplyで構成されます。

ベクトル、行列・データフレーム、リストの各要素に対して、高速に同じ演算を適用することができます。

では、applyファミリーの各関数についてみていきます。

apply

関数applyは次のように使用します。

apply(X, MARGIN, FUN, ...)

関数applyの引数を以下に示します。

Xベクトル、行列・データフレーム
MARGINMARGIN = 1のときは、Xの行ベクトルに対して関数を適用する。MARGIN = 2のときは、Xの列ベクトルに対して適用する。
FUNXの各要素に対して適用する関数

関数applyの簡単な使用例を見ていきます。

引数Xとして次の行列を与えます。

この行列を次で、Aに代入し、apply関数によってAの行ベクトルに対して関数sumを適用します。

次に示すデータフレームをみると、apply関数の意味をつかみやすいです。data.frameを用いて、4列目にapplyの結果を持つsumAboutRowという列を 追加してみましょう。

上の実行結果からわかる通り、X1、X2、X3までの行列Aの各行の和が4列目のsumAboutRowとなっていることが分かります。行方向について、関数sumが適用されていることが確認できます。

また、引数MARGINを2に変更すると、今度は列方向に対して和をとることができます。

mapply

関数mapplyは次のように使用します。

mapply(X, MoreArgs = NULL, SIMPLIFY = TRUE, ..., USE.NAMES = TRUE)

関数mapplyの引数を以下に示します。

FUN適用する関数
...関数に適用するベクトル、行列・データフレーム、リスト
MoreArgsFUNの引数を要素に持つリスト
SIMPLIFYlogicalまたはcharacter型。結果をベクトルにするかリストのままにするか。
USE.NAMES演算結果にnames属性(行名、列名、次元名)を持たせるか。

関数mapplyはapplyの多変量版といえます。引数...部分にベクトルX, Y , Z, ...を代入することで、X, Y, Zの3つに対して演算を行うことができます。

関数mapplyは次のように使用します。

引数USE.NAMESをFALSEにすると列名cOne、cTwo、cThreeが結果に含まれていないことが分かります。

lapply

関数lapplyは次のように使用します。

lapply(X, FUN, ...)

関数lapplyの引数を以下に示します。

Xリスト
FUNリストXの各要素に対して適用する関数

関数lapplyはリストの要素に対して、関数を適用することができます。

lapplyの使用例を見ていきましょう。

上の例では、c(1 : 10)、NULL、c("ウサギ", "さんの", "統計学", "サロン")の3つのベクトルを要素にもつリストに関数lengthを適用しています。

各要素のベクトルの長さ10,0,4をリストで返しているのが分かります。

sapply

関数sapplyは次のように使用します。

sapply(X, FUN, ..., simplify = TRUE, USE.NAMES = TRUE)

関数sapplyの引数を以下に示します。

X関数FUNに適用するベクトルまたはリスト
FUN適用する関数
...FUNの引数
SIMPLIFYlogicalまたはcharacter型。結果をベクトルにするかリストのままにするか。
USE.NAMES演算結果にnames属性(行名、列名、次元名)を持たせるか。

関数sapplyの使用例を見ていきます。

lapplyと比較したいので、先ほど用いたリストを用います。

次に、簡便のためこのリストをlistAに代入します。

関数sapplyを用いて、このリストの各要素に対して関数pasteを適用してみます。

sapplyの引数...の部分に関数pasteの引数を指定することで、pasteの出力を変更することもできます。

上の例では、関数pasteの引数collapse = ""とすることで、各3つのベクトルの要素を 結合させることができます。

tapply

関数tapplyは次のように使用します。

tapply(X, INDEX, FUN = NULL, …, default = NA, simplify = TRUE)

関数tapplyの引数を以下に示します。

Xベクトル(levelsなどのグループを表すベクトル)。
INDEX1つまたは、それ以上のfactor型のオブジェクトをもつリスト。Xと同じ長さを持つ必要がある。
FUN適用する関数
default(simplify  = TRUEの場合のみ)出力する配列の初期値となる。
simplify演算結果にnames属性(行名、列名、次元名)を持たせるか。

関数tapplyのつかいかたを紹介します。

統計解析のfactor型の各levelsごとの演算に対して、tapplyが役に立ちます。

例として、データセットToothGrowthを用います。ToothGrowthはsupp、doseという2つのfactorを持ちます。この2つのfactorの各levelsの組み合わせについて、平均を求めるには次のようにtapply関数を用います。

applyファミリーの使用例

上の簡単な使用例だけでは、applyファミリーをどのように扱えばよいか想像しにくいので、具体的な使用例を紹介します。

ここでは、applyとlapplyのみを解説します。

applyはベクトルや行列・データフレームの演算が可能であるのに対し、lapplyはリストの演算が可能であるので、

2つの使いかたが分かれば、ほとんどのオブジェクト(ベクトル、行列・データフレーム、リスト)に対し、高速な繰り返し処理を行うことが可能となります。

apply

実際に、データセットを用いたapplyの使用例をみていきます。次のRに標準で入っている集計表のデータセットoccupationalStatusを用います。

このデータセットの各行の和、各列の和、総計を求めてみましょう。

次のように関数applyを用いることで各行の和を計算することができます。

関数cbindを用いて、これらの和のベクトルをdataに結合させます。

次に、applyを用いて列方向に関数sumを適用することで、各列の和と総計を計算することができます。

最後にこのcolSumrbindでdataに結合させることで、各行、各列の和と総計を集計表に加えることができます。

また、次に示す例のように関数を自分で定義することもできます。

apply関数の引数FUNにfunction(x) {...}を代入することでapply内にローカルの関数を定義することができます。

次のコードは、xy_coordinatesというxy座標が格納されたデータフレームの異なるi番目とj番目の座標のユークリッド距離が整数であるかを判定する関数となります。

apply関数の最初の引数には、i番目とj番目の全組み合わせcombn(nrow(xy_coordinates), 2)を与え、そのデータフレームの各列のインデックスについて距離を計算しています。

また、距離が整数であるかどうかは、distance %% 1 == 0のように1で割った余りが0であるという論理演算を行うことで判定可能です。

上では、xy座標は次のように与えられています。

このxy座標に対し、先ほどのapply関数を用いると、次のようにi番目とj番目の座標の組み合わせについて、結果が出力されます。

lapply

次にlapplyの使用例を見ていきます。

次のlistAには、int型のc(3, 8, 1, 6, 3, 9, 2)float型のsqrt(c(7, 5, 13, 17, 3, 10, 19))string型のc("j", "d", "y", "l", "m", "s", "a")が格納されています。

このリストの各要素をソートするには、次のようにlapplyを用います。

実行すると、各要素についてソートされたベクトルが出力されているのが確認できます。

また、正規表現に関するlapplyの使用例もみていきます。

次のように"Hello Worlrd !!!""ウサギさんの統計学サロン"に数字が混在しているベクトルを与えます。

スペース区切りで数字を取り除いた元の文字列を抽出したい場合、関数strsplitを用いて、分割後のリストをlapplyに適用します。

実行すると、数字を除去した文字列が節ごとに出力されているのが確認できます。

まとめ

applyファミリーの使用法についてみていきました。

Rでは大きなデータフレームを用いる際にfor 文などの繰り返し処理を行うと、計算時間が膨大になることがほとんどです。

applyファミリーを用いることでこれらの実行時間を大幅に減らすことができます。

for文を使わず、積極的にapplyファミリーを使っていきましょう。

スポンサーリンク

  • この記事を書いた人
  • 最新記事

usagi-san

統計学とゲームとかをメインに解説していくよ。 数式とかプログラミングコードにミスがあったり質問があったりする場合はコメントで受け付けます。すぐに対応します。

-R言語
-,