オブジェクト指向言語のJavaや、それに加えてテンプレートお化けのC++と比較すると簡素な言語仕様であるRは、直観で使っている人々が多く、それで間に合ってしまうことが多いと思いますが、プログラミング初心者や他のプログラミング言語利用者に説明するときのために、ざっとした説明をまとめました。
1 算術演算子
四則演算は普通にあります。
1 + 2
[1] 3
2 * 3
[1] 6
3 - 4
[1] -1
4 / 5
[1] 0.8
6 ^ 7 # 6の7乗
[1] 279936
10 %/% 3 # 端数切捨ての除算
[1] 3
10 %% 3 # 剰余
[1] 1
3*(1 + 2)
[1] 9
優先順位は、括弧、n乗、乗算・除算・剰余、加算・減算です。
2 コメント
行の#
から右側は無視されて実行しません。コードの先頭に#
をつけて、消さずに実行させないことをコメント・アウトと言います。
3 関数
変数名と括弧で表記されるのは関数です。括弧内に値があれば、それを元に動作し、計算結果を戻します。
# 4の階乗を計算
factorial(4)
[1] 24
ユーザー定義の方法は、Rの関数のざっとした説明でもう少し詳しく説明しています。
4 変数
アルファベットの並びに<-
と->
で数字や文字列を代入できます。
<- 123
x 10 -> y
%% y x
[1] 3
%/% y x
[1] 12
<- "zetton") (z
[1] "zetton"
対話モードで代入演算全体を(
と)
でくくると、代入した内容が表示されます。
5 文
これまで書いてきた1+2
のような命令をそれぞれ文(statement)と呼びます。一行一文とは限らず、以下の様に演算子の後の改行では文は終了しませんし、
1 +
2
[1] 3
(
や{
を書いた場合は、対応する)
や}
が書かれるまでは、文の途中と看做されます。
逆に;
で区切って一行に複数の文も書けます。
1 + 2; 3 + 4
[1] 3
[1] 7
6 コードブロック
{
と}
の間をコードブロックと呼びます。関数の引数のような一文しか書けないようなところに入れることができます。
<- {
a print(1)
2
}
[1] 1
a
[1] 2
コードブロック内では文を何行でも書くことができ、最後の評価式がコードブロックの値となります。評価式が無い場合はNULL
が戻ります。なお、NULL
のときのためのPerl風の演算子%||%
が用意されています。
<- {}
a # if(is.null(a)) print("a is NULL")と同じ
%||% "a is NULL" a
[1] "a is NULL"
7 データ型
数値と文字は違う、数値も整数と小数点付きは違うぐらいの認識でもだいたい困らないと思いますが、Rでもデータには型があります。
- 数値(
numeric
)- 整数(
integer
) - 浮動小数点(
double
/single
) - 複素数(
complex
)
- 整数(
- 文字列(
character
) - 真理値(
logical
) - バイナリ型(
raw
)
が用意されています。型変換関数などで指定しなければ、変数の型は自動で判断されます。
型はtypeof
で確認できます。
<- as.integer(1); typeof(x) x
[1] "integer"
<- as.numeric(1); typeof(x) x
[1] "double"
<- "1"; typeof(x) x
[1] "character"
演算時も可能ならば自動的に型変換が行われます。
typeof(as.integer(1) + as.numeric(2))
[1] "double"
typeof(as.numeric(3) + as.integer(4))
[1] "double"
文字列型を数字に変えたりはできずエラーになります。
typeof(as.character(5) + 6)
as.character(5) + 6 でエラー: 二項演算子の引数が数値ではありません
虚数は\(1i\)と言うように、数字の後に\(i\)をつけて表します。
# 指数表記を抑制
options(scipen=FALSE)
# 1の三乗根を三乗
-1/2 + 1i*sqrt(3)/2)^3 (
[1] 1+1.110223e-16i
真理値はTRUE
(T
と略記可)とFALSE
(F
と略記可)の二つです。
typeof(TRUE)
[1] "logical"
typeof(FALSE)
[1] "logical"
条件文やベクトルの要素を抜き出すときに使います。
バイナリ型については、Rでのバイナリファイルの扱い方を参照してください。
8 データ構造
同じデータ型のデータの集合体がベクトル(一次元配列)になり、実はx <- 1
とした場合も、要素数が一つ配列として扱われ、配列xの1番目の要素を意味するx[1]
と言う表記でも値を参照できます。ベクトルがもっとも基本的なデータ構造です。詳しくはRのベクトルの扱い方のざっとした説明を参照してください。
異なる型のベクトルを束ねることができるデータ構造がリストです。名前とベクトルをセットにできる構造で、他のプログラミング言語だと連想配列/ハッシュ配列/MAP/辞書などと呼ばれるものにあたります。詳しくはRのリストの扱い方のざっとした説明を参照してください。
Rのユーザープログラミングでは、計算や加工を行う対象になるデータを格納する構造としてベクトルとリストを用います。R内部で扱われるペアリスト、ペアリストの特殊版であるモデル式1などの言語オブジェクト2、名前空間でもある環境もデータ構造ですが、Rの動作を定めるための特殊なデータのためのものです。
ベクトルとリストには、属性(attributes
)を設定することができます。行列や3次元以上の配列は、ベクトルに属性をつけたものです。因子型(factor
)や順序型(ordered
)もそうなります。データフレームは、リストに属性をつけたものになります。計量分析をするlm
などの関数の戻り値も、同様です。
9 条件分岐
if
とelse
が用意されています。例えばこんな風に書きます。
<- 1.23
x if(is.numeric(x)){
if(is.integer(x)) print("x is integer!")
else if(is.double(x)) print("x is double!")
else if(is.single(x)) print("x is single!")
if(0 > x[1]) print("x[1] is lower than zero!")
else if(0 < x[1]) print("x[1] is greater than zero!")
else print("x[1] is zero!")
else if(is.character(x)) print("x is a string!") else {
} print("x is other type!")
}
[1] "x is double!"
[1] "x[1] is greater than zero!"
if
の括弧の中は真偽値の評価式になっている必要があり、>
,<
,>=
3,<=
4,==
,!=
5,%in%
[^CND4]といった比較演算子か、真偽値を戻す関数を使います。真偽値は!
で反転させることができます。また、ベクトル全体を評価した場合は、ベクトルの要素それぞれに計算される真偽値をany
(どれかが真)やall
(すべてが真)などの関数でまとめる必要があります。
10 繰り返し文(ループ)
for
とwhile
とrepeat
が用意されています。
for
はベクトルの要素をひとつづつ取り出し、処理を繰り返す文です。
# 1,2,3からなるベクトルをつくって、順番にiに代入して処理
for(i in c(1, 2, 3)) print(i)
while
は条件式が真の間、処理を繰り返す文です。
# iが3以下の間、処理
<- 1
i while(i <= 3){
print(i)
<- i + 1
i }
repeat
は無条件に、処理を繰り返します。
<- 1
i repeat{
print(i)
<- i + 1
i # iが4以上のときループを抜ける
if(i >= 4) break;
}
繰り返す文の中にnext
を入れると、繰り返す文の最初に戻ります。for
であれば次の要素が取り出され、while
であれば条件式が評価されます。
break
を入れると、繰り返しを抜けます。
11 エラーと例外処理
stop
を使うと基本的に処理がそこで止まり、後の文は評価されません。同様にエラーが出して止まるRの関数もあります。しかし、例外処理を書いて処理を続行させることもできます。エラーが出た後にも終了処理などが必要な場合に便利です。
<- tryCatch({
(r stop("Error!")
0 # エラーが無ければ最後の式の値がtryCatch文の値
error = function(e){
}, # エラーが出れば実行
message("Exception occured!")
-1 # エラー時のtryCatch文の値
warning = function(e){
}, # 警告が出れば実行
message("Warning occured!")
-2 # 警告時のtryCatch文の値
finally = {
}, # エラーが出ても出なくてもfinallyの部分は実行
message("Exception occured or not")
NULL # 使われない(ので無い方がよい)
}))
第1引数とfinally
は文で、error
とwarning
が関数であることには注意してください。
error
とwarning
に指定する関数の引数には、condition
クラスから派生したerror
もしくはwarning
S3オブジェクト6が入ります。中身はメッセージと評価式です。評価式はエラーがおきた場所を示すことに使われたりしますが、NULL
の場合もあります。
11.1 例外をキャッチしない方法
オブジェクト指向的なtry-catchが好きではない人のために、try
関数があります。
# エラーの発生とメッセージ表示を抑制
<- try(stop("Error!"), silent = TRUE)
r # 戻り値がtry-errorクラスを継承していれば、エラー処理を行う
if(inherits(r, "try-error")){
message(r)
}
11.2 警告
警告も同様に例外処理にかけられますが、単に画面にメッセージを出したくないときはtryCatch
の代わりにsuppressWarnings
でラップすれば済みます。なおwarning
関数は警告が表示されますが処理は止まらないです。またwarnings
関数で直近のエラーメッセージは表示できます。