未来はキミドリイロ

サイコメトリックアイドルを目指す心理学徒の勉強部屋です。勉強・趣味などについて書いています。

【R】行列における複数行の繰り返し

備忘をかねて,Rでの行列操作,複数行の繰り返しについてまとめておきます。
例えば,手元のデータが次のようになっていることを考えます。

y1<-matrix(c(1,1,1,2,2,2,3,3,3),3,3,byrow=TRUE)
print(y1)

[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
[3,] 7 8 9

このとき,この行列を行方向に3回反復した9行3列の行列を作りたい,という問題意識があるとしましょう。
最終目標は次のような行列になるわけです。

[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
[3,] 7 8 9
[4,] 1 2 3
[5,] 4 5 6
[6,] 7 8 9
[7,] 1 2 3
[8,] 4 5 6
[9,] 7 8 9

エクセルなんかで3×3の行列を下にコピーペーストすれば簡単なんだと思いますが,これを100回繰り返す300行3列のデータを作りたい場合や,手元のデータが1000行1500列と大きくかつそれを100回繰り返すデータなんかを作る場合を考えると,ただのコピペでも随分と労力がかかってしまいますよね。
これを,Rで簡単に実行しよう,というのが本記事の目的です。

最初に思いついた方法――rep関数の利用(失敗)

最初に思いついたのは,3回繰り返して下にくっつければいいんだからrep関数でよさそうじゃない,というものでした。
実際に書いてみると,次のようになります。

y1<-matrix(1:9,3,3,byrow=TRUE)
Y1<-matrix(rep(y1,3),9,3,byrow=TRUE)
print(Y1)

[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
[4,] 1 4 7
[5,] 2 5 8
[6,] 3 6 9
[7,] 1 4 7
[8,] 2 5 8
[9,] 3 6 9

Y2<-matrix(rep(y1,3),9,3)
print(Y2)

[,1] [,2] [,3]
[1,] 1 1 1
[2,] 4 4 4
[3,] 7 7 7
[4,] 2 2 2
[5,] 5 5 5
[6,] 8 8 8
[7,] 3 3 3
[8,] 6 6 6
[9,] 9 9 9

はい,どう行列を読み込んでも失敗ですありがとうございました。

終わった後に思いついた方法――汗と涙と気合いのrbind

人力コピペばりに,rbindを何行も根性で書いて縦積みしていく方法です。
想像するだけでも面倒なので,パスということでお願いいたします。

今回提案する方法――forループを利用した方法


これが今回備忘録に残しておきたい楽をする方法,forループを利用した方法です。
必要なものは手元のデータの行数&列数と繰り返したい回数だけです。

y1<-matrix(1:9,3,3,byrow=TRUE)

#最終的に作りたい行列の行数
rowY<-9

#最終的に作りたい行列の列数
colY<-3

#要素を入れるための入れ物を作る
Y3<-matrix(0,rowY,colY)

#行数の指定を工夫することで,1行目から3行分,4行目から3行分……と繰り返させる
for(i in 0:2){
Y3[c(1:3)+3*i,]<-y1
}
print(Y3)

[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
[3,] 7 8 9
[4,] 1 2 3
[5,] 4 5 6
[6,] 7 8 9
[7,] 1 2 3
[8,] 4 5 6
[9,] 7 8 9

はい,成功です。
もっとスマートなやり方があるのかもしれませんが,今回は行数指定を工夫することでデータを縦にN回積み上げたい,という問題に対処してみました。
いじる部分を行から列に変えれば,列方向にN回反復したい場合もほぼ同じコードで解決できますね。
すくなくともエクセルでN回コピペし続けるよりは(精神的に)楽になったんじゃないかと思います。

こういった対処は基本的にうんうん楽できないか悩んで見つけているのですが,きちんとRについて勉強すれば当意即妙,ぱぱっとクリアできるものなのでしょうか。
その意味で,最近翻訳された『R言語徹底解説』が気になるところです。

R言語徹底解説

R言語徹底解説