投稿

2月, 2015の投稿を表示しています

Rでシミュレーション(正規分布に従う確率変数の和は正規分布に従う)

イメージ
「シミュレーション」なんていうと、難しそうな気がしてしまいますが、今回のは「乱数を使って試してみる」くらいのものです。 例えば、10万人の学生がいます。彼らの身長は正規分布に従っているとします。また、彼らのテストの点数も正規分布に従っているとします。 このとき、「身長+点数」という確率変数を考えると、これは正規分布に従っているでしょうか? これを数学的に証明するのではなく、乱数を使ったシミュレーションで、「身長+点数もきっと正規分布に従うんじゃないか」ということを確認しようというわけです。 まずは↓こんな感じでデータを生成しておきます。 # 身長 # 平均 :170cm # 標準偏差: 5cm heights <- rnorm ( 100000 , 170 , 5 )   # 点数 # 平均 : 50 # 標準偏差: 10 scores <- rnorm ( 100000 , 50 , 10 ) ↓身長と点数のそれぞれでヒストグラムを描いてみましょう。 brk <- seq ( 0 , 300 , 1 ) # ヒストグラムの刻み hist ( heights , breaks=brk , ylim= c ( 0 , 10000 ) ) 正規分布に従う「身長」のヒストグラム hist ( scores , breaks=brk , ylim= c ( 0 , 10000 ) ) 正規分布に従う「点数」のヒストグラム ↓両者を足してヒストグラムを描いてみると、 hist ( heights + scores , breaks=brk , ylim= c ( 0 , 10000 ) ) 「身長+点数」は正規分布に従うか? どうやら正規分布になっているっぽいです。 では、どんな正規分布(平均、分散)になっているのでしょうか。 > mean(heights) [1] 169.9721 > mean(scores) [1] 50.04487 > mean(heights + scores) [1] 220.017 「身長の平均」

Rでヒストグラムの上に度数の数字を表示する

イメージ
例えば、↓こんなヒストグラムがあったとしましょう。 普通にhist関数で描画したもの。 30~40、40~50の階級の度数はゼロ? ぱっと見、30~40と40~50の階級の度数はゼロなんだな、と見えちゃいますが、そうではありません。 ↓実はこんなスクリプトでサンプルデータを作ったので、 d <- c ( rep ( 5 , 10000 ) , rep ( 15 , 1000 ) , rep ( 25 , 100 ) , rep ( 35 , 10 ) , rep ( 45 , 1 ) ) hist ( d , breaks= seq ( 0 , 50 , 10 ) ) 30~40の階級には10の度数、40~50の階級には1の度数があるんですよね。でも、0~10の階級の10000の度数が多すぎるために、つぶれて見えなくなってしまったという状態。 こんなときは、棒グラフの上のところに度数の数字を表示させてやれば、少ない度数の階級についても確認ができます。 hist ( d , breaks= seq ( 0 , 50 , 10 ) , labels =T ) hist関数にlabels=Tオプションを指定し、度数を表示させたもの labels=T オプションを指定するだけなので、とても簡単です。 が、実は私、このオプションの存在を知らず、いままで↓下記のような方法で書いてました。(このへんの紆余曲折が、この記事を書こうと思い立った理由だったりします) h <- hist ( d , breaks= seq ( 0 , 50 , 10 ) ) text ( h$mids , h$counts , h$counts ) hist関数の戻り値を、text関数を使ってプロット hist関数の戻り値(変数hに格納してます)には、階級値や度数の情報が入っているので、それをtext関数で表示させるというもの。 文字と棒グラフのborderが重なって見にくいと思う場合は、↓こうやればOK。 h <- hist ( d , breaks= seq ( 0 , 50 , 10 ) , ylim= c ( 0 , 10100 ) )

Rのduplicated関数を使ってデータフレームの重複チェック(改)

duplicated関数の引数にデータフレームを指定すると、すべての項目(列)を組み合わせた上での重複チェックができますよ、という話を以前書きました↓ Rのデータフレームで複数項目を組み合わせた重複のチェック - Rプログラミングの小ネタ また、上記の記事では、すべてではなく一部の項目のみを組み合わせ対象にしたい場合は、interaction関数を使って新たにチェック用の列を作ってはどう?、というやり方も紹介しました。 が、duplicated関数がすべての列を対象にする動きなら、対象にしたい列だけで構成された新たなデータフレームを生成して、duplicated関数に渡した方がシンプルではないか、ということに気づきました。 例えば↓こんなデータがあって、 > d    名字 名前 年齢 1  伊東 二郎   52 2  佐藤 五郎   52 3  遠藤 太郎   53 4  後藤 太郎   53 5  近藤 五郎   28 6  遠藤 二郎   33 7  後藤 四郎   52 8  須藤 次郎   28 9  伊東 二郎   35 10 遠藤 太郎   23 11 遠藤 史郎   38 12 工藤 吾郎   53 13 須藤 太郎   22 14 武藤 二郎   28 15 工藤 吾郎   53 16 伊東 二郎   22 17 遠藤 四郎   33 18 後藤 史郎   38 19 加藤 一郎   28 20 加藤 二郎   22 名字と名前だけを対象として重複チェックをしたい場合は、 > sum(duplicated( data.frame(d$名字, d$名前) )) [1] 4 とか、 > d[duplicated( data.frame(d$名字, d$名前) ), ]    名字 名前 年齢 9  伊東 二郎   35 10 遠藤 太郎   23 15 工藤 吾郎   53 16 伊東 二郎   22 という感じですね。interaction関数を使うよりも、シンプルだと思います。 が、duplicated関数の仕様って、2つ目以降が現れたときにTRUEとなる、というものなんですよね。つまり、伊東二郎さんが3回現れる場合、1つ目はFALSE、2つ目はTRUE、3つ目はTRUEという結果になります。なので、sum関数で数えた場合の結果は

Rで複数のヒストグラムを比較する方法あれこれ

イメージ
2つ以上のヒストグラムを1つのグラフ上に描画して、比較したいようなときってありますよね。 例えば、集団aのテストの点数と、集団bのテストの点数が、それぞれ1000件ずつあるとしましょう。 # サンプルデータを作っておく a <- rnorm ( 1000 , 40 , 10 ) b <- rnorm ( 1000 , 60 , 10 ) borderオプションを使って、ヒストグラムの線に色をつけるってのは1つのやり方ですね↓ # 線に色をつける hist ( a , breaks= seq ( 0 , 100 , 5 ) , border= "red" , xlim= c ( 0 , 100 ) , main= "" , xlab= "" ) hist ( b , breaks= seq ( 0 , 100 , 5 ) , border= "blue" , add=T ) borderオプションでヒストグラムの線に色をつける なんとなく見えてはいるのですが、重なった縦線は後から描画した方で上書きされてしまい、そのへんがちょっと見にくいですね。 colオプションで面に色をつけることもできますが・・・ # 色で塗りつぶす hist ( a , breaks= seq ( 0 , 100 , 5 ) , col = "red" , xlim= c ( 0 , 100 ) , main= "" , xlab= "" ) hist ( b , breaks= seq ( 0 , 100 , 5 ) , col = "blue" , add=T ) colオプションでヒストグラムを塗りつぶす ↑普通の色で塗っちゃうと重なったところが見えなくなってしまいます。 そういうときは、透過色を使えばいいです↓ # 透過色を使う hist ( a , breaks= seq ( 0 , 100 , 5 ) , col = "#FF00007F" , x

Rのinteraction関数で重複チェックするときは、drop=Tを指定する

前回の記事で、データフレームの重複をチェックするときに、interaction関数を使うという方法を紹介しました↓ Rのデータフレームで複数項目を組み合わせた重複のチェック 例えば、こんな↓データだったら、 > d    名字 名前 年齢 出身         職業 1  佐藤 一郎   20 埼玉   アルバイト 2  武藤 二郎   22 大阪         学生 3  加藤 三郎   25 愛知       会社員 4  伊東 四郎   77 東京 コメディアン 5  近藤 五郎   32 千葉         無職 6  後藤 太郎   33 兵庫       公務員 7  工藤 次郎   35 福岡     専業主夫 8  須藤 三朗   38 静岡       自営業 9  遠藤 史郎   52 茨城     会社役員 10 斉藤 吾郎   83 広島     定年退職 ↓こんなふうにして、 > intr <- interaction(d$名字, d$名前, d$年齢, d$出身, d$職業, drop=T) > sum(duplicated(intr)) [1] 0 TRUEの数がゼロだから重複なしだな、みたいな。 で、前回の記事でも上記のサンプルでも、interaction関数にさりげなく、drop=Tオプションを指定していますが、これが結構重要です。何も指定していないと、デフォルトはdrop=Fです。 両者で実行結果を比較してみましょう。 ↓まずはdrop=Tで、 > interaction(d$名字, d$名前, d$年齢, d$出身, d$職業, drop=T )  [1] 佐藤.一郎.20.埼玉.アルバイト   武藤.二郎.22.大阪.学生         [3] 加藤.三郎.25.愛知.会社員       伊東.四郎.77.東京.コメディアン  [5] 近藤.五郎.32.千葉.無職         後藤.太郎.33.兵庫.公務員       [7] 工藤.次郎.35.福岡.専業主夫     須藤.三朗.38.静岡.自営業       [9] 遠藤.史郎.52.茨城.会社役員     斉藤.吾郎.83.広島.定年退職    10 Levels : 佐藤.一郎.20

Rのデータフレームで複数項目を組み合わせた重複のチェック

例えば、↓こんな感じのデータフレームがあったとします。 > d    名字 名前 年齢 1  伊東 二郎   52 2  佐藤 五郎   52 3  遠藤 太郎   53 4  後藤 太郎   53 5  近藤 五郎   28 6  遠藤 二郎   33 7  後藤 四郎   52 8  須藤 次郎   28 9  伊東 二郎   35 10 遠藤 太郎   23 11 遠藤 史郎   38 12 工藤 吾郎   53 13 須藤 太郎   22 14 武藤 二郎   28 15 工藤 吾郎   53 16 伊東 二郎   22 17 遠藤 四郎   33 18 後藤 史郎   38 19 加藤 一郎   28 20 加藤 二郎   22 仮に、名字と名前と年齢の一致によって個人を特定できるとし、このデータに重複がないかチェックをしたいということにします。 全項目を加味した重複チェックを行うのは実は簡単で、duplicated関数の引数にデータフレームを渡してやればOKです。TRUEがあれば重複があるということになります↓ > duplicated(d)   [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE [11] FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE 重複の有無を一目で確認したいときは、sum関数を使います。1以上なら重複ありということになります↓ > sum(duplicated(d)) [1] 1 重複したのがどの行だったのか見たい場合は、↓こんな感じでしょうか。 > d[duplicated(d), ]    名字 名前 年齢 15 工藤 吾郎   53 データフレームの全項目ではなく、一部の項目の組み合わせでの重複チェックをしたい場合は、interaction関数を使ってそれらの項目を組み合わせた因子を作って、それをIDのように扱うという方法もあります。 年齢の項目は無視して、同姓同名を見つけたいような場合は、名字と名前の2つを組み合わせた因子の項目を作ります。 > d$