R の for loop:
R で繰り返し処理を行いたい場合のスクリプト

UB3/informatics/r/for_loop_r

このページの最終更新日: 2024/09/30

  1. 概要: R の for loop
  2. for loop の結果をリストに格納する
  3. 実例 1: 偶数の数を数える
  4. 実例 2: R の for loop で変数を扱う

広告

概要: R の for loop

for loop は、繰り返し処理を行いたい場合に、さまざまな言語で共通して使われる形式である。言語によって書き方に多少の違いがある。このページでは、R での for loop の使い方と実例を示す。

あらかじめ繰り返し数を指定するのが for、特定の条件式を与えて、その式が偽になるまで処理を続けるのが while である。

基本系は以下の通り。

for (val in x) # val という変数に入れるデータを指定
{
# valに関する処理を指定
}

処理をただ繰り返したい場合は、val in 1:5 のようにすればよい。val が実際に使われていなくても、5 回の繰り返しになる。

メモ

  • 文字列のリスト (ベクター形式) から順に実行したいとき。まずは val = c("文字列1") として、for loop なしで解析を実行する。動くようだったら vallist = c("文字列1", "文字列2") のようにリストを作り、for (val in vallist) とすれば、スクリプトの形を変えずに実行できる。

for loop の結果をリストに格納する

自らを rbind または cbind に入れる 方法で、for loop から出力される結果を list や data frame にまとめることができる (4)。

for loop に入る前に、a_row <- NULL のようにして「入れ物」を用意しておかないと、変数がみつからないというエラーになる。

実例 1: 偶数の数を数える

以下の例 (文献 1 を改変) では、まず x にいくつかの番号を入れ、それらについて一つずつ繰り返し処理を行う。処理は if 以下で、「数値が 2 で割り切れるならば、count という変数に 1 を加える」というもの。

そのために、x を指定した後に count を 0 と定義している。最後、print(count) で変数 count を出力。この場合、2 と 12 が偶数なので、個数として 2 が出力されるはずである。


x <- c(1, 2, 3, 5, 7, 9, 12)
count <- 0
for (val in x) {
if(val %% 2 == 0) count = count+1
}
print(count)


なお、%% と == は R の概要 のページにまとめた演算子である。val %% 2 は val を整数の範囲で 2 で割った余り、== は「等しい」を示す。

if statement もいずれまとめる予定。とりあえず参考ページ その 1その 2

R の for loop で変数を扱う

paste0()関数, assign()関数 との組み合わせ

x <- c("a", "b", "c")
for (val in x) {
print(val)
}


アウトプットは以下のようになり、a, b, c が順に print 関数で書き出されたことになる。

[1] "a"
[1] "b"
[1] "c"


ところが、以下のスクリプトは object 'val.csv' not found というエラーになる。ワーキングディレクトリにある a.csv, b.csv, c.csv というファイルを順に読んで、それぞれ a, b, c というオブジェクトに保存するという内容を書いたつもりだったのだが。

x <- c("a", "b", "c")
for (val in x) {
val <- read.csv(val.csv)
}


ここでの問題は、val.csv の val が x として認識されていないことである。つまり、print 関数は val を解釈できるが、read.csv 関数の中に入っていると認識されないのである。

同様に、val.csv を val として、ワーキングディレクトリに a, b, c というファイルを用意すると、一応 csv ファイルとして読み込まれるが、val というオブジェクトが生成する。つまり、オブジェクト名としても val に x が代入されていないということ。


この場合は、文字列を結合する paste0 関数 を使う。よく似た関数に paste があり、paste はスペースを入れて、paste0 はスペースを入れずに、文字列を結合する。

x <- c("a", "b", "c")
for (val in x) {
val <- read.csv(paste0(val, ".csv"))
}


こうすると、read.csv(paste0(val, ".csv")) の部分は OK になる。a.csv, b.csv, c.csv が順番に読み込まれる。

しかし、オブジェクト名の val の部分がまだ val として認識されている。つまり、val というオブジェクトにデータが上書きされてしまう。


これを解決するために assign 関数 を使う (3)。assign は assign(オブジェクト名, 代入したい値) のように使う。つまり次のようになる。

x <- c("a", "b", "c")
for (val in x) {
csv <- read.csv(paste0(val, ".csv"))
assign(val, csv)
}


文字列ベクターを使ってデータフレームを読み込む: get() 関数

a, b, c というデータフレームがあって、それを順に読み込みたい場合。以下のコードで、data_temp に a, b, c が代入される。paste0() なしでも大丈夫かもしれない。

x <- c("a", "b", "c")
for (val in x) {
data_temp <- get(paste0(val))
}



広告

References

  1. R for loop. Link: Last access 2021/03/08.
  2. 繰返処理. Link: Last access 2021/03/08.
  3. Rでloopを使って動的な名前の変数を作成したい. Link: Last access 2022/07/08.
  4. for文の応用的な使い方. Link: Last access 2022/11/26.

コメント欄

サーバー移転のため、コメント欄は一時閉鎖中です。サイドバーから「管理人への質問」へどうぞ。