はじめに
2024年1月15日
最近、いくつかの友人からR言語について尋ねられ、puqでは社会科学や自然科学の分野でR言語の学習が共有されているのを見かけました。
これはかなり人気があり実用的なツールだろうと思い、冬休みを利用してR言語を独学することに決め、学習ノートをブログ形式で記録することにしました。
2月12日
他のことが忙しくて、この目標を思い出したのは今頃になってしまいました。学習を再開します。
まず準備として、ここからR言語の環境をダウンロードしてインストールし、同時にVisual Studio Codeで対応するモジュールをインストールして操作します。筆者が使用しているのは4.3.2バージョンです。
菜鳥プログラミングのステップバイステップに従って学習を進めます。
紹介によると、R言語は主に数学分析に使用され、用途はMATLABと似ています。
基礎構文
変数
有効な変数名は、文字、数字、'.'(ドット)、'_'(アンダースコア)で構成され、文字またはドットで始まります。
._.
e.e
これらはすべて有効な変数名ですが、少し奇妙ですね。
変数への代入
<-、=、->のいずれも代入に使用でき、矢印の方向が代入の方向です。
ls()関数は、すべての名前付き変数名を確認できます。
rm(a)関数は、変数aを削除できます。
data_point=1
result_value<-2
3->storage_value #3つの基本的な代入方法
print(ls()) #出力は"data_point" "result_value" "storage_value"
rm(data_point) #変数data_pointを削除
print(ls()) #出力は"result_value" "storage_value"
対話型プログラミング
Macではコマンドラインで'R'を実行すると直接対話型プログラミングウィンドウに入ることができますが、Windowsのコマンドプロンプトではできません。
q()関数を入力すると終了できます。
ファイルスクリプト
R言語のファイル拡張子は.Rです。
入出力
print()
print("表示するテキスト") #出力は"表示するテキスト"
print(12.30) #出力は12.3、末尾の0は自動的に削除される
print(3.2e2) #出力は320、科学記数法
cat()
cat(output_data,file='D:\\output.txt',append=TRUE)
#output_dataをファイルに出力し、ここではファイルの絶対パス、appendパラメータは追加か上書きかを制御し、デフォルトは上書き
sink()
sink("D://output.txt") #コンソール出力を対象ファイルにリダイレクトし、コンソールには出力を表示しない
sink("D://output.txt",split=TRUE) #splitパラメータによりコンソールに依然として出力を表示できる
sink() #ファイル出力をキャンセル
テキスト入力
R言語にはコンソールから読み込むための専用関数はなく、Rの使用中にテキスト入力は常に実行されています。
ファイルからのテキスト読み込み
readLines("パス/ファイル名") #ファイルから読み込み、各行を文字列として扱い、最後の行には改行が必要
その他の方法
CSV、Excelなどについては、後日学習するために穴を空けておきます。
作業ディレクトリ
getwd() #get working directory、現在の作業ディレクトリを取得し、文字列形式で出力
setwd("パス") #set working directory、現在の作業ディレクトリを設定
コメント
#これはコメントの方法です
if(FALSE){
"これもコメントの方法です"
}
#Visual Studio Codeではctrl+/でコメントできます
データ型
数値
通常の表記法と科学記数法、例:2.5,25e-1,25E-1。
論理値
TRUEとFALSE、大文字小文字を厳密に区別します。
テキスト
文字型データ、単一引用符または二重引用符で表現します。
基本的な演算
数学演算子
| 記号 | 意味 | 例 | 結果 | 優先順位 |
|---|---|---|---|---|
| () | 括弧 | (5) | 3 | 1 |
| ^ | べき乗 | 5^2 | 25 | 2 |
| %% | 剰余 | 5%%2 | 1 | 3 |
| %/% | 整数除算 | 5%/%2 | 2 | 3 |
| \* | 乗算 | 5\*2 | 10 | 4 |
| / | 除算 | 5/2 | 2.5 | 4 |
| + | 加算 | 5+2 | 7 | 5 |
| - | 減算 | 5-2 | 3 | 5 |
比較演算子
ベクトル内の要素を比較し、TRUEまたはFALSEを返します。
| 演算子 | 説明 | 例 | 結果 |
|---|---|---|---|
| > | 2つのベクトルの要素が大きいかを順に判断 | c(1,2,3)>c(0,2,4) | TRUE FALSE FALSE |
| < | 2つのベクトルの要素が小さいかを順に判断 | c(1,2,3)<c(0,2,4) | FALSE FALSE TRUE |
| == | 2つのベクトルの要素が等しいかを順に判断 | c(1,2,3)==c(0,2,4) | FALSE TRUE FALSE |
| != | 2つのベクトルの要素が等しくないかを順に判断 | c(1,2,3)!=c(0,2,4) | TRUE FALSE TRUE |
| >= | 2つのベクトルの要素が大きいか等しいかを順に判断 | c(1,2,3)>=c(0,2,4) | TRUE TRUE FALSE |
| <= | 2つのベクトルの要素が小さいか等しいかを順に判断 | c(1,2,3)<=c(0,2,4) | FALSE TRUE TRUE |
論理演算子
論理演算、0でない場合はTRUEです。
&&と||は4.2.1以降、ベクトルには適用されなくなりました。
| 演算子 | 説明 | 例 | 結果 |
|---|---|---|---|
| & | 論理積、両方がTRUEの場合のみTRUE | c(0,2)&c(1,-1) | FALSE TRUE |
| | | 論理和、いずれかがTRUEの場合はTRUE | c(0,2)|c(1,-1) | TRUE TRUE |
| ! | 論理否定、反転 | !c(0,2) | TRUE FALSE |
| && | 論理積、ベクトルの最初の要素のみ演算 | c(0,2)&&c(1,-1) | FALSE |
| || | 論理和、ベクトルの最初の要素のみ演算 | c(0,2)||c(1,-1) | TRUE |
代入演算子
=、<-、->に加えて、<<-と->>があり、後者は関数内でグローバル変数に代入できますが、変数名の衝突を避けるため、慎重に使用する必要があります。
その他の演算子
> v=c(1:10) # a:bベクトルを作成[a,a+1,...,b-1,b]
> v
[1] 1 2 3 4 5 6 7 8 9 10
> 6 %in% v # %in%ベクトル内に要素があるか判断
[1] TRUE
> 0 %in% v
[1] FALSE
条件分岐
if文
構文
if(条件式){
条件式がTRUEの場合に実行される文
}
例
if(3>2){
print("3は2より大きい")
}
# "3は2より大きい"を出力
if...else文
構文
if(条件式){
...
}else{
条件式がFALSEの場合に実行される文
}
if(条件式1){ #複数の条件判断を行うif...elseの使用方法
...
}else #条件式1がFALSEの場合、以下の判断を継続
if(条件式2){
...
}else #以前の条件式がすべてFALSEの場合、以下の判断を継続
if(条件式3){
...
}
例
GPA=4.0
if(GPA>4.5){ #条件を満たさないのでelseへ
print("素晴らしい")
}else
if(GPA>3.8){ #条件を満たすので文を実行
print("良好") #出力は"良好"
}else #以降の判断は不要
if(GPA>3.0){
print("まあまあ")
}else{
print("良くない")
}
switch文
構文
#最初のパラメータが整数の場合
switch(値,値1に対応する結果,値2に対応する結果,...,値nに対応する結果)
#最初のパラメータが文字列の場合
switch(文字列,変数名1=結果1,変数名2=結果2,...,変数名n=結果n)
例
> switch(3,"a","b","c","d") #3番目を返す
[1] "c"
> switch("c",a=1,b=2,c=3,c=4) #変数cに対応する値を返し、重複がある場合は最初のものを返す
[1] 3
ループ
ループの種類
repeatループ
構文
repeat{
...
if(ループを終了する条件){
break
}
}
例
count=1
repeat{
print(count)
count=count+1
if(count>5){
break
}
}
#5行出力、各行に1から5の整数
whileループ
構文
while(ループ条件){
...
}
例
count=1
while(count<=5){
print(count)
count=count+1
}
#5行出力、各行に1から5の整数
forループ
構文
for(ループ変数 in コレクション){
ループ本体
}
例
for(i in 1:5){
print(i)
}
#5行出力、各行に1から5の整数
ループ制御
break
機能
現在の最も内側のループから抜け出します。
例
for(i in 1:5){
if(i>3) break #i>3になったらループを終了
print(i)
}
#3行出力、各行に1から3の整数
next
機能
現在のループをスキップします。
例
for(i in 1:5){
if(i%%2==1) next #iが奇数ならスキップ
print(i)
}
#2と4のみを出力
関数
関数の定義
形式
関数名<-function(引数){
関数本体
return(戻り値)
}
例
gcd=function(x,y){ #xとyの最大公約数を返す関数
if(y) return(gcd(y,x%%y))
else return(x)
}
power=function(a,b){ #aのb乗を返す関数
result=1
while(b){
if(b%%2==1) result=result*a
a=a*a
b=b%/%2
}
return(result)
}
is_prime=function(x){ #xが素数かどうかを判断する関数
if(x<2){
return(FALSE)
}
if(x<4){
return(TRUE)
}
for(i in 2:floor(sqrt(x))){
if(x%%i==0){
return(FALSE)
}
}
return(TRUE)
}
関数の呼び出し
引数のない関数
f=function(){ #関数内でxを使用していない
return(114514)
}
print(f())
#関数本体を実行し、数字を出力
引数のある関数
#前セクションのpower関数を例に、aとbという2つの引数があり、aのb乗を返す
> power(3,5) #3,5を順番に入力すると、デフォルトでa=3、b=5となり、3の5乗を出力
[1] 243
> power(b=5,a=3) #引数名付きで関数を呼び出すこともでき、順序は任意
[1] 243
デフォルト値
関数定義時にデフォルト値を設定できます。これは引数を指定しない場合のデフォルト値です。
power=function(a=2,b){ #デフォルト値、a=2
result=1
while(b){
if(b%%2==1) result=result*a
a=a*a
b=b%/%2
}
return(result)
}
print(power(,2)) #aの値を指定しなくても、aはデフォルトで2となる
#出力は4
遅延評価
関数内で呼び出されない引数は、渡さなくても問題ありません。
f=function(x){ #引数xがあるが、関数内では使用していない
return(114514)
}
print(f()) #関数を呼び出す際に引数xの値を指定しなくても実行可能
ベクトルvector
C言語における一次元配列に相当します。
ベクトルの作成
> a=c(1,2) #c()関数でベクトルを作成
> b=c(10,20,30,40)
ベクトルの加減算
> a+b #長いベクトルが短いベクトルの長さの整数倍の場合のみ、加減算が可能
[1] 11 22 31 42 #短いベクトルが繰り返され、要素が順に加算される
ベクトル要素の取り出し
> a[1] #ベクトル内の単一要素を取り出す
[1] 1 #注意!他の言語と異なり、Rの添字は1から始まります
> b[2:4] #ベクトル内の連続した要素を取り出す
[1] 20 30 40
> b[c(1,3,4)] #ベクトルを使用してベクトルの複数要素を取り出すことも可能
[1] 10 30 40 #1,3,4番目の要素を取り出した
ベクトルのソート
| 関数 | 説明 |
|---|---|
| sort() | ソート |
| rev() | 逆順 |
| order() | 順位 |
> a=c(1,1,4,5,1,4)
> sort(a) #sort()関数でベクトルをソートし、デフォルトは昇順
[1] 1 1 1 4 4 5
> a
[1] 1 1 4 5 1 4 #しかしsortは元のベクトルを変更しない
> rev(a) #rev()でベクトルを逆順にする
[1] 4 1 5 4 1 1
> a #同様に元のベクトルを変更しない
[1] 1 1 4 5 1 4
> order(a) #order()はベクトルを返し、各要素のソート後の位置を表す。同じ要素は元の順序に従う
[1] 1 2 5 3 6 4
> a[order(a)] #order()のソート方法を利用
[1] 1 1 1 4 4 5
ベクトルの統計
| 関数 | 説明 |
|---|---|
| sum | 合計 |
| mean | 平均値 |
| var | 分散 |
| sd | 標準偏差 |
| min | 最小値 |
| max | 最大値 |
| range | 値の範囲 |
> a=c(1,1,4,5,1,4)
> sum(a) #合計
[1] 16
> mean(a) #平均値
[1] 2.666667
> var(a) #分散
[1] 3.466667
> sd(a) #標準偏差
[1] 1.861899
> min(a) #最小値
[1] 1
> max(a) #最大値
[1] 5
> range(a) #範囲、最小値と最大値を返す2次元ベクトル
[1] 1 5
その他のベクトル操作
| 関数 | 説明 |
|---|---|
| which | フィルタリング |
| all | すべてTRUEかどうかを判断 |
| any | TRUEが存在するかどうかを判断 |
> a=c(1,1,4,5,1,4)
> which(a>2 & a<5) #whichにベクトル要素のフィルタリング条件を追加
[1] 3 6 #ベクトル内で条件を満たす要素の添字を返す
> a[c(which(a>2 & a<5))] #この操作で条件を満たす要素を返す
[1] 4 4
> a>2 #ベクトルと要素で論理演算を行い、論理ベクトルを返す
[1] FALSE FALSE TRUE TRUE FALSE TRUE
> all(a>2) #すべてがTRUEかどうか
[1] FALSE
> any(a<5) #TRUEが存在するかどうか
[1] TRUE
文字列string
文字列の作成
単一引用符または二重引用符を使用して作成します。
単一引用符内には二重引用符を含めることができますが、エスケープなしの単一引用符は含めることができません。
二重引用符も同様です。
> 'abc'
[1] "abc"
> "123\'abc"
[1] "123'abc"
文字列関数
| 関数 | 説明 |
|---|---|
| toupper | 大文字に変換 |
| tolower | 小文字に変換 |
| nchar | 文字数をカウント |
| substr(s,begin,end) | 文字列sのbeginからendまでの部分文字列を抽出 |
| substring(s,begin\[,end\]) | 文字列sのbeginからendまでの部分文字列を抽出。endパラメータがない場合、デフォルトで末尾まで抽出 |
| as.numeric | 文字列を数値に変換 |
| as.character | 数値を文字列に変換 |
| strsplit(s,c) | cでsを分割 |
| gsub(a,b,s) | s内のすべてのaをbに置換 |
| paste | オブジェクトを連結し、文字列として出力 | パラメータ | 説明 | | sep | 文字列連結に使用する文字、デフォルトはスペース | | collapse | 要素を区切る文字 | |
| --- |
format文字列または数値をフォーマットし、文字列として出力
| パラメータ | 説明 |
|---|---|
| digits | 表示する数値の桁数。元の数値より多い場合は元の数値を表示 |
| nsmall | 小数点以下に表示する最小桁数 |
| scientific | パラメータがTRUEの場合は科学記数法を使用、デフォルトはFALSE |
| width | 出力文字列の長さ。必要な長さより短い場合は元の文字列を表示 |
| justify | 表示位置、lrcはそれぞれ左寄せ、右寄せ、中央寄せを示し、デフォルトはrで文字列にのみ有効 |
> toupper("123Abc")
[1] "123ABC"
> tolower("123Abc")
[1] "123abc"
> nchar("日本語") #文字数をカウント
[1] 3
> nchar("日本語",type="byte") #占有バイト数をカウント、1つの漢字は3バイト
[1] 9
> substr("123Abc",2,4)
[1] "23A"
> substring("123Abc",4)
[1] "Abc"
> as.numeric("114514")
[1] 114514
> as.character(114514)
[1] "114514"
> strsplit("11:45:14",":") #コロンで文字列を分割し、リストを返す、リストにはベクトルが含まれる
[[1]]
[1] "11" "45" "14"
> gsub(":"," ","11:45:14") #コロンをスペースに置換
[1] "11 45 14"
> paste("123","abc",sep=",") #オブジェクトが文字列の場合、sepを区切り文字として直接連結
[1] "123,abc"
> paste(1:3,11:15,sep=" ",collapse=",") #オブジェクトがベクトルの場合、まずsepで文字列を連結し、次にcollapseで区切る
[1] "1 11,2 12,3 13,1 14,2 15" #長さが異なる場合、短い方のベクトルが繰り返される
> format(1.23,digits=2)
[1] "1.2"
> format(1.23,digits=9)
[1] "1.23"
> format(1.23,scientific=TRUE)
[1] "1.23e+00"
> format(1.23,width=9)
[1] " 1.23"
> format("123456789",width=13,justify='c')
[1] " 123456789 "
> format(123456789,width=13,justify='c') #オブジェクトが数字の場合、justifyは無効で依然として右寄せ
[1] " 123456789"
行列matrix
他の言語における二次元配列に似ており、線形代数における行列演算をサポートします。
筆者がこの部分を執筆している時点では、線形代数を体系的に学習しておらず、いくつかの不備がある可能性があります。読者の皆様にはご容赦ください。
行列の作成
形式
matrix(data=NA,nrow=1,ncol=1,byrow=FALSE,dimnames=NULL)
| パラメータ | 意味 |
|---|---|
| data | リスト、行列内のすべての要素 |
| nrow | 行列の行数、デフォルトは1 |
| ncol | 行列の列数、デフォルトは1 |
| byrow | TRUEの場合、データを行で埋める。デフォルトは列で埋める |
| dimnames | 2つのベクトルを含むリスト、各ベクトルは変更後の行/列の名前を表す |
例
> matrix(1:6,3,2) #3行2列の行列、要素は1から6。デフォルトでは列で埋められていることがわかる
[,1] [,2]
[1,] 1 4
[2,] 2 5
[3,] 3 6
> matrix(1:6,3,2,byrow=TRUE) #byrowパラメータを設定すると行で埋める
[,1] [,2]
[1,] 1 2
[2,] 3 4
[3,] 5 6
> matrix(1:6,3,2,dimnames=list(c("第一行","第二行","第三行"),c("第一列","第二列")))
第一列 第二列
第一行 1 4
第二行 2 5
第三行 3 6 #各行各列の名前を変更
その他の作成方法
> matrix(1,3,4) #dataに値を1つだけ指定すると、作成される行列のすべての要素がその値になる
[,1] [,2] [,3] [,4]
[1,] 1 1 1 1
[2,] 1 1 1 1
[3,] 1 1 1 1
行列のスライシング
> t=matrix(1:12,4,3) #4行3列の行列を作成、要素は1から12
> t[3,] #3行目の要素を抽出
[1] 3 7 11
> t[,2] #2列目の要素を抽出
[1] 5 6 7 8
> t[3,2] #3行2列の要素を抽出
[1] 7
> t[2,-3] #2行目から3列目以外の要素を抽出
[1] 2 6
> t[-1,1] #1行目を除く1列目の要素を抽出
[1] 2 3 4
> t[-2,-2] #2行目と2列目を除く要素を抽出
[,1] [,2]
[1,] 1 9
[2,] 3 11
[3,] 4 12
行列演算
全体的に、R言語における行列演算のルールは数学における行列演算に準拠しています。
行列の加減算
行数、列数、要素タイプが同じ行列は加減算できます。
> A=matrix(1:12,4,3) #4行3列、1から12の行列
> B=matrix(13:24,4,3) #4行3列、13から24の行列
> A+B #行列の加算
[,1] [,2] [,3]
[1,] 14 22 30
[2,] 16 24 32
[3,] 18 26 34
[4,] 20 28 36
> A-B #行列の減算
[,1] [,2] [,3]
[1,] -12 -12 -12
[2,] -12 -12 -12
[3,] -12 -12 -12
[4,] -12 -12 -12
行列のスカラー乗算
行列にスカラーを乗算すると、新しい行列が生成され、各要素は元の行列のその位置の値にスカラーを乗算したものになります。
> A=matrix(1:3,1,3)
> A*3 #乗算
[,1] [,2] [,3]
[1,] 3 6 9
> A/2 #除算も同様
[,1] [,2] [,3]
[1,] 0.5 1 1.5
行列の乗除算
最初の行列の列数が2番目の行列の行数に等しい場合に限り、これら2つの行列は乗算できます。
R言語では、行列乗算の記号は%*%です。
行列乗算は交換則を満たしません。
> A=matrix(1:3,nrow=1,3) #行列Aは1行3列
> A
[,1] [,2] [,3]
[1,] 1 2 3
> B=matrix(1:3,3,1) #行列Bは3行1列
> B
[,1]
[1,] 1
[2,] 2
[3,] 3
> A%*%B
[,1]
[1,] 14
行列のその他の操作
行列の転置
> m=matrix(1:6,3,2)
> t(m) #t()は行列の転置行列を出力
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6