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によって形式を選ぶことができます。

plotの形式
引数機能
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の初歩