Rに限らず、どのようなプログラミング言語を用いる場合においても、読みやすいコードと読みにくいコードがあります。また、変数や関数の名前はわかりやすくつけておかないと、後々どのような意味の変数・関数であったかを理解しにくくなってしまいます。
このような、コードの問題、変数や関数の名前の問題をできるだけ抑えるために、企業などでプログラミングを行う場合には、その組織のコーディング規約(coding style) 、つまりコードの書き方のルールを設けるのが一般的です。
Rは大学の研究室などで、教官や学生などが小規模なデータの分析に用いる場合も多いため、コーディング規約は必ずしも重要ではありませんが、コードの可読性を高め、解析の再現性(reproducibility)を担保するためにコーディング規約に基づいたプログラミングを心がけた方が良いでしょう。
Rのコーディング規約では、tidyverseに従ったもの(tidyverse style guide )が主流だと思います。
Rには、styler
(Müller and Walthert 2023 ) やformatR
(Xie 2023 ) という、coding styleを修正してくれるライブラリや、Rstudioのコーディング規約修正(reformat code)のショートカット(Ctrl+Shift+A)などが備わっており、ある程度自動的にフォーマットの修正を行うことができますので、このような機能を用いるのもよいでしょう。
Rでのコーディング規約については、基本的には上記のtidyverse style guide に従うのが最もよいでしょう。以下にtidyverse style guideに記載のコーディング規約のうち、よく用いられる表現について記載しておきます。
ファイル名
ファイル名はPCにも読みやすく、ヒトにも読みやすいようにしましょう。スペースやシンボルを使うのは避け、文字の区切りには-(ハイフン)もしくは_(アンダースコア)を使うことが推奨されます。ファイル名は意味のある言葉とし、同じ種類のファイルは同じルールで名前を付けましょう。
# 良い例
## 拡張子のRは大文字、アンダースコアで単語を繋ぐ
fit_models.R
## ファイル名は意味が理解できるものとする
report_of_iris_analysis.txt
## 同じ種類のファイルの命名は似た形にする
fig- lm- iris-1. png
fig- lm- iris-2. png
# 悪い例
## 拡張子のRに小文字を用いない、スペースを用いない
fit models.r
## 意味がわからないファイル名にしない
temp.txt
## 同じ種類のファイルを違う形で保存しない
fig lm iris1.PNG
fig_iris.png
また、ファイル名にはその順番が分かるような指標(01、02などの番号、日付など)を加えて、ファイルの順序が分かるようにしましょう。
# 良い例
01 - lm- analysis.R
02 - glm- analysis.R
240401 _file1.R
240501 _file2.R
# 悪い例
## アルファベット順に並べるとファイル順や日付順に並ばない
lm- analysis01.R
glm- analysis02.R
file_text_240401.txt
file_image_240501.txt
ファイル名に「最終」などを付けないようにしましょう。大体の場合、「最終2」などができます。
# 悪い例
lm_analysis_final.R
lm_analysis_final2.R
lm_analysis_final_revisited.R
シンタックス
シンタックスというのは、プログラムとして書く文書、要はコードのことを指します。コードを書く時のルールを以下に記載していきます。
変数名
変数名は単語をアンダースコアでつないで記載しましょう。変数名にはその変数の意味の分かる名前を用い、あまり長くならないようにします。また、Rに定義されている変数や関数などを上書きしないよう気を付けましょう。キャメルケース(dayOne
、DayOne
のように単語の区切りを大文字にする)は基本的に使用しません。
# 良い例
day_1
mean_leaf_length
# 悪い例
the_first_day_of_1994_May
mll
pi <- "円周率" # 既存の変数に代入
スペースの使用
コンマの後、演算子の前後にはスペースを入れましょう。ただし、演算子の一部(:
や^
、!
、?
、[
、$
など)の前後にはスペースを入れません。
関数のカッコの前後にはスペースを入れず、if
、for
、while
の後、()
と{}
の間にはスペースを入れましょう。function
の後にスペースは入れませんが、()
と{}
の間にスペースを入れるのが推奨されています。
(私はif
文や){
の間にはスペースを入れない主義ですが、コーディング規約にはスペースを入れるよう記載されています)
# 良い例
x [ 1 , ]
c ( 1 , 2 , 3 )
y <- 4 + 1
if ( z < 10 ) { print ( x ) }
function ( x ) { print ( x ) }
# 悪い例
x [ 1 ,]
c ( 1 ,2 ,3 )
y <- 4 + 1
## 個人的にはこちらが良いと思っています
if ( z < 10 ) { print ( x ) }
function ( x ) { print ( x ) }
改行の代わりにセミコロン(;
)を使うのは避けましょう。また、代入は<-
で行い、=
は使わないようにしましょう。文字列にシングルクォーテーション('
)を使うのもやめましょう。
# 良い例
x <- 1
y <- 2
"A dog is walking."
# 悪い例
x = 1 ; y = 2
'A dog is walking.'
関数
関数名
関数名は基本的に変数と同じように、意味が分かるように、アンダースコアで単語を繋いだものとします。ただし、関数名は動詞を使うこととされています。
# 良い例
bind_row ( )
mutate ( )
# 悪い例
binder_of_row ( )
mutation ( )
無名関数
無名関数とは、関数名を定義することなく用いる関数で、apply
関数などで利用されます(11章 の最後を参照)。無名関数はfunction
でも、バックスラッシュ(\
)でも作成できます。
無名関数を用いるときは、function
を用いても、\
を用いても問題ありません。ただし、\
は改行のある関数では使わない、名前付き関数(通常の関数名を使う関数のこと)では使用しないようにします。
return関数
関数の返り値は他の言語では通常return
関数で明示的に示すのが一般的だと思います。Rでもreturn
関数で指定することはできますが、Tidyverse style guideではfunction
の返り値はreturn
関数で示すのではなく、最後に変数を宣言する形で設定するとしています。ただし、function
の最後ではない場所で返り値を返す場合にはreturn
関数を使いましょう。
# 良い例
sum_2_value <- function ( x , y ) {
z <- x + y
if ( z < 2 ) { return ( 0 ) }
z
}
# 悪い例
sum_2_value <- function ( x , y ) {
z <- x + y
if ( z < 2 ) { return ( 0 ) }
return ( z )
}
パイプ演算子
20章 で紹介したパイプ演算子は演算の文脈を理解するために有用ですが、パイプ演算子の利用が適していない場合もあります。例えば、
2つのオブジェクトを同時に加工したい場合
パイプ演算子の途中で生成する中間的なオブジェクトを維持することに意味がある場合
パイプ演算子の前にはスペースを入れ、パイプ演算子の後で改行します。改行した場合にはインデントを入れます。Rstudioではパイプ演算子をショートカット(ctrl+shift+M)で入力すると自動的にスペースが加えられ、改行するとインデントされるので、Rstudio使用している場合には特に気にする必要はないでしょう。
# 良い例
iris |>
group_by ( Species ) |>
summarise ( m = mean ( value ) )
# 悪い例
iris |> group_by ( Species ) |> summarise ( m= mean ( value ) )
パイプ演算子の演算内で別のパイプ演算子の演算を行うとわかりにくくなるので避けましょう。また、Rのデフォルトのパイプ演算子(|>
)が推奨されており、magrittr
のパイプ演算子(%>%
)は避けるようにしましょう。
# 良い例
x_join <- x |> select ( a , b , w )
y_join <- y |> select ( a , b , v )
left_join ( x_join , y_join , join_by ( a , b ) )
# あまり良くない例
x |>
select ( a , b , w ) |>
left_join ( y |> select ( a , b , v ) , join_by ( a , b ) )
ggplot2
26章 で紹介するggplot2
では、+
演算子ごとに改行を入れます。また、引数がたくさんある場合には改行を入れるようにしましょう。
iris |>
ggplot ( aes ( x= Sepal.Length , y = Sepal.Width , color = Species , fill = Species ) ) +
geom_point ( size = 1 ) +
geom_smooth ( method = "lm" ) +
labs (
x = "Sepal Length" ,
y = "Sepal Width" ,
title = "linear regression of Sepal Length & Width" ,
caption = "ribbon represents 95% CI"
)