R入門-その2
昨日はひつじ数えて眠ったので、その続きからやっていきます。
Collatzの問題
1937年にドイツの数学者Collatz(コラッツ)が,「ある数が偶数なら2で割り,奇数なら3倍して1を足す。これを繰り返すとすべての数は1になるだろう」と予想しましたが,だれもそれを証明することができていません。
という問題ですが、これはプログラムで解くとすぐにできそうです。ざっくりと言葉で書くと、whileかforを使って、ループで処理を行います。その処理はifを使って条件分岐させ、2で割った時のあまりが0の場合には2で割り、それ以外(奇数)の場合には3倍して1を足します。
collatz = function(n){ cat(n) while(n>1){ if(n %% 2 == 0){ n = n / 2 } else{ n = n * 3 +1 } cat("→",n) } }
とこのようにかけます。whileとかifとかさらっと出てきたけど、特に注意することはないと思う。n %% 2はnを2で割った時のあまりですから、この余りが0ならばnは偶数になります。n %% 2 == 0の論理値がtrueならば、ifの処理が実行されます。引数を渡して実行してやると、うまくいくのがわかります。
> collatz(11) 11→ 34→ 17→ 52→ 26→ 13→ 40→ 20→ 10→ 5→ 16→ 8→ 4→ 2→ 1
データを読み込む
やっとデータを扱えます。警察庁のHPから公表されている統計データをダウンロードしてきます。交通事故統計(平成25年11月末)を使ってみます。変数xに年間合計を代入します。
x = scan(pipe("pbpaste"))
enterを押さない状態でexcelの取得したい範囲をコピーした状態でターミナルに戻りenterを押します。
> x = scan(pipe("pbpaste")) Read 16 items > x [1] 9214 9012 9073 8757 8396 7768 7425 6927 6403 5782 5197 4968 4922 4663 4411 [16] 3883
Read 16 itemsと16の要素を読み込んでいます。xを表示してみると正しく読み込めていました。同様に変数tに年代を取り込んでみても良いのですが、ひとつずつならんだものならば、
x = 1998:2013
の方が簡単です。今思ったのですが、元号は平成、昭和などかわることがありますから、西暦の方が分析するときには気にせずできて楽そうです。
plot(t, x, type="o")
plotはRで作図する時に頻繁に使われる関数です。機能も多く、折れ線グラフや散布図なども描くことができます。引数typeによって形式を選ぶことができます。
引数 | 機能 |
---|---|
type="p" | 点プロット(デフォルト) |
type="l" | 線プロット(折れ線グラフ) |
type="b" | 点と線のプロット |
type="c" | "b" において点を描かないプロット |
type="o" | 点プロットと線プロットの重ね書き |
type="h" | 各点から x 軸までの垂線プロット |
type="s" | 左側の値にもとづいて階段状に結ぶ |
type="S" | 右側の値にもとづいて階段状に結ぶ |
type="n" | 軸だけ描いてプロットしない(続けて低水準関数でプロットする場合) |
ラベルをつけて描くために
plot(t, x, type="o", pch=16, xlab="年", ylab="死者数(人)")
としてやると年などのラベルがつくはずが
と画像のように文字化けしています。文字化けさせないためにはフォントを指定してあげるとokだそうです。
par(family="HiraMaruProN-W4")
で文字化けは解消されます。font-familyは適当。ついでに図のタイトルをつけて描画すると
plot(t, x, type="o", pch=16, xlab="年", ylab="死者数(人)",main="交通事故死者数の推移")
うまくいきました。
データフレーム
> 身長 = c(168.5, 172.8, 159.0) > 体重 = c(69.5, 75.0, 56.5)
このようなデータがふたつあったときにデータフレームが非常に有効です。そもそもデータフレームはdata.frame クラスを持つ要素であり、異なるデータ型でも複数の要素をひとつの変数として持つことができます。2次元配列のように見え、行と列は必ずラベルをもつという特徴があります。ラベルがあることによりラベルでの操作を可能にしてくれます。例えば、
> 身長 = c(168.5, 172.8, 159.0) > 体重 = c(69.5, 75.0, 56.5)
というようなデータがあった時に、データフレームにまとめると効率的に扱えることがあります。
> X = data.frame(身長, 体重) > X 身長 体重 1 168.5 69.5 2 172.8 75.0 3 159.0 56.5
行の名前が1,2,3となっていますが、これを変更することもできます。row.namesで引数にデータフレームをとれば
> row.names(X)=c("太郎", "次郎", "花子") > X 身長 体重 太郎 168.5 69.5 次郎 172.8 75.0 花子 159.0 56.5
ここまでで一旦切って、次につなげます。
*参照:Rの初歩