5  繰り返し文(Looping)

コンピューターのいいところは、同じことを何度繰り返しても疲れないことです。Excelで表を作るときに、コピーアンドペーストを何百回も繰り返し、何時間も費やしたことがある方は多いかと思います。このような繰り返しがあっても、すべてをコンピューターに任せることができれば、コンピューターは疲れることなく、一瞬で繰り返し作業を終えてくれます。

ただし、コンピューターに繰り返し作業をしてもらいたければ、具体的に繰り返し作業を指示しないといけません。プログラミングでコンピューターに繰り返し作業を指示するためのものが、繰り返し文です。Rには繰り返し文として、for文、while文、repeat文の3つが設定されています。

表1:Rで使える繰り返し文
繰り返し文 繰り返し文の形式
for文 for(i in ベクター){繰り返す処理}
while文 while(条件式){TRUEの時に繰り返す処理}
repeat文 repeat{breakまで繰り返す処理}

5.1 for文

for文はRで、そして他の言語でもよく設定されている、最も典型的な繰り返し文の一つです。Rでは、for文は、

for(繰り返しの条件){繰り返す処理}

という形で表記します。このうち、繰り返しの条件に関しては、

for(i in c(1, 2, 3, 4, 5))

といった形で、「変数 in ベクター」という形で書きます。これは、ベクターの要素を前から順番に変数に入れていく、ということを意味しています。

for文での繰り返し処理
for(i in c(1, 2, 3, 4, 5)){print(i)} # ベクターの要素をiに入れて、iを表示する
## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 5

for(i in c("dog", "cat", "pig", "horse")){print(i)} # 文字列のベクターでも同じ
## [1] "dog"
## [1] "cat"
## [1] "pig"
## [1] "horse"

上のfor文で用いているprint関数は、オブジェクトを表示させるための関数です。for文の処理中でオブジェクトを表示させる場合にはprint関数を明示的に用いる必要があります。また、for文で用いる変数名にはiを用いるのが普通です。このiはイテレーター(iterator、繰り返すもの)の略だと思いますが、よくわかりません。for文の中でfor文を呼び出す、つまり入れ子(ネスト)にする場合には、i以降の変数として、jk…とアルファベット順に使っていくことが多いです。

for文を入れ子にする場合には、Rでは以下のような表現を用いることができます。

for文を入れ子(ネスト)にする
for(i in c(1, 2)) for(j in c(4, 5)){
  print(paste0("i=", i, ", ", "j=", j))
}
## [1] "i=1, j=4"
## [1] "i=1, j=5"
## [1] "i=2, j=4"
## [1] "i=2, j=5"

# 以下も同じ内容のスクリプト
for(i in c(1, 2)){
  for(j in c(4, 5)){
    print(paste0("i=", i, ", ", "j=", j))
  }
}
## [1] "i=1, j=4"
## [1] "i=1, j=5"
## [1] "i=2, j=4"
## [1] "i=2, j=5"

上の例では、iにベクターの要素が前から順番に代入されているのがわかると思います。for文では、このinの後のベクターとして連続した整数を用いる場合が多いのですが、整数の数が多かったり、繰り返したい回数がとても多いと、いちいちc関数でベクターを作るのは大変です。Rでは、連続した数値のベクターを作る場合、「:(コロン)」を用いることができます。コロンを用いたベクターの作り方は以下の通りです。

:(コロン)を用いたベクターの作成
1:5
## [1] 1 2 3 4 5

10:20
##  [1] 10 11 12 13 14 15 16 17 18 19 20

0.5:5.5
## [1] 0.5 1.5 2.5 3.5 4.5 5.5

for文はコロンを使用して、以下のような形で書くことができます。

コロンを使ったfor文
for(i in 1:5){
  print(i - 1)
}
## [1] 0
## [1] 1
## [1] 2
## [1] 3
## [1] 4

ベクターを変数としてあらかじめ準備しておけば、ベクターの要素に対して同じ処理を繰り返す事もできます。

変数を使ったfor文
vec <- c("dog", "cat", "pig", "horse")
for(i in vec){
  isanimal <- paste(i, "is animal.") # iに文字列をつなぐ
  print(isanimal) # 文字列を繋いだものを表示する
}
## [1] "dog is animal."
## [1] "cat is animal."
## [1] "pig is animal."
## [1] "horse is animal."

for文を用いれば。様々な繰り返し作業をRに行ってもらうことができます。for文とif文の組み合わせで、繰り返しの中で条件判断を行い、ベクターの要素ごとに異なる処理を行うこともできます。

for文を途中で止める場合にはbreakを、繰り返しをスキップするときにはnextを用います。

for文でのnextとbreak
for(i in 1:5){
  if(i == 2){next} # iが2のときには繰り返しをスキップする
  if(i == 4){break} # iが4のときには繰り返し自体を止める
  print(i)
}
## [1] 1
## [1] 3

5.2 while文

while文は、条件式に定めた条件がTRUE(真)である場合は繰り返し、FALSE(偽)になったら繰り返しを中止する、繰り返し文の一つです。while文は以下のように記述して用います。

while(条件式){TRUEのときに繰り返す処理}

while文では、for文のように繰り返し処理でベクターの要素を引き出すようなことはできないので、処理の中で要素を呼び出すような形を取ることが多いです。

while文
x <- 1 # xは1
while(x < 5){ # xが5以下の時、以下の処理を繰り返す
  print(x) # xを表示する
  x <- x + 1 # xに1を足す
}
## [1] 1
## [1] 2
## [1] 3
## [1] 4

この、「x <- x + 1」のような表現はプログラミング初心者には変に感じるかもしれませんが、繰り返し文中で変数を1ずつ足して更新していく、プログラミング言語ではよく見る表現です。他の言語でも同じような書き方をすることが多く、変数に1を足すための演算子(インクリメント演算子)や1を引くための演算子(デクリメント演算子)を持つプログラミング言語も多いです(Rにはありません)。

while文では条件がTRUEであれば繰り返しが続くため、条件がFALSEにならないような場合には、永遠に繰り返し処理を行うことになります(無限ループ)。Rで無限ループにハマったときには、慌てず騒がず、「stopボタン」を押しましょう。また、コンソールを選択し、Escキーを押すことでも無限ループを停止することができます。

whileを使ったときの無限ループ
while(TRUE){ # 無限ループ
  print("I`m looping infinitely.")
}

図1:RstudioのStopボタン

図1:RstudioのStopボタン

5.3 repeat文

repeat文は、同じ処理を繰り返すときに使います。repeat文から抜けるときには、breakを実行します。breakは条件判断(if文など)を用いて実行することになります。breakがない場合には、無限ループすることになります。

repeat文による繰り返しと、breakによる中断
x <- 1
repeat{
  x <- x + 1 # printより前にxを1増やす
  print(x)
  if(x >= 5){break} # xが5以上ならrepeatをやめる
}
## [1] 2
## [1] 3
## [1] 4
## [1] 5

Rでは繰り返し処理を行うこと自体が割と少ないので、無限ループに陥ることは稀です。無限ループはこのwhile/repeat文を使った時ぐらいにしか発生しませんし、他の言語と異なりwhile文やrepeat文自体使う機会が少なめです。どのようなプログラミング言語でも無限ループを起こすことは普通にあり、無限ループを止める方法は必ずありますので、無限ループでコンピュータが壊れるようなことはありません。