---
title: Rの頑健なコードを書くにはどのような工夫が必要か
tags:  #r with pharma lab meetup 1  
author: [森岡裕[SASユーザー総会世話人]](https://image.docswell.com/user/6484025)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/LJ1Y39NXEG.jpg?width=480
description: Rの頑健なコードを書くにはどのような工夫が必要か by 森岡裕[SASユーザー総会世話人]
published: April 05, 26
canonical: https://image.docswell.com/s/6484025/K6NVG9-2026-04-05-101744
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/LJ1Y39NXEG.jpg)

2026年4月8日
R with Pharma Lab Meetup #1
Rの頑健なコードを書くにはどのような工夫が必要か
大山暁史


# Page. 2

![Page Image](https://bcdn.docswell.com/page/GJWGPQ4K72.jpg)

はじめに
Rプログラムを動かす機会が増えたが、意図通りに処理されているか不安
頑健なプログラムを書きたい！
頑健なRプログラムの例
・ 想定外のデータが入ってきた場合にも意図通りの処理または手当てができる
・ 実行環境を変えても意図通りの処理になる
・ バージョンが変わっても意図通りの処理になる
・ 処理が意図通りでない場合には検知できる
・ 可読である(他プログラマーも問題なく流用・メンテナンスできる)
Copyright©EPS All rights reserved.
2


# Page. 3

![Page Image](https://bcdn.docswell.com/page/4EZLKW2N73.jpg)

本発表について
Rの標準パッケージ(version 4.5.2)のコーディングについて、
想定外の挙動を起こさないように理解しておくべきこと、工夫できることを調査・検討した
以下は本発表のスコープ外とする
・ 追加パッケージのコーディング・処理
・ パッケージ/バージョン管理
・ バリデーション
・ ログチェック
・ IDE(Rstudio)の設定
Copyright©EPS All rights reserved.
3


# Page. 4

![Page Image](https://bcdn.docswell.com/page/Y76WQGV97V.jpg)

プログラム実行前に作業メモリ上のデータを消去する
以下コードを実行することで、作業メモリ上のオブジェクトが消去される
不要なオブジェクトの影響を受けないよう、Rスクリプトの先頭に記載すると良い
rm(list=ls())
※SASの以下の処理のようなもの
proc datasets kill nolist; quit;
Copyright©EPS All rights reserved.
4


# Page. 5

![Page Image](https://bcdn.docswell.com/page/G75MRVDD74.jpg)

式の途中の改行に注意
改行位置が演算子前後で処理が変わる
行が演算子で終わっている場合、式は完結していないとみなされる
a1 &lt;- 1 + 2 + 3
+4+5
a2 &lt;- 1 + 2 + 3 +
4+5
1+2+3 と4+5でそれぞれ2つの計算式としてみなされるので、
実行するとa1には6が格納され、コンソールに9が出力される
a2に15という結果が格納される
基本的に不要な改行はすべきではないが、
可読性の観点などから式の途中で改行する場合は注意
Copyright©EPS All rights reserved.
5


# Page. 6

![Page Image](https://bcdn.docswell.com/page/9J29DXMMER.jpg)

演算子の前後には半角スペースを入れる
例）x が -10以下の値である場合には ”xは-10より小さい” と出力したい
x &lt;- 15
x
if (x &lt; -10){
print(&quot;xは-10より小さい&quot;)
}
x
if (x &lt;-10){
print(&quot;xは-10より小さい&quot;)
}
x
← xに15を代入する
← xには15が代入されており、
xが-10より小さいと判定されない
← 演算子(&lt;と-)の間にスペースがないことで、
代入演算子(&lt;-)と判定され、
x&lt;-10により、xに10が代入されてしまう
また、条件は常に真と判定される
Rでは演算子の前後には半角スペースを入れないと意図しない処理になる危険がある
Copyright©EPS All rights reserved.
6


# Page. 7

![Page Image](https://bcdn.docswell.com/page/DEY428XPJM.jpg)

NAに注意
NA(欠損値)があると結果をNAで戻すなど、うまく動かない関数がある
→事前にNAの有無を確認
NAの判定についてはis.na()関数を用いる
x &lt;- c(1, 2, 3, NA)
x == NA
is.na(x)
ただし、is.na()はNaN(非数)もTRUEで判定してしまうことに留意
NaNを判定するにはis.nan()を用いる
x2 &lt;- c(1, 2, 3, NA, NaN)
is.na(x2)
is.nan(x2)
※sum関数など、実行時にNA(およびNaN)を除外して処理できるna.rmオプションがついている関数もある
Copyright©EPS All rights reserved.
7


# Page. 8

![Page Image](https://bcdn.docswell.com/page/VJNY8Q1M78.jpg)

データハンドリング時にNULLを発生させないように留意
NULLは何もないことを示すもの
解析時に意図しない挙動を起こしうる
条件分岐で該当がない場合、NULLが戻るので、
該当しない場合はNA(欠損値)を格納するようにコードに明示する必要がある
df &lt;- data.frame(id = 1:3, aval = c(1, -1, 2))
make_flag &lt;- function(x) {
if (x &gt; 0) {
return(&quot;Y&quot;) # ifに該当しない場合、手当をしないと NULL が戻る
} # NAを格納するにはelse if (x &lt;= 0){return(NA)} を追記
}
df$flag &lt;- sapply(df$aval, make_flag)
Copyright©EPS All rights reserved.
8


# Page. 9

![Page Image](https://bcdn.docswell.com/page/YE9PKD5WJ3.jpg)

算術処理前に適切な値か確認する
log()関数やsqrt()関数に負の数値を指定するとwarningを出してくれる
しかし、割合の分母に0を指定した場合にはwarningなしでInfやNaNが格納されるため、
分母が0でないか前処理で確認する必要がある
event &lt;- 10
subject &lt;- 0
proportion &lt;- event / subject #Infが格納される
event &lt;- 0
subject &lt;- 0
proportion &lt;- event / subject #NaNが格納される
Copyright©EPS All rights reserved.
9


# Page. 10

![Page Image](https://bcdn.docswell.com/page/GE8DR3YRED.jpg)

算術処理前に適切な値か確認する
平均はNA, Inf, NaNでない数値が1以上、SDは2以上ないとうまく算出できないため、
is.finite関数やlength関数で確認してから算出すると良い
x &lt;- c(10, 12, NA, Inf, NaN)
x2 &lt;- x[is.finite(x)] #有限な数値だけを取り出す
#lengthはオブジェクトの要素数を戻す関数
if (length(x2) &gt;= 2) {
sd(x2)
} else {
NA
}
Copyright©EPS All rights reserved.
10


# Page. 11

![Page Image](https://bcdn.docswell.com/page/LELMKV427R.jpg)

switch関数でも想定外のデータを検知できるように
SASでもif文、else if文を記載して、
それらに当てはまらない想定外のデータをelse文で捕捉することがあるが、
Rのswitch関数で条件分岐を実施する場合には、
閉じ括弧の上の行に該当する条件がない旨を検知できるような処理などを書く
switch(a,
&quot;1&quot; = x &lt;- 1,
&quot;2&quot; = x &lt;- 2,
print(&quot;該当する条件がありません&quot;)
)
Copyright©EPS All rights reserved.
11


# Page. 12

![Page Image](https://bcdn.docswell.com/page/4JMY2GK9JW.jpg)

代入演算子
・ 代入演算子として = は使わない
可読性、検索性の観点からオブジェクトに値を代入する際は &lt;- を使うことが良い
(Tidyverse style guideでも代入に &lt;- を用いるよう記載されている）
y = mean (x=1:5) #1つ目の=と2つ目の=は意味が違う
y &lt;- mean (x=1:5) #好みの問題もあるが、mean関数の結果をオブジェクトyに格納することが分かりやすい
・ 永続代入演算子 &lt;&lt;- は使わない
関数定義内からグローバル (関数定義外)のオブジェクトを上書きするもの
ミスの原因になることから、基本的に使用しない方が良い
Copyright©EPS All rights reserved.
12


# Page. 13

![Page Image](https://bcdn.docswell.com/page/PJR9MZX979.jpg)

小数点以下の表示桁数の設定
SASと同様、算出結果の小数点以下の最後の数字が 0 の場合には、
0 より手前までの値しか表示されない
帳票に載せる値を算出する際はformat関数やsprintf関数などを用いて
事前に小数点以下表示桁数を指定しておくと良い
y &lt;- round(0.12300, digits = 4)
y1 &lt;- format(y, nsmall = 4) #nsmallに小数点以下の桁数を指定する
y2 &lt;- sprintf(&quot;%.4f&quot;, y) #%.とfの間に小数点以下の桁数を指定する
なお、例示で用いているround関数はIEEE式であり、
そのままだとSASと異なる結果を戻す場合があることに留意
(SASと同様の処理をしたい場合は右記のような自作関数を用意する)
Copyright©EPS All rights reserved.
sas_round &lt;- function(x, digits = 0) {
p &lt;- 10^digits
(x * p * 2 + 1) %/% 2 / p
}
13


# Page. 14

![Page Image](https://bcdn.docswell.com/page/PEXQV963JX.jpg)

factor型→数値型の変換はひとまず文字型に変換してから
factor型のデータを数値型に変えると、
factorの中身ではなく水準番号が格納される
そもそも数字として処理し得るものはfactor型に設定しないほうが良いが、
factor型に設定されてしまっているデータを数値として扱うには、一度文字型に変換する
score &lt;- factor(c( &quot;10&quot;, &quot;20&quot;, &quot;30&quot;, &quot;20&quot;))
as.numeric(score)
as.numeric(as.character(score))
mean(as.numeric(score))
mean(as.numeric(as.character(score)))
Copyright©EPS All rights reserved.
14


# Page. 15

![Page Image](https://bcdn.docswell.com/page/3EK9QP1NED.jpg)

t関数で転置するなら転置後データフレームに戻す
データフレームをt関数で転置するとデータフレームはmatrix(行列)になる
そのため、転置後はデータフレーム型に戻すためにas.data.frame関数を使う
なお、 matrixは単一の型しか保持できないため、以下の優先順で1つの型に統一されることに注意
character(文字型) &gt; complex(複素数型) &gt; double(小数型) &gt; integer(整数型) &gt; logical(論理型)
df &lt;- data.frame(
USUBJID = c(&quot;01&quot;, &quot;02&quot;),
AVAL = c(10, 20),
ADT = as.Date(c(&quot;2024-01-01&quot; , &quot;2024-01-02&quot;)),
FLAG = c(TRUE, FALSE)
)
df_t &lt;- t(df) #そのまま転置するとmatrixになる
#matrix変換時に全ての値が文字型になっている
df2 &lt;- as.data.frame(t(df)) #データフレームに変換する
Copyright©EPS All rights reserved.
15


# Page. 16

![Page Image](https://bcdn.docswell.com/page/L73WPXQZ75.jpg)

文字値から日付値への変換はフォーマットに注意
文字値をas.Date関数を用いて日付値に変換する際、
文字値がyyyy-mm-dd形式かyyyy/mm/dd形式であればフォーマット指定なしで変換可能
x1 &lt;- as.Date(c(&quot;2026-01-01&quot;))
x2 &lt;- as.Date(c(&quot;2026/01/01&quot;))
しかし、Rではデータに複数形式が存在する場合、
指定フォーマットと対応していない値が警告なしにNAを戻すので注意
→変換後にNAが発生していないか確認すると安全
x3 &lt;- as.Date(c(&quot;2026-01-01&quot;, &quot;2026/01/01&quot;))
#フォーマットを指定しなければyyyy-mm-dd形式が変換される
x4 &lt;- as.Date(c(&quot;2026-01-01&quot;, &quot;2026/01/01&quot;), &quot;%Y-%m-%d&quot;)
x5 &lt;- as.Date(c(&quot;2026-01-01&quot;, &quot;2026/01/01&quot;), &quot;%Y/%m/%d&quot;)
if (any(is.na(x3))) stop(&quot;変換が適切であるか要確認&quot;)
Copyright©EPS All rights reserved.
16


# Page. 17

![Page Image](https://bcdn.docswell.com/page/87DKL294JG.jpg)

文字値から日付値への変換はフォーマットに注意
日本語環境で%Y(4桁の西暦) ,%m(2桁の月), %d(2桁の日)以外のフォーマットを使う場合、
日本語文字に変換されてしまい、戻り値がNAとなってしまう
→Sys.setlocale関数でロケール(国・地域の内部設定)をC言語の標準(北米)に設定する
as.Date(&quot;02JAN2026&quot;, &quot;%d%b%Y&quot;)
Sys.setlocale(&quot;LC_TIME&quot; , &quot;C&quot;)
as.Date(&quot;02JAN2026&quot; , &quot;%d%b%Y&quot;)
Copyright©EPS All rights reserved.
17


# Page. 18

![Page Image](https://bcdn.docswell.com/page/VJPK21ZVE8.jpg)

予約語に注意
以下などはRの処理系によって先に予約されているため、
オブジェクト名として使用することができない
break else FALSE for function if in Inf
NA NA_integer_ NA_real_ NA_complex_ NA_character_
NaN next NULL repeat TRUE while
Copyright©EPS All rights reserved.
18


# Page. 19

![Page Image](https://bcdn.docswell.com/page/2EVVDYWREQ.jpg)

予約語に注意
pi，T，F はそれぞれ円周率、TRUE、FALSE を
意味する記号として初期設定されているため、
オブジェクト名として使わないように(上書きしないように)留意
TやFはオプションの引数に使われることもあるため、
上書きされてしまうと以下のように意図通りの処理にならない
x &lt;- c(1, 2, 3, NA)
mean(x, na.rm = T) #na.rmがTRUEならNAを除外して処理する
T &lt;- FALSE
mean(x, na.rm = T)
→TRUEやFALSEについてはTやFのように省略せずに記載したほうが安全
Copyright©EPS All rights reserved.
19


# Page. 20

![Page Image](https://bcdn.docswell.com/page/57GLY9D6EL.jpg)

シード値設定漏れに注意
set.seed関数で乱数のシード値を設定できる
コード内で同じ結果を再現したい場合には毎回シード値を設定する必要がある
set.seed(123)
rnorm(5)
rnorm(5) #2行目の結果が再現されない
set.seed(123)
rnorm(5)
set.seed(123)
rnorm(5) #2行目の結果が再現される
Copyright©EPS All rights reserved.
20


# Page. 21

![Page Image](https://bcdn.docswell.com/page/4EQYMW12JP.jpg)

source関数によるプログラム呼び出し
各データ・帳票作成プログラム中で共通して用いる自作関数等は、
別途プログラムを用意しておき、source関数で呼び出すと良い（個々で関数を作ると効率悪い＆ミスにつながるため）
working directoryにあるプログラムであれば、パスは記載不要
source(&quot;パス/Myfunction.R&quot;)
echoオプションをTRUEにすると、呼び出したファイルのコードがコンソールに表示される
source(&quot;パス/Myfunction.R&quot;, echo = TRUE)
working directory：getwd()を実行すると出力される作業パス
Copyright©EPS All rights reserved.
21


# Page. 22

![Page Image](https://bcdn.docswell.com/page/KJ4WVKRP71.jpg)

source関数によるプログラム呼び出し
呼び出すプログラム内のオブジェクトとグローバルのオブジェクトが競合する場合には、
以下のように上書きされてしまう
x &lt;- 5
source(&quot;test.R&quot;, echo = TRUE) # test.Rの処理(x &lt;- 3) でxが上書きされる
x
新たな環境を作成し、その環境下に呼び出すと、
環境名$オブジェクト名に値が格納されるため、グローバルのオブジェクトは上書きされない
x &lt;- 5
temp_env &lt;- new.env(parent = baseenv()) #base環境の生成
source(&quot;test.R&quot;, local = temp_env, echo = TRUE)
x
temp_env$x
Copyright©EPS All rights reserved.
22


# Page. 23

![Page Image](https://bcdn.docswell.com/page/LE1Y3XQX7G.jpg)

相対パスを活用
他試験にプログラムを流用したり、CROで作成したプログラムをメーカー環境で実行するなど、
別環境で実行することが良くあるが、絶対パスを記載しているとそのまま実行することができない
別環境での実行を前提とするのであれば、
相対パス (working directoryを./で、その1つ上の階層を../で表す)を用いて記載する方が良い
source(&quot;../source/Myfunction.R&quot;)
Copyright©EPS All rights reserved.
23


# Page. 24

![Page Image](https://bcdn.docswell.com/page/GEWGPNMKJ2.jpg)

警告レベルを制御
options(warn=)で警告レベルを指定できる
設定値
動作
負の値
警告を表示しない
0 （デフォルト）
警告を出力するが、
コードは続行
1
警告を即時表示
（遅延表示しない）
2
警告をエラー扱いにする
warn=2を設定することにより、warningもerrorとして扱われる
処理を止めることができ、不備に気づきやすくなる(エラートラップ)
Copyright©EPS All rights reserved.
24


# Page. 25

![Page Image](https://bcdn.docswell.com/page/47ZLK3QNJ3.jpg)

警告レベルを制御
x_list &lt;- list(
c(&quot;1&quot;, &quot;2&quot;, &quot;3&quot;),
c(&quot;4&quot;, &quot;a&quot;, &quot;6&quot;), # ← &quot;a&quot; が混入（数値変換できない）
c(&quot;7&quot;, &quot;8&quot;, &quot;9&quot;)
)
options(warn = 0)
for (i in 1:3) {
as.numeric(x_list[[i]]) # 警告は最後に表示される
message(&quot;done i = &quot;, i)
}
options(warn = 1)
for (i in 1:3) {
as.numeric(x_list[[i]]) # 警告がその場で表示される
message(&quot;done i = &quot;, i)
}
options(warn = 2)
for (i in 1:3) {
as.numeric(x_list[[i]]) # エラーになる
message(&quot;done i = &quot;, i)
}
Copyright©EPS All rights reserved.
25


# Page. 26

![Page Image](https://bcdn.docswell.com/page/YJ6WQX69JV.jpg)

オプション設定をデフォルトに戻す
Rセッションを切るまではオプション設定が維持されてしまうので、
オプション変更前には情報をオブジェクトに退避し、
必要に応じてデフォルトに戻せるようにしておく
initial_option &lt;- options() #デフォルトのオプションを任意のオブジェクトに格納
getOption(&quot;warn&quot;)
options(warn=2) #オプションを変更する
getOption(&quot;warn&quot;)
options(initial_option) #デフォルトのオプションに戻す
getOption(&quot;warn&quot;)
Copyright©EPS All rights reserved.
26


# Page. 27

![Page Image](https://bcdn.docswell.com/page/GJ5MRX6DJ4.jpg)

ユーザー定義のWarning/Errorを活用する
warning関数を用いてWarningを、stop関数を用いてエラーを出すことができる
（使用例：データに未来日付が入っている場合、UATを用いた開発時にはWarningを、本番実行時にはエラーが出るように組む）
以下のように該当データを出力することも可能
dates &lt;- as.Date(c(&quot;2025-08-25&quot;, &quot;2025-12-10&quot;, &quot;2026-11-22&quot;, &quot;2027-03-05&quot;))
# 今日の日付
today &lt;- Sys.Date()
# 未来日付があれば警告
if (any(dates &gt; today)) {
warning(&quot;未来日付が含まれています: &quot;, paste(dates[dates &gt; today], collapse = &quot;, &quot;))
}
# 未来日付があればエラー
if (any(dates &gt; today)) {
stop(&quot;未来日付が含まれています: &quot;, paste(dates[dates &gt; today], collapse = &quot;, &quot;))
}
Copyright©EPS All rights reserved.
27


# Page. 28

![Page Image](https://bcdn.docswell.com/page/9E29DXNM7R.jpg)

ユーザー定義のWarning/Errorを活用する
例えば”warning”という単語でログを検索しているなどの都合上、
該当データがない場合にはwarningという文言をコンソールに出力したくない場合は、
message関数を用いて以下のように記載すれば良い
# 未来日付があれば警告（該当データがなければwarningという文言はコンソールに表示されない）
if (any(dates &gt; today)) {
message(&quot;w&quot;, &quot;arning 未来日付が含まれています:&quot;, paste(dates[dates &gt; today], collapse = &quot;, &quot;))
}
また、該当データの出力は難しいが、意図しない処理の検知にはstopifnot関数も有用
x &lt;- 0
stopifnot(&quot;x &gt; 3でない場合はエラー&quot; = x &gt; 3)
x &lt;- 5
stopifnot(&quot;x &gt; 3でない場合はエラー&quot; = x &gt; 3)
Copyright©EPS All rights reserved.
28


# Page. 29

![Page Image](https://bcdn.docswell.com/page/D7Y428PPEM.jpg)

tryCatch関数によるエラーハンドリング
Errorが生じた場合、特に手当を行わないと処理が止まってしまうが、
tryCatch関数を用いれば、エラーや警告が出ても処理を止めずに手当(例外処理)が可能
# 例として、xが0未満ならばエラーとなり、 xが0ならば警告となる関数を用意する
f &lt;- function(x) {
if (x &lt; 0) {
stop(&quot;Error! xが0未満&quot;)
} else if (x == 0) {
warning(&quot;Warning! xが0&quot;)
}
}
Copyright©EPS All rights reserved.
29


# Page. 30

![Page Image](https://bcdn.docswell.com/page/VENY8Q5MJ8.jpg)

tryCatch関数によるエラーハンドリング
# tryCatchを用いることで、エラーや警告が出ても処理を止めずに手当（例外処理）を行うことができる
g &lt;- function(x) {
tryCatch({
f(x)
return(x)
},
error = function(e) {
cat( e$message, &quot;であるためNAを返します&quot;, &quot;\n&quot;) # エラー時にはこちらの処理が動く。e$messageにはエラーメッセージが格納されている
return(NA)
},
warning = function(w) {
cat( w$message, &quot;であるためNAを返します&quot;, &quot;\n&quot;) #警告時にはこちらの処理が動く。w$messageには警告メッセージが格納されている
return(NA)
},
finally = {
cat(&quot;処理完了&quot;, &quot;\n&quot;) #必要に応じて、最後に必ず実行されるfinallyオプションに処理を記載する
}
)
}
g(2)
g(1)
g(0)
g(-1)
Copyright©EPS All rights reserved.
30


# Page. 31

![Page Image](https://bcdn.docswell.com/page/Y79PKDYWE3.jpg)

制限時間の設定
setTimeLimit関数を用いて、
実行時間が想定以上に長い処理は強制的にエラーにさせることができる
setTimeLimit(elapsed = 5) # 制限時間を5秒に設定
Sys.sleep(10) # 確認したい処理を記載する。（便宜上、例示では10秒のスリープ処理を入れている）
setTimeLimit() # 制限時間の設定を解除
Copyright©EPS All rights reserved.
31


# Page. 32

![Page Image](https://bcdn.docswell.com/page/G78DR36R7D.jpg)

制限時間の設定
実行時間が長い場合を検知したいがエラーとして処理を止めたくない場合には、
tryCatch関数とconditionMessage関数を用れば良い
なお、実行時間が長い場合以外のエラーも検知できるようにすることに留意
setTimeLimit(elapsed = 5)
res &lt;- tryCatch(
Sys.sleep(10),
error = function(e) {
if (grepl( &quot;time limit&quot; , conditionMessage(e))) {
message(&quot;処理時間が想定以上に長いので確認してください&quot;)
return(NULL)
}
stop(e) # 処理時間以外に関するエラーがある場合にはここで出力する
}
)
setTimeLimit()
Copyright©EPS All rights reserved.
32


# Page. 33

![Page Image](https://bcdn.docswell.com/page/L7LMKV92JR.jpg)

途中記載に警告を出力するオプション
①関数オプション名の途中記載
R は関数のオプション名を途中まで書いても一致させてしまう仕様であるが、
オプション名を正確に記載していないと、
バージョンが上がってオプション名が増えた場合などに挙動が変わる恐れがある
→options(warnPartialMatchArgs = TRUE) を設定することで、警告を出し得る
round(0.12300, digits = 4)
round(0.12300, digit = 4) #digitをdigitsとみなして処理される
options(warnPartialMatchArgs = TRUE)
round(0.12300, digits = 4)
round(0.12300, digit = 4) #digitは正確なオプション名ではないため警告
Copyright©EPS All rights reserved.
33


# Page. 34

![Page Image](https://bcdn.docswell.com/page/4EMY2GZ9EW.jpg)

途中記載に警告を出力するオプション
②属性の途中記載
属性名を途中までの一致で取得してしまう
→options(warnPartialMatchAttr = TRUE) を設定することで、警告を出し得る
x &lt;- 1:3
attr(x, &quot;label&quot;) &lt;- &quot;Score&quot;
attr(x, &quot;lab&quot;) #labをlabelとみなして属性を拾ってしまう
options(warnPartialMatchAttr = TRUE)
attr(x, &quot;lab&quot;) #設定されていない属性でないため警告
Copyright©EPS All rights reserved.
34


# Page. 35

![Page Image](https://bcdn.docswell.com/page/PER9MZ69J9.jpg)

途中記載に警告を出力するオプション
③$で指定した列名の途中記載
データフレーム中の$で指定した列名を途中までの一致で取得してしまう
→options(warnPartialMatchDollar = TRUE) を設定することで、警告を出し得る
df &lt;- data.frame(
testvar = 1:3,
othervar = 4:6
)
df$testv
df$oth
options(warnPartialMatchDollar = TRUE)
df$testv
df$oth
Copyright©EPS All rights reserved.
35


# Page. 36

![Page Image](https://bcdn.docswell.com/page/P7XQV9M3EX.jpg)

途中記載に警告を出力するオプション
ただし、以下のように途中までの記載から、列名を一意に推測・特定できない場合、
options(warnPartialMatchDollar = TRUE) の設定に関わらずNULLを戻す
adsl &lt;- data.frame(
TRT01PN = c(1,2,1),
TRT01P = c(&quot;A&quot;,&quot;B&quot;,&quot;A&quot;)
)
adsl$TRT
options(warnPartialMatchDollar = TRUE)
adsl$TRT
そのため、データフレームから列を取得する場合には$を使わず、
不正確な列名の場合エラーを戻すことができる、データフレーム名[ ,列名]の書き方をすると良い
Copyright©EPS All rights reserved.
36


# Page. 37

![Page Image](https://bcdn.docswell.com/page/37K9QPGN7D.jpg)

attach関数は使用しない
データフレームの変数を操作する際に、
毎度データフレーム名を指定する必要がないようにattach関数が用意されているが、
以下のように意図通りの処理にならない恐れがあるため使用しない方が良い
AVAL &lt;- 10
df &lt;- data.frame(AVAL = 1:3, TRT=1:3)
attach(df)
TRT #df内のTRTをdf名の指定なしで展開できる（変数名が競合しないので適切に動く）
AVAL #df内のAVALではなく、もともと定義していたAVALが優先される
df &lt;- data.frame(AVAL = 1:3)
attach(df)
AVAL &lt;- AVAL + 1 #新しいオブジェクトに上書きされる
AVAL
df #dfのAVALには反映されていない
Copyright©EPS All rights reserved.
37


# Page. 38

![Page Image](https://bcdn.docswell.com/page/LJ3WPXNZJ5.jpg)

関数名の重複に注意
追加パッケージに含まれる関数名が、既にロードしていたパッケージの関数名と重複する場合、
追加パッケージのロード時に以下のようなNoteが出て、関数が上書きされる
関数はstats::lagのようにパッケージ名::関数名で呼び出すことが可能なので、
複数パッケージに存在する関数を用いる場合には、
パッケージ名::関数名という形で記載したほうが良い
Copyright©EPS All rights reserved.
38


# Page. 39

![Page Image](https://bcdn.docswell.com/page/8JDKL2W4EG.jpg)

自作関数は既存関数名と別名で定義する
自作関数名がRで既に用意されている関数名と同名であっても、
警告が表示されないことが多いので注意
log(1)
log &lt;- function(x){
return(x)
}
log(1) #関数が上書きされた
rm(log) #関数を上書きしてしまった場合はオブジェクトを消去
log(1)
Copyright©EPS All rights reserved.
39


# Page. 40

![Page Image](https://bcdn.docswell.com/page/VEPK219V78.jpg)

関数名の重複確認・所在確認
ロード済みの関数のうち、重複した関数はconflicts()で調べることができる
(インストールしているがロードしていないパッケージは判定されない)
また、各関数の所在はfind(“関数名”)で調べることができる
Copyright©EPS All rights reserved.
40


# Page. 41

![Page Image](https://bcdn.docswell.com/page/27VVDYMR7Q.jpg)

まとめ
標準パッケージの頑健なコーディングについて検討した
今後はpharmaverseなどの追加パッケージについても検討したい
皆様が工夫されていることがございましたら、是非コメントいただけますと幸いです
Copyright©EPS All rights reserved.
41


# Page. 42

![Page Image](https://bcdn.docswell.com/page/5JGLY9G67L.jpg)

参考文献
[1] The R Project
https://www.r-project.org
[2] Rdocumentation
https://www.rdocumentation.org
[3] 舟尾 暢男 (2016) The R Tips 第3版 ーデータ解析環境Rの基本技・グラフィックス活用集ー オーム社
[4] Name all but the most important arguments Tidy design principles
https://design.tidyverse.org/call-data-details.html
[5] Ｒのスクリプト作成時の注意点とエラーへの対処 名古屋大学 大学院教育発達科学研究科・教育学部
https://www.educa.nagoya-u.ac.jp/~ishii-h/materials/R_errors.pdf
[6] Tidyverse style guide
https://style.tidyverse.org/
Copyright©EPS All rights reserved.
42


# Page. 43

![Page Image](https://bcdn.docswell.com/page/47QYMWX2EP.jpg)



