R言語の条件分岐、特にif文について、詳しく解説します。

Rの条件分岐について

条件分岐とは条件の真偽により処理の流れを分岐させることをいいます。if文は条件分岐の一つです。if文はあらゆるプログラミング言語で使用されていますが、実のところ、R言語においては使用する機会はあまり多くありません。なぜならば、R言語は統計解析向けのプログラミング言語であり、処理の多くはデータフレーム上の操作となるからです。しかし、プログラミングにおいてはとても重要な概念であることと、if文に近しいifelse()を使用する機会が多いため、条件分岐そのものは習得しておく必要があります。

if文

if文についてこれから解説しますが、if文において最も重要なことは、所定の処理を実行するかしないかのどちらかしかないということです。このことを頭の片隅にでも置いて、以下を見てください。

if文の書き方

if文の書き方は次になります。これは、条件1の真偽判定の結果が真(TRUE)ならばifの後の{}内の処理1-1、処理1-2、処理1-3が実行されます。真偽判定の結果が偽(FALSE)ならば何も起こりません。


if (条件1) {
    処理1-1
    処理1-2
    処理1-3
}

実際に、簡単なコードで確かめてみます。次は条件1が真(TRUE)となる例です。出力を見ると、{}内の処理が実行されていることが確認できます。


if (2 > 1) {
(con)    print("処理1-1")
(con)    print("処理1-2")
(con)    print("処理1-3")
(con)}
(out)[1] "処理1-1"
(out)[1] "処理1-2"
(out)[1] "処理1-3"

次は条件1が偽(FALSE)となる例です。何も出力されないことから、{}内の処理が実行されないことが確認できます。


if (2 < 1) {
(con)    print("処理1-1")
(con)    print("処理1-2")
(con)    print("処理1-3")
(con)}

if, else文の書き方

先ほどはif文の条件の真偽判定の結果が真(TRUE)のときだけ処理が実行されました。偽(FALSE)のときにも処理が実行されるような書き方が次になります。
これは、条件1の真偽判定の結果が真(TRUE)ならばifの後の{}内の処理1-1、処理1-2、処理1-3が実行されます。真偽判定の結果が偽(FALSE)ならばelseの後の{}内の処理9-1、処理9-2、処理9-3が実行されます。このif, else文の特徴は、条件が真であれ偽であれ必ず所定の処理が実行されることです。


if (条件1) {
    処理1-1
    処理1-2
    処理1-3
} else {
    処理9-1
    処理9-2
    処理9-3
}

実際に、簡単なコードで確かめてみます。次は条件1が真(TRUE)となる例です。出力を見ると、ifの後の{}内の処理が実行されていることが確認できます。


if (2 > 1) {
(con)    print("処理1-1")
(con)    print("処理1-2")
(con)    print("処理1-3")
(con)} else {
(con)    print("処理9-1")
(con)    print("処理9-2")
(con)    print("処理9-3")
(con)}
(out)[1] "処理1-1"
(out)[1] "処理1-2"
(out)[1] "処理1-3"

次は条件1が偽(FALSE)となる例です。出力を見ると、elseの後の{}内の処理が実行されていることが確認できます。


if (2 < 1) {
(con)    print("処理1-1")
(con)    print("処理1-2")
(con)    print("処理1-3")
(con)} else {
(con)    print("処理9-1")
(con)    print("処理9-2")
(con)    print("処理9-3")
(con)}
(out)[1] "処理9-1"
(out)[1] "処理9-2"
(out)[1] "処理9-3"

if, else if文の書き方

先ほどのif, else文は条件が真であれ偽であれ必ず所定の処理が実行されました。そうではなく、所定の条件が真のときにだけ実行されるようにするにはif, else if文を使用します。if, else if文の書き方は次になります。これは条件1が真(TRUE)ならばifの後の{}内の処理1-1、処理1-2、処理1-3が実行され、このif文が終了します。条件1が偽(FALSE)ならば条件2の真偽判定が行われ、条件2が真(TRUE)ならばelse ifの後の{}内の処理2-1、処理2-2、処理2-3が実行され、このif文が終了します。条件2が偽(FALSE)ならばこのif文は終了します。実際にはelse ifはいくつあっても構いません。


if (条件1) {
    処理1-1
    処理1-2
    処理1-3
} else if (条件2) {
    処理2-1
    処理2-2
    処理2-3
}

実際に、簡単なコードで確かめてみます。次は条件1が真(TRUE)となる例です。出力を見ると、ifの後の{}内の処理が実行されていることが確認できます。


x <- 20 if (x > 10) {
(con)    print("処理1-1")
(con)    print("処理1-2")
(con)    print("処理1-3")
(con)} else if (x > 1) {
(con)    print("処理2-1")
(con)    print("処理2-2")
(con)    print("処理2-3")
(con)}
(out)[1] "処理1-1"
(out)[1] "処理1-2"
(out)[1] "処理1-3"

次は条件1が真(FALSE)、条件2が真(TRUE)となる例です。出力を見ると、else ifの後の{}内の処理が実行されていることが確認できます。


x <- 5 if (x > 10) {
(con)    print("処理1-1")
(con)    print("処理1-2")
(con)    print("処理1-3")
(con)} else if (x > 1) {
(con)    print("処理2-1")
(con)    print("処理2-2")
(con)    print("処理2-3")
(con)}
(out)[1] "処理2-1"
(out)[1] "処理2-2"
(out)[1] "処理2-3"

次は条件1が真(FALSE)、条件2が偽(FALSE)となる例です。何も出力されないことから、{}内の処理が実行されないことが確認できます。


x <- 0 if (x > 10) {
(con)    print("処理1-1")
(con)    print("処理1-2")
(con)    print("処理1-3")
(con)} else if (x > 1) {
(con)    print("処理2-1")
(con)    print("処理2-2")
(con)    print("処理2-3")
(con)}

if, else if, else文の書き方

最後は、これまでに解説したif、else if、elseを組み合わせる書き方です。ここまでくれば詳し説明は不要でしょうから、直前のコードを少し変更したコードだけを載せておきます。


x <- 0 if (x > 10) {
(con)    print("処理1-1")
(con)    print("処理1-2")
(con)    print("処理1-3")
(con)} else if (x > 1) {
(con)    print("処理2-1")
(con)    print("処理2-2")
(con)    print("処理2-3")
(con)} else {
(con)    print("処理9-1")
(con)    print("処理9-2")
(con)    print("処理9-3")
(con)}
(out)[1] "処理9-1"
(out)[1] "処理9-2"
(out)[1] "処理9-3"

{}の省略

if、else if、elseにおいて、{}内の処理が1つのとき、すべてを1行に記載すると{}を省略することができます。とはいえ、実際に{}がない書き方はif単体で使用する場合がほとんどです。ifとelseを使用する場合は、後述するif_else()が好んで使われます。


x <- 0 if (x > 10) print("処理1-1") else if (x > 1) print("処理2-1") else print("処理9-1")
(out)[1] "処理9-1"

ifelse()

ifelse()は、if、else文を関数化したものです。ExcelのIF関数や他のプログラミング言語でいうところの三項演算子と同様のものになります。ifelse()はRに標準で搭載されている関数ですが、実際にはtidyverseに含まれているdplyrパッケージのif_else()を使用することが多いので、if_else()の解説をします。if_else()の解説には次のように記載されています。

Compared to the base ifelse(), this function is more strict. It checks that true and false are the same type. This strictness makes the output type more predictable, and makes it somewhat faster.

基本のifelse()と比較すると、この関数はより厳格です。trueとfalse が同じ型であることを確認します。この厳密性により、出力タイプはより予測可能になり、いくらか高速になります。

if_else()の使い方は次になります。

if_else(条件, 真(TRUE)の処理, 偽(FALSE)の処理)

簡単なコードで確認してみます。条件にはベクトルも使うことができる点に注意してください。このことから、データフレームのある列に対してif_else()を適用する場面は多々あります。


if_else(2 > 1, 10, -10)
(out)[1] 10
(out)
if_else(1:10 > 5, 7, 3)
(out) [1] 3 3 3 3 3 7 7 7 7 7

switch文

Rには他のプログラミング言語でいうところのswitch文がありません。しかし、if、else文に対応するifelse()があるようにswitch文に対応するswitch()があります。しかし、switch()を使用する機会はほぼないと思われますので、解説は割愛します。また、データフレームの操作として、switch文のようなことがしたいときにはswitch()は使用せず、tidyverseパッケージにも含まれているdplyrパッケージ内のcase_when()を使用することがほとんどです。case_when()については後日解説します。

R入門 条件分岐(if, else if, else)