制御文 (繰返し,条件分岐)

目次

コンピュータは正しくプログラムすれば,同じ作業の繰返し (ループ)や,条件によって処理を変えるといったことを速く正確に行うことができる。繰返しや条件分岐を行うためには制御文と呼ばれる構文を用いる。ここで取り扱うif文,for文,while文は,多少の文法の違いはあれど,どの言語でもよく使われる基本的な構文である。

if文

if文は,条件分岐を行うための制御文。与えた条件が真であるか偽であるかによって,処理内容を変えることができる。

if (条件) {
  ...条件が真の場合の処理内容...
} else {
  ...条件が偽の場合の処理内容...
}

ただし,条件が偽の場合に何も実行しないのであれば,else以降を省略しても良い。

if文の条件は,TRUE (真)かFALSE (偽)を返す式である。よく使われる条件 (論理式)の書き方は以下の通り。

条件 意味
x == 10 xが10と等しい
x != 10 xが10と等しくない !(x==10)とも書ける
x > 10 xが10より大きい
x < 10 xが10より小さい
x >= 10 xが10以上
x <= 10 xが10以下
x %in% A xがベクトルAに含まれる

このうち,とくにAとBが等しいという条件を (A == B)と書くことに注意。=が1つだと,条件ではなく代入を表すことになるため,エラーとなる。

for文

for文は,同じ作業を繰り返し行う (ループさせる)ための制御文。Rでのfor文の書き方は,以下の通り。

for (変数 in ベクトル) {
  ...処理内容...
}

これで,ベクトルの要素を1つずつ変数に代入して,処理内容を実行することができる。たとえば,1から10までの数字を表示したければ以下のように書けば良い。

for (i in 1:10) {
  print(i)
}
[1] 1
[1] 2
[1] 3
[1] 4
[1] 5
[1] 6
[1] 7
[1] 8
[1] 9
[1] 10

ここで,1:10c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)と同じ意味である。ベクトルは数値でなくても良い。たとえば,文字列のベクトルを用意して,その要素を1つずつ取り出して表示することもできる。

for (i in c("a", "b", "c")) {
  print(i)
}
[1] "a"
[1] "b"
[1] "c"

残りの処理を実行せずに,ループを次に進めるにはnextを用いる。たとえば,1から10までの数字を表示するときに,4の倍数を表示しないようにするには,以下のようにする。

for (i in 1:10) {
  if (i %% 4 == 0) next
  print(i)
}
[1] 1
[1] 2
[1] 3
[1] 5
[1] 6
[1] 7
[1] 9
[1] 10

i %% 4は,iを4で割った余りを返す。ここでは,iが4の倍数である場合にはnextを実行して,print(i)を実行せずに,次のループに進んでいる。

また,ループを途中で抜けさせたい場合には,breakを用いる。たとえば,名前のベクトルの要素を1つずつ表示させていき,“Jim”が出たらループを抜けるには,以下のようにする。

names <- c("John", "Jane", "Jim", "Jill")
for (i in names) {
  print(i)
  if (i == "Jim") break
}
[1] "John"
[1] "Jane"
[1] "Jim"

while文

while文は,条件が真である限り,処理を繰り返す。while文の書き方は以下の通り。

while (条件) {
  ...処理内容...
}

たとえば,1から10までの数字を表示するには,以下のようにする。

i <- 1
while (i <= 10) {
  print(i)
  i <- i + 1
}
[1] 1
[1] 2
[1] 3
[1] 4
[1] 5
[1] 6
[1] 7
[1] 8
[1] 9
[1] 10

ここでは,最初にiに1を代入し,while文でiが10以下である限り,括弧内の処理を実行する。当然だが,iに変化がなければ無限ループになるので,最後にiに1を加えるという処理を行っている。この例だとfor文の方がわかりやすいが,while文はあらかじめ繰返しの回数がわからないときに用いるのが良い。for文と同じように,nextbreakを用いることもできる。

apply系関数

基本的には,if文とfor文を理解していれば効率的に処理を実行するプログラムを書くことができる。ただし,Rはfor文の処理が遅いと言われており,より高速な処理が求められるケースではfor文の代わりにapply系の関数が用いられることが多い。そのため,自分では使わないとしても,apply系の関数を使った他の人のプログラムを読むことはできるようになっておいた方が良い。apply系の関数を理解するためには,リストオブジェクトや行列について知っておく必要があるため,それらを説明してからapply系の関数の使い方を説明する。