R(3)リスト
R におけるリストは,独自の index `$` を持った構造体であり,Python の dictionary, Perl の hash table に似ている.`$` は S3 の機能で,S4 は `@` である.これはリストが本質的に R の実装の深いところに存在するデータ型だからである.
司馬博文
5/07/2021
6/05/2024
A Blog Entry on Bayesian Computation by an Applied Mathematician
$$
$$
データ型 logical
, integer
, double
, complex
, character
, raw
は全てベクトルと理解される.1 逆に,全てのベクトルはこの6つのいずれかの atomic data type を持つ.2
4.2
, four point two
はいずれもデータ型こそ違えど長さ1のベクトルである.
全てはベクトルで,行列も配列もリストも,それに特殊な属性を付与したもの.
dim
属性を持つベクトルのことである.各次元に名前がつくとdimnames
属性も持つ.
リストは各要素のデータ型が異なっていても良く,“generic vector” というべきものである.
ベクトルは基本横で[1]
という行の名前の後に表示される,行列はそのdim
属性のために基本縦で[,1]
と indexing される.indexing の表示の違いでクラスの違いがわかる.
まずベクトルの時点で定義される演算を紹介し,インデックスを紹介する.全てのオブジェクトはベクトルなので,ベクトルをベクトルでインデックスするという奇怪な状況が発生する.また R では演算のほとんどがベクトル化されていて,これを使いこなすことが高速化の最初の手法になる. 次に行列を定義し,行列特有の演算を見る.
スカラーなどの概念はない,全てはベクトル. 文字列も,character
modeの長さ1ベクトル.
c(arg1,arg2,...)
を用いる.実は浮動小数点モードを生成する.
a:b
:a<b
ならば増加,a>b
ならば減少の,step=1
のベクトルの生成.実は整数モードを生成する.seq(from=1,to=1,by=((to - from)/(length.out - 1)))
1:0
は[1] 1 0
を返すので安全でない.seq(NULL)
はNULL
を返すので安全.rep(y,times=n,each,length.out)
times
:=3
でn
回繰り返す.each
:=3
とすると各要素を3回繰り返す.length.out
:=3
とすると出力の長さを制限y[2]
という書き方は禁忌).y <- vector(length=n)
としてポインタを作ってから,y[1]<-5
などと代入していく.
ret <- vector(length=n)
とした方がいい.返す前にret <- ret[1:n]
として未使用部分を無くすために再割り当てをして2回で済ませるのがいい.rev(x)
:反転t(x)
:転置head(x[, n=6L])
tail(x[, n=6L])
names
属性を付与できるが,リストにはならない.
names(x) <-
:colnames か rownames か,どちらか適切な方.names(x) <- NULL
:削除.length(x)
mean(a, na.rm=F)
:算術平均.na.rm=T
でNA
があっても適用可能になる.sum(a)
:総和prod(a)
:総積max(a)
:sd(x)
:standard deviationall(expr)
:expr の結果である logical vector が,全てT
かどうかを判定して長さ1ベクトルを返すany(expr)
:expr の結果である logical vector が,T
が存在するかを判定して長さ1ベクトルを返す:
,c
,seq
に対応した indexing 法がある.y[c(1,3,4)]
:scaler は退化したベクトルなのでこれがあるべき姿y[-c(1,3,4)]
:除外は負数を用いる.y[-length(y)]
は最後の要素の除外.y[-1:-2]
は1,2番目の除外.tail(x,[n=]1)
:右後ろから indexinga+b
, a-b
a*b
:Hadamard積,a/b
a %*% b
:内積%o%
:外積%/%
:整数除算a^b
:冪で,**
でも実行できるが非推奨.%%
:mod.情報落ちを検出したら警告が出るようになっている.paste(“str1”, “str2”)
:concatenation
strsplit(x, split, fixed = FALSE, perl = FALSE, useBytes = FALSE)
ベクトルは C の配列のように,連続的に格納されているので,要素の挿入や削除は新しく作るのと等価.実装は C の pointer と同じで,再代入はポインタの指す先を変えることで再割り当てを実現する.
dim
属性(ncol
とnrow
)のついたベクトルで,縦に並んだベクトルをdim
属性を参照しながら横にずらしながら構成される.
dim
属性を付与するコンストラクタmatrix([data=]a,[nrow=]m,[ncol=]n)
a
が scaler の場合m×n
を a
-fill する,a
がベクトルの場合m×n
に fill していく.byrow=TRUE
とすると行ごとになる.as.vector(A)
rbind(a,b,c)
:行ベクトルとして結合,あるいは行列の横結合.cbind(a,b,c)
:列ベクトルとして結合,あるいは行列の縦結合.dim(x) <- c(n,m)
:ベクトルに次元のデータを加えて,行列に変換する.matrix(nrow=a,ncol=b)
でなされる.rownames(), colnames() <- name
:名前をつけられる.t(A)
:転置dim(A)
:返り値は長さ2のベクトルnrow(A)=dim(A)[1]
ncol(A)=dim(A)[2]
A[行,列]
:空欄を渡すと走る,長さ2以上のベクトルを渡すと複数選択
[,2]
などでも行ベクトルで帰ってくる.これは全てのベクトルは横で表示されるから.[n]
だと,列を繋げた順序についての indexing で,要素が返ってくる.norm(A [,type=c(“o”, ”I”, ”F”, ”M”, ”2”)])
2
はspectral norm.sqrt(a %*% a)::matrix
でいけるdet(A)
sum(diag(A))
:\(\operatorname{Tr}\)同次元演算
A+B
, A-B
A*B
, A/B
:Hadamard積A %*% B
:行列積逆行列solve(A)
一般化逆行列 (Moore-Penrose pseudoinverse)
行列はベクトルなので,ほとんどの関数はベクトルだと思って作用する.属性を外してベクトルと見て演算して,属性を戻すとかそういう感じ.
diag(x)
:引数がベクトルなら対角行列の作成.diag(rep(1,n))=En
.行列ならベクトルを返す.*
:scaler と行列ならば普段の積.%*%
ではエラーになる.%*%
:これは数学でも generic よね.
xA=行ベクトル
,Ax=列ベクトル
と返り値が定まり,x
の縦横に依らない.solve(A,B)
:B
がベクトル \(b\) の時,\(Ax=b\) を解く.行列のときは \(AX=B\) を解く.
B
を省略すると対角行列とみなされ,したがって解は \(X=A^{-1}\)sin()
, exp()
, abs()
, sqrt()
, log()
, log10()
, acos()
, sinpi()
1:10*2
は(1:10)*2
だが,1:10^2
は1:100
log([x=]b,[base=exp(1)])
acos
:逆三角関数sinpi(3/2)
:sin(pi*3/2)
に同じround()
, floor()
, ceiling()
factorial()
x>3
などの評価:条件評価も実際は関数.
3
が recycle されてx
と同じ長さになる.pmax()
cumsum()
, cumprod()
sapply(x,f)
f
をx
の各要素に適用し,返り値を行列とする.f
がベクトルの長さを伸ばすような関数だった場合,行列化処理と合成するのが自然で,これを勝手にやってくれる.\(n\) 次元リストで,一番一般的なデータ構造.
array(data=NA, dim=length(data), dimnames=NULL)
dim=c(3,4,2)
などができる.dimnames
はもともと数字で,,,1
という調子で切り出して表示される(list みたいな)