プログラムの正しさのチェック
の編集
http://www.okadajp.org/RWiki/?%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E3%81%AE%E6%AD%A3%E3%81%97%E3%81%95%E3%81%AE%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF
[
トップ
] [
編集
|
差分
|
バックアップ
|
添付
|
リロード
] [
新規
|
一覧
|
検索
|
最終更新
|
ヘルプ
]
-- 雛形とするページ --
(no template pages)
---- *要約 diff コマンドを利用してプログラムの正しさをチェックします。 $ > diff answer out ● answer 期待される出力結果のファイル ● out 実際の出力結果のファイル ---- *手順 **(1) check という,コマンドを作っておく chmod 755 check などで実行可能としておく #!/bin/sh -f R --vanilla --silent --slave < tests.R diff answer out 注1:tests.R は,以下に示す R スクリプト~ 注2:answer は,期待される出力のファイル(一文字単位で正確なもの)~ 注3:out は,開発中の関数が出力する結果が納められるファイル(実行のたびに作られる) **(2) チェックを行うための R スクリプト ファイル名は tests.R としておく (1) の中の名前と対応付け source("my.oneway.ANOVA.R") # my.oneway.ANOVA.R は,開発中のスクリプト---(3)を参照 test <- function() # テストの記述 { sink("out") # 以下の結果を out という名前のファイルに書き出す print(my.oneway.ANOVA(c(8, 11, 22, 6), c(135.83, 160.49, 178.35, 188.06), c(19.59, 12.28, 15.01, 9.81)^2)) print(my.oneway.ANOVA(c(8, 11, 22, 6), c(135.83, 160.49, 178.35, 188.06), c(19.59, 12.28, 15.01, 9.81)^2, equal=FALSE)) sink() # 書き出し終了 } test() # 実際にテストを実行する **(3) 開発中の関数 ファイル名は my.oneway.ANOVA.R としておく (2) の中の名前と対応付け my.oneway.ANOVA <- function(n, m, u, equal=T) { ng <- length(n) if (equal) { # 分散が等しいと仮定する場合 nc <- sum(n) sw <- sum(u*(n-1)) sb <- sum(n*(m-sum(n*m)/nc)^2) ss <- c(sb, sw, sb+sw) df <- c(ng-1, nc-ng, nc-1) ms <- ss/df f <- p <- rep(99999, 3) f[1] <- ms[1]/ms[2] p[1] <- pf(f[1], df[1], df[2], lower = F) anova.table <- cbind(ss, df, ms, f, p) colnames(anova.table) <- c("SS", "d.f.", "MS", "F value", "P value") rownames(anova.table) <- c("between class", "within class", "total") anova.table } else { # 分散が等しいと仮定しない場合 w <- n/u m0 <- sum(w*m)/(sum.w <- sum(w)) temp <- sum((1-w/sum.w)^2/(n-1))/(ng^2-1) f <- sum(w*(m-m0)^2)/((ng-1)*(1+2*(ng-2)*temp)) p <- pf(f, ng-1, 1/(3*temp), lower=F) list(F=f, df1=ng-1, df2=1/(3*temp), P=p) } } **(4) 開発中の関数が出力すると期待される結果を納めたファイル answer 前もって作っておく~ キーボードから入力する必要はない。~ できかけの関数が書き出す結果をファイルに出力し,必要なら微修正すればよい。 SS d.f. MS F value P value between class 13669.396 3 4556.4655 20.82824 1.737484e-08 within class 9406.843 43 218.7638 99999.00000 9.999900e+04 total 23076.240 46 501.6574 99999.00000 9.999900e+04 this line may be displayed. $F [1] 17.56461 $df1 [1] 3 $df2 [1] 16.50403 $P [1] 2.191921e-05 **(5) test により,実際に作成される結果のファイル out (1) で定義するシェルスクリプトにより起動される(2)の R スクリプト中の test 関数が出力する結果 SS d.f. MS F value P value between class 13669.396 3 4556.4655 20.82824 1.737484e-08 within class 9406.843 43 218.7638 99999.00000 9.999900e+04 total 23076.240 46 501.6574 99999.00000 9.999900e+04 $F [1] 17.56461 $df1 [1] 3 $df2 [1] 16.50403 $P [1] 2.191921e-05 **(6) 実行結果 (1) で作ったシェルスクリプトを実行する。 $ > ./check 5d4 < this line may be displayed. # 違いのある行が表示される **(7) 注釈 -膨大な出力ファイルでもかまわない -プログラムの改訂があれば,必要に応じて answer ファイルも改訂する -プログラムの改訂があったとき,いつでもこのチェックをする必要はない *コメント無用(^_^;)
タイムスタンプを変更しない
---- *要約 diff コマンドを利用してプログラムの正しさをチェックします。 $ > diff answer out ● answer 期待される出力結果のファイル ● out 実際の出力結果のファイル ---- *手順 **(1) check という,コマンドを作っておく chmod 755 check などで実行可能としておく #!/bin/sh -f R --vanilla --silent --slave < tests.R diff answer out 注1:tests.R は,以下に示す R スクリプト~ 注2:answer は,期待される出力のファイル(一文字単位で正確なもの)~ 注3:out は,開発中の関数が出力する結果が納められるファイル(実行のたびに作られる) **(2) チェックを行うための R スクリプト ファイル名は tests.R としておく (1) の中の名前と対応付け source("my.oneway.ANOVA.R") # my.oneway.ANOVA.R は,開発中のスクリプト---(3)を参照 test <- function() # テストの記述 { sink("out") # 以下の結果を out という名前のファイルに書き出す print(my.oneway.ANOVA(c(8, 11, 22, 6), c(135.83, 160.49, 178.35, 188.06), c(19.59, 12.28, 15.01, 9.81)^2)) print(my.oneway.ANOVA(c(8, 11, 22, 6), c(135.83, 160.49, 178.35, 188.06), c(19.59, 12.28, 15.01, 9.81)^2, equal=FALSE)) sink() # 書き出し終了 } test() # 実際にテストを実行する **(3) 開発中の関数 ファイル名は my.oneway.ANOVA.R としておく (2) の中の名前と対応付け my.oneway.ANOVA <- function(n, m, u, equal=T) { ng <- length(n) if (equal) { # 分散が等しいと仮定する場合 nc <- sum(n) sw <- sum(u*(n-1)) sb <- sum(n*(m-sum(n*m)/nc)^2) ss <- c(sb, sw, sb+sw) df <- c(ng-1, nc-ng, nc-1) ms <- ss/df f <- p <- rep(99999, 3) f[1] <- ms[1]/ms[2] p[1] <- pf(f[1], df[1], df[2], lower = F) anova.table <- cbind(ss, df, ms, f, p) colnames(anova.table) <- c("SS", "d.f.", "MS", "F value", "P value") rownames(anova.table) <- c("between class", "within class", "total") anova.table } else { # 分散が等しいと仮定しない場合 w <- n/u m0 <- sum(w*m)/(sum.w <- sum(w)) temp <- sum((1-w/sum.w)^2/(n-1))/(ng^2-1) f <- sum(w*(m-m0)^2)/((ng-1)*(1+2*(ng-2)*temp)) p <- pf(f, ng-1, 1/(3*temp), lower=F) list(F=f, df1=ng-1, df2=1/(3*temp), P=p) } } **(4) 開発中の関数が出力すると期待される結果を納めたファイル answer 前もって作っておく~ キーボードから入力する必要はない。~ できかけの関数が書き出す結果をファイルに出力し,必要なら微修正すればよい。 SS d.f. MS F value P value between class 13669.396 3 4556.4655 20.82824 1.737484e-08 within class 9406.843 43 218.7638 99999.00000 9.999900e+04 total 23076.240 46 501.6574 99999.00000 9.999900e+04 this line may be displayed. $F [1] 17.56461 $df1 [1] 3 $df2 [1] 16.50403 $P [1] 2.191921e-05 **(5) test により,実際に作成される結果のファイル out (1) で定義するシェルスクリプトにより起動される(2)の R スクリプト中の test 関数が出力する結果 SS d.f. MS F value P value between class 13669.396 3 4556.4655 20.82824 1.737484e-08 within class 9406.843 43 218.7638 99999.00000 9.999900e+04 total 23076.240 46 501.6574 99999.00000 9.999900e+04 $F [1] 17.56461 $df1 [1] 3 $df2 [1] 16.50403 $P [1] 2.191921e-05 **(6) 実行結果 (1) で作ったシェルスクリプトを実行する。 $ > ./check 5d4 < this line may be displayed. # 違いのある行が表示される **(7) 注釈 -膨大な出力ファイルでもかまわない -プログラムの改訂があれば,必要に応じて answer ファイルも改訂する -プログラムの改訂があったとき,いつでもこのチェックをする必要はない *コメント無用(^_^;)
テキスト整形のルールを表示する