統計解析フリーソフト R 入門

統計解析フリーソフト R 入門
R によるシミュレーション入門
R Commander 国際化!
R Commander 国際化!
„ GUI メニューから R の機能を使うことが
出来るパッケージ
R Commander
のセットアップが楽になりました
„ パッケージをインストールするだけで
メニューが日本語化!
„ CRAN からの「Rcmdr」と「rgl」の2つの
パッケージをインストールするだけ!
„ R Commander の詳しい使い方は荒木先生
の本をご参照下さい
第5回のメニュー
„ R の乱数生成関数
‰乱数生成関数の一覧
‰乱数生成の例
‰乱数データを使った検定の例
„ 繰り返し文(for)と条件分岐(if)
‰繰り返し文(for)
‰条件分岐(if)
„ R によるシミュレーション
本日の話の流れ
„ 例数設計を題材とし,SAS と対比をさせなが
ら,R によるシミュレーション方法を紹介
„ 2群の平均値の差を検出することを考える
‰第1群の標本:平均 0,標準偏差1.5の正規分布
‰第2群の標本:平均 1,標準偏差1.5の正規分布
‰解析は2標本 t 検定(α = 0.05)
‰検出力90%を確保するために必要な症例数を算出
する
„ まずは乱数の生成方法を紹介
„ 次にシミュレーションの方法を紹介
第5回のメニュー
„ R の乱数生成関数
‰乱数生成関数の一覧
‰乱数生成の例
‰乱数データを使った検定の例
„ 繰り返し文(for)と条件分岐(if)
‰繰り返し文(for)
‰条件分岐(if)
„ R によるシミュレーション
R の乱数生成関数
„ R には多数の乱数生成関数が用意されている
‰SAS の rand() 関数に匹敵する位の種類
‰SAS と同様,seed を指定することが出来る
‰SAS の rand() 関数と同じ乱数生成アルゴリズム
を搭載(メルセンヌ・ツイスター法)
R の乱数生成関数
„ 乱数生成速度が速い
‰メルセンヌ・ツイスター法で生成
‰結果をベクトル(1次元)として持つ
„ 基本的な乱数生成関数
‰runif(10) :(0,1)区間の一様乱数を10個生成
‰rnorm(20) :標準正規乱数を20個生成
‰rexp(30, 5):rate 5(平均1/5)の指数乱数を
30個生成
SASのrand()で生成可能な乱数の分布
分布名
rand()の第1引数
V8.2以前の既存の関数
Rの関数
ベルヌーイ分布
Bernoulli
(rbinom()で生成可)
ベータ分布
Beta
rbeta()
二項分布
Binomial
ranbin()
rbinom()
コーシー分布
Cauchy
rancau()
rcauchy()
χ2分布
Chisquare
アーラン分布
Erlang
指数分布
Exponential
F分布
F
ガンマ分布
Gamma
幾何分布
Geometric
rgeom()
超幾何分布
Hypergeometric
rhyper()
対数正規分布
Lognormal
rlnorm()
負の二項分布
Negbinomial
rnbinom()
正規分布
Normal
rannor(), normal()
rnorm()
ポアソン分布
Poisson
ranpoi()
rpois()
t分布
T
テーブル(多項)分布
Table
rantbl()
三角分布
Triangle
rantri()
一様分布
Uniform
ranuni(), uniform()
ワイブル分布
Weibull
rchisq()
ranexp()
rexp()
rf()
rangam()
rgamma()
rt()
rmultinom()
runif()
rweibull()
【例1】2組の正規乱数を生成
„ 2群(各群50例)の正規乱数を1組生成
SAS による乱数生成
data dummy1;
array mu(2) mu1-mu2;
mu1 = 0.0 ; mu2 = 1.0 ;
sd = 1.5 ; n
= 50 ;
do group=1 to 2;
do j=1 to n ;
y=normal(7)*sd+mu(group);
output;
end;
end;
run;
R による乱数生成
>
>
>
>
>
>
>
>
# 乱数のシード(初期値)を設定
set.seed(7)
# 平均0,標準偏差1.5の正規乱数
y1 <- rnorm(n=50, m=0.0, sd=1.5)
# 平均1,標準偏差1.5の正規乱数
y2 <- rnorm(n=50, m=1.0, sd=1.5)
SASのデータセット
mu1
mu2
sd
n
group
j
y
0
1
1.5
50
1
1
0.59195
0
1
1.5
50
1
2
0.40391
0
1
1.5
50
1
3
0.41213
0
1
1.5
50
1
4
-0.17594
・・・
・・・
・・・
・・・
・・・
・・・
・・・
0
1
1.5
50
1
49
-0.04794
0
1
1.5
50
1
50
0.70376
0
1
1.5
50
2
1
1.95777
0
1
1.5
50
2
2
3.04958
0
1
1.5
50
2
3
1.54307
0
1
1.5
50
2
4
-0.23373
・・・
・・・
・・・
・・・
・・・
・・・
・・・
0
1
1.5
50
2
49
1.74497
0
1
1.5
50
2
50
0.69841
R のデータ(ベクトル)
> y1
[1]
[6]
[11]
[16]
[21]
[26]
[31]
[36]
[41]
[46]
3.430870742
-1.420919918
0.535479345
0.701520767
1.259625539
0.276289157
-1.306276534
-0.843188814
1.827825802
-0.602289920
> y2
[1]
[6]
[11]
[16]
[21]
[26]
[31]
[36]
[41]
[46]
0.60588648
1.72155407
1.11455721
2.66387468
1.64894074
-0.98875887
1.51387803
0.53244720
3.45369165
0.13953139
-1.795157523
1.122209010
4.075127675
-1.340701085
1.058012746
1.128419844
1.078065830
1.496270167
-1.048975618
2.025776371
0.98849784
-1.35180237
1.23873292
2.15373129
-0.38390258
-0.33355509
1.00637235
0.48089711
0.03186479
2.67698981
-1.041438766
-0.175432839
3.422177889
-0.460992449
1.958947081
0.887617579
0.165979317
-1.657695088
-0.428149127
0.886785041
-0.618439427
0.228986439
0.486030810
-0.007233633
-2.081994325
-1.474578894
-0.117700152
-0.213431746
-1.967329009
0.150788183
-1.456010012
3.284967161
2.844100600
1.482246224
1.909375296
-0.414095933
-0.630735689
0.472492357
-0.586518647
1.396607993
1.55072951 3.56074382 2.08561039
1.47737543 1.24898718 -0.34986144
1.81551128 2.05721103 1.47845371
2.73021051 2.89102525 2.05093526
0.07662369 -0.29998953 -1.45927563
0.16359650 0.90639654 4.63403947
1.04382976 0.40986486 -0.18905684
0.54308862 -1.67884023 1.88091201
1.92848825 1.35459040 2.26975135
-1.31000170 0.34281415 0.77399054
SASに比べて R は・・・
„ 乱数を生成するのが楽
‰ 乱数を生成するプログラムが簡単
‰ 生成速度が速い(メルセンヌ・ツイスター法)
„ 自宅のマシン(Pen4:2.6GHz,512MB RAM)で乱数を10万個生成
【SAS】0.15秒∼0.17秒
【 R 】0.03秒∼0.05秒
‰ SAS と同様,seed を指定することができる
„ 生成されたデータに冗長性が無い
‰ SAS はデータセット(余分な情報が・・・)
‰ R はベクトル
【例2】2標本 t 検定
SAS による2標本 t 検定
ods listing close ;
ods output ttests=out1
(where=(method="Pooled")) ;
proc ttest data=dummy1 ;
class group ;
var
y ;
run ;
ods output close ;
ods listing ;
R による2標本 t 検定
> out1 <- t.test(y1, y2,
var.equal=T)
> out1
Two Sample t-test
data: y1 and y2
t = -2.845, df = 98, p-value = 0.005408
alternative hypothesis:
true difference in means is not equal to 0
95 percent confidence interval:
-1.4219012 -0.2533483
sample estimates:
mean of x
mean of y
-0.005048812 0.832575895
【例2】2標本 t 検定
„SAS のアウトプット
Variable
y
Method
Pooled
Variances
tValue
DF
Equal
-2.20599
Probt
98
0.029721
„R のアウトプット
> names(out1)
[1] "statistic"
[6] "null.value"
> out1$p.value
[1] 0.005408422
"parameter"
"p.value"
"alternative" "method"
# p 値
"conf.int"
"data.name"
"estimate"
【参考】回帰分析
„ R でやると面倒な例
SAS による回帰分析
R による回帰分析
ods listing close ;
> dummy1 <- data.frame(
group=c(rep(1,50),
ods output ModelANOVA=out2
(where=(HypothesisType=3));
rep(2,50)),
y=c(y1,y2) )
proc glm data=dummy1 ;
> out2 <- summary(
class group ;
lm(y
group, data=dummy1) )
model y = group ;
quit ;
ods output close ;
ods listing ;
【参考】回帰分析
„SAS のアウトプット
Dependent HypothesisType Source DF
y
3 group
SS
MS
1 10.3007 10.3007
FValue
ProbF
4.8663 0.0297
„R のアウトプット
> out2$coefficients[ ,"Pr(>│t│)"]
(Intercept)
group
0.073337026 0.005408422
# 命令は names(out2) で調べる
> out2$coefficients[2,"Pr(>│t│)"]
[1] 0.005408422
# p 値
第5回のメニュー
„ R の乱数生成関数
‰乱数生成関数の一覧
‰乱数生成の例
‰乱数データを使った検定の例
„ 繰り返し文(for)と条件分岐(if)
‰繰り返し文(for)
‰条件分岐(if)
„ R によるシミュレーション
【SAS】検出力のシミュレーション
„ 2群(各群50例)の正規乱数を1000組生成し,
各組で t 検定を行い,p 値を取り出す
data dummy2;
array mu(2) mu1-mu2;
mu1 = 0.0 ; mu2 = 1.0 ;
do i=1 to 1000 ;
do group=1 to 2;
do j=1 to 50 ;
y=normal(7)*1.5+mu(group) ;
output;
end;
end;
end;
run;
proc ttest data=dummy2 ;
by
i ;
class group ;
var y ;
run ;
ods output close ;
ods listing ;
data power2;
set out2;
if ( Probt < 0.05 ) then flag = 1;
else
flag = 0;
run;
ods listing close ;
ods output
proc freq data=power2;
ttests=out2(where=(method="Pooled")) ;
tables flag / norow nopercent ;
run;
【R】シミュレーションの準備(1)
„ for:同じような作業を繰り返す
‰for (i in 1:1000) { 1000 回繰り返す内容 }
> power <- 0
> for (i in 1:1000) {
+
power <- power + 1
+ }
> power
[1] 1000
# カウンタ power を初期化( 0 を代入)
# 同じような作業を 1000 回繰り返す
# カウンタ power を 1 増やす
# カウンタの中身
【R】シミュレーションの準備(2)
„ if:条件に合致していたら処理を行う
‰if (条件) { 条件に合致していたら処理を行う }
> power <- 0
#
> for (i in 1:1000) {
#
+
if (i%%2 == 0) {
#
+
power <- power + 1 #
+
}
+ }
> power
#
[1] 500
カウンタ power を初期化( 0 を代入)
同じような作業を 1000 回繰り返す
i が 2 の倍数だったら・・・
カウンタ power を 1 増やす
カウンタの中身
【R】検出力のシミュレーション
„ 2群(各群50例)の正規乱数を1000組生成し,
各組で t 検定を行い,p 値を取り出す
>
>
>
+
+
+
+
+
+
+
>
乱数のシードを設定
カウンタ <- 0
for (i in 1:1000) {
y1 <- 平均 0 ,標準偏差 1.5 の正規乱数を 50 個生成
y2 <- 平均 1 ,標準偏差 1.5 の正規乱数を 50 個生成
out <- y1 と y2 の 2 標本 t 検定(等分散性を仮定)
if (結果 out の p 値が 0.05 より小さければ) {
カウンタを 1 増やす
}
}
power/1000 で有意になった割合を算出
【R】検出力のシミュレーション
„ 2群(各群50例)の正規乱数を1000組生成し,
各組で t 検定を行い,p 値を取り出す
>
>
>
+
+
+
+
+
+
+
>
set.seed(7)
power <- 0
for (i in 1:1000) {
y1 <- rnorm(n=50, mean=0.0, sd=1.5)
y2 <- rnorm(n=50, mean=1.0, sd=1.5)
out <- t.test(y1, y2, var.equal=T)
if (out$p.value < 0.05) {
power <- power + 1
}
}
power/1000
検出力のシミュレーション結果
„SAS のアウトプット(実行時間:約18秒)
FREQ プロシジャ
累積
flag
度数
度数
---------------------------0
75
75
1
925
1000
„R のアウトプット(実行時間:約1~2秒)
> power/1000
[1] 0.902
繰り返し文(do ⇔ for)
SAS
R
> set.seed(7)
data dummy2;
> power <- 0
array mu(2) mu1-mu2;
> for (i in 1:1000) {
mu1 = 0.0 ; mu2 = 1.0 ;
+ y1 <- rnorm(n=50, mean=0.0, sd=1.5)
do i=1 to 1000 ;
+ y2 <- rnorm(n=50, mean=1.0, sd=1.5)
do group=1 to 2;
+ out <- t.test(y1, y2, var.equal=T)
do j=1 to 50 ;
y=normal(7)*1.5+mu(group); + if (out$p.value < 0.05) {
+
power <- power + 1
output;
+ }
end;
+ }
end;
> power/1000
end;
run;
1. do が for になっている
2. セミコロンは要らない
3. do~end ではなく { と } で
括る
条件分岐(if)
SAS
R
data power2;
set out2;
if (Probt<0.05) then flag=1;
else
flag=0;
run;
>
>
>
+
+
+
+
+
+
+
>
set.seed(7)
power <- 0
for (i in 1:1000) {
y1 <- rnorm(n=50, mean=0.0, sd=1.5)
y2 <- rnorm(n=50, mean=1.0, sd=1.5)
out <- t.test(y1, y2, var.equal=T)
if (out$p.value < 0.05) {
power <- power + 1
}
}
power/1000
1. then は要らない
2. セミコロンは要らない
3. do~end ではなく { と } で
括る
【R】検出力のシミュレーション
„ 2群(各群50例)の正規乱数を1000組生成し,
各組で t 検定を行い,p 値を取り出す
>
>
>
+
+
+
+
+
+
+
>
set.seed(7)
power <- 0
for (i in 1:1000) {
y1 <- rnorm(n=50, mean=0.0, sd=1.5)
y2 <- rnorm(n=50, mean=1.0, sd=1.5)
out <- t.test(y1, y2, var.equal=T)
if (out$p.value < 0.05) {
power <- power + 1
}
}
power/1000
#
#
#
#
#
#
#
カウンタ power を 0 に
繰り返し文開始
第 1 群のデータを生成
第 2 群のデータを生成
t 検定 → 結果を out に格納
結果が有意ならば
カウンタに 1 加算
# 結果の表示
第5回のメニュー
„ R の乱数生成関数
‰乱数生成関数の一覧
‰乱数生成の例
‰乱数データを使った検定の例
„ 繰り返し文(for)と条件分岐(if)
‰繰り返し文(for)
‰条件分岐(if)
„ R によるシミュレーション
R によるシミュレーション
【応用1】先程のプログラムを関数化する
> f <- function(n) {
+ set.seed(7)
+ power <- 0
+ for (i in 1:1000) {
+
y1 <- rnorm(n, mean=0.0, sd=1.5)
+
y2 <- rnorm(n, mean=1.0, sd=1.5)
+
out <- t.test(y1, y2, var.equal=T)
+
if (out$p.value < 0.05) {
+
power <- power + 1
+
}
+ }
+ power/10
# パーセント表示する
+ }
> f(30)
# n=30 のときの検出力
[1] 73.4
R によるシミュレーション
【応用2】検出力の値をプロットする
85
86
87
88
y
89
90
91
92
> y <- c(f(40), f(41), f(42), f(43), f(44), f(45),
f(46), f(47), f(48), f(49), f(50), f(51))
> plot(40:51, y, type="b", col=ifelse(y>=90, "red", "blue"))
> abline(h=90)
40
42
44
46
40:51
48
50
R でシミュレーションを行う利点
„ 計算が速い
„ 繰り返し回数が多くてもフリーズしにくい
„ 記述が簡単(Rに慣れれば・・・)
‰ SASのデータステップは,記述は簡単だが繰り返し
回数に制約がある(高々数千回)
‰ SASの IML は,繰り返し回数の制約が緩いが,
記述が難解
(可読性に難,統計量を逐一求める必要あり)
„ 今回は t 検定を例に出したが,同様の方法でさ
まざまな検定,分析を主解析とした場合の例数
設計が出来る
参考
„ SASに power プロシジャや glmpower プロシジャが
あるように,R にも以下の関数が用意されている
‰ power.t.test():t 検定の例数設計を行う
‰ power.anova.test():一元配置分散分析の例数
設計を行う
‰ power.prop.test():比率の検定の例数設計を行う
> power.t.test(n=50, delta=1, sd = 1.5, sig=0.05)
Two-sample t test power calculation
n = 50
delta = 1
sd = 1.5
sig.level = 0.05
power = 0.9099633
alternative = two.sided
NOTE: n is number in *each* group
本日のまとめ
„ R の乱数生成関数
‰乱数生成関数の一覧
‰乱数生成の例
‰乱数データを使った検定の例
„ 繰り返し文(for)と条件分岐(if)
‰繰り返し文(for)
‰条件分岐(if)
„ R によるシミュレーション
参考文献・引用文献
„ SAS Technical News Winter 2005
⇒「rand関数で生成可能な乱数の分布」で引用
„ 伏見 正則 「乱数」 東京大学出版会
„ 脇本 和昌 「乱数の知識」
http://www.sci.kagoshima-u.ac.jp/ ebsa/wakimoto01/index.html
„ 良い乱数・悪い乱数
http://www001.upp.so-net.ne.jp/isaku/rand.html
„ 間瀬 他「工学のためのデータサイエンス入門」
(数理工学社)
統計解析フリーソフト R 入門
終