rでのtry関数によるエラー処理

8
Rでのtry関数によるエラー処理 作成: 2015年3月1日(日) ~ 異常終了の防止方法 ~

Upload: wada-kazumi

Post on 19-Jul-2015

568 views

Category:

Education


5 download

TRANSCRIPT

Page 1: Rでのtry関数によるエラー処理

Rでのtry関数によるエラー処理

作成: 2015年3月1日(日)

~ 異常終了の防止方法 ~

Page 2: Rでのtry関数によるエラー処理

こんなことありませんか?昔々あるところに、複数のデータセットに時間

のかかる同じ処理をしなければならないセンサスくんがいました。賢いセンサスくんは、一部のデータを使って処理コードを作り、さらにforループでデータセットを入れ替える処理を加えて自動化し、帰宅間際にPCに投げました。センサスくんが帰宅しても、PCが夜なべで働

き、翌朝出勤時までに仕事が終わっているはずでしたが、その翌朝・・・

あ~っ、途中でabort(異常終了)してる・・・

Page 3: Rでのtry関数によるエラー処理

何が起きるのか確認してみましょう

これは正常終了するコードの例です

rm(list=ls(all=TRUE)) # ワークスペースのクリア

data(iris) # 組み込みのあやめデータ呼出し

aa <- as.matrix(iris[,1:4]) # 量的変数だけ行列属性に変換してaaへ

# 品種を示す第5変数の内容別にデータフレームを作成

dat1 <- aa[which(iris[,5]=="setosa"),]

dat2 <- aa[which(iris[,5]=="versicolor"),]

dat3 <- aa[which(iris[,5]=="virginica"),]

listD <- ls(pattern="d") # ワークスペース内のdで始まる変数名を取得

listD # 中身表示

# listDの数だけループをさせて、dat1~3の共分散行列を表示させる

for (i in 1: length(listD)) {

x <- get(listD[i])

cv <- cov(x) # データの共分散行列を算出

print(solve(cv)) # 共分散行列の逆行列を画面表示

}

Page 4: Rでのtry関数によるエラー処理

逆行列計算がabortするとき先の例では、共分散行列は全て正則なので、

逆行列の計算は正常終了します。続けて、以下のコードにより、dat2の逆行

列が計算できなくなるよう、特定の行の要素だけ有効桁数を超える小さな数に変更してみます。

cv <- cov(dat2)cv[1,] <- cv[1,] / 10**16solve(cv) # ここでエラーが起きる

> cv <- cov(dat2)> cv[1,] <- cv[1,] / 10**16> solve(cv)# エラーが起きる。以下にエラー solve.default(cv) : システムは数値的に特異です:条件数の逆数 = 1.4947e-17

追加コード

コンソール出力

forループ内でこれが起きると、その時点で処理が終了します。複数データ

をforで回していれば、後ろのデータは未処理のまま。

Page 5: Rでのtry関数によるエラー処理

エラーが起きても後のデータを処理して欲しいのですが・・・

そんなあなたにtry関数!

cv <- cov(dat1)cv[1,] <- cv[1,] / 10**16XX <- try(solve(cv)) # ここでtry関数を使うXX # XXにエラーメッセージが入ることに注意!

> cv <- cov(dat1)> cv[1,] <- cv[1,] / 10**16> XX <- try(solve(cv))# ここでtry関数を使うError in solve.default(cv) : システムは数値的に特異です: 条件数の逆数 = 1.4947e-17

> XX# XXにエラーメッセージが入ることに注意![1] "Error in solve.default(cv) : \n システムは数値的に特異です: 条件数の逆数 = 1.4947e-17 \n"attr(,"class")[1] "try-error"attr(,"condition")<simpleError in solve.default(cv): システムは数値的に特異です: 条件数の逆数 = 1.4947e-17 >

追加コード

コンソール出力

エラーが起きてもループの途中で異常終了はせず、後ろの処理が続行されます

Page 6: Rでのtry関数によるエラー処理

実際に試してみましょう

結果の出力は次のスライドへ

# 数値をいじるために一旦共分散行列を変数cv1に格納する

cv1 <- array(NA, c(4,4,3))

for (i in 1: length(listD)) {

x <- get(listD[i])

cv1[,,i] <- cov(x) # 配列cv1に保存

}

cv1[1,,2] <- cv[1,,2] / 10**16 # 二つ目の共分散行列の要素1つを小さく

# try関数なしの場合for (i in 1: length(listD)) {

print(solve(cv1[,,i])) # 共分散行列の逆行列を画面表示

}

# try関数を使う場合for (i in 1: length(listD)) {

print(try(solve(cv1[,,i]))) # 共分散行列の逆行列を画面表示

}

追加コード

Page 7: Rでのtry関数によるエラー処理

結果のコンソール出力> # try関数なしの場合> for (i in 1: length(listD)) {+ print(solve(cv1[,,i]))# 共分散行列の逆行列を画面表示+ }

[,1] [,2] [,3] [,4][1,] 18.943439 -12.404826 -4.500207 -4.776127[2,] -12.404826 15.570540 1.111079 -2.104098[3,] -4.500207 1.111079 38.776204 -17.935035[4,] -4.776127 -2.104098 -17.935035 106.045906以下にエラー solve.default(cv1[, , i]) : システムは数値的に特異です: 条件数の逆数 = 0

>

> # try関数を使う場合> for (i in 1: length(listD)) {+ print(try(solve(cv1[,,i])))# 共分散行列の逆行列を画面表示+ }

[,1] [,2] [,3] [,4][1,] 18.943439 -12.404826 -4.500207 -4.776127[2,] -12.404826 15.570540 1.111079 -2.104098[3,] -4.500207 1.111079 38.776204 -17.935035[4,] -4.776127 -2.104098 -17.935035 106.045906Error in solve.default(cv1[, , i]) : システムは数値的に特異です: 条件数の逆数 = 0

[1] "Error in solve.default(cv1[, , i]) : \n システムは数値的に特異です: 条件数の逆数 = 0 \n"attr(,"class")[1] "try-error"attr(,"condition")<simpleError in solve.default(cv1[, , i]): システムは数値的に特異です: 条件数の逆数 = 0 >

[,1] [,2] [,3] [,4][1,] 10.533867 -3.479726 -9.960146 1.788152[2,] -3.479726 15.875442 1.102689 -8.472851[3,] -9.960146 1.102689 13.405821 -2.890918[4,] 1.788152 -8.472851 -2.890918 19.314050>

try関数で問題の起きる処理をくるむと、i=2でエラーが起きても、i=3での逆行列が計算されます

Page 8: Rでのtry関数によるエラー処理

おわり

8