第2講 - R言語で扱うデータとその演算
(Press ?
for help, n
and p
for next and previous slide)
村田 昇
tibble, data.table
など)zoo, xts
など)TRUE
, FALSE
)数値や文字列の要素からなるベクトルの生成
(x <- c("Alice","Bob","Cathy","David")) # 文字列のベクトル
(y <- c(1,-2, 3,-4, 5)) # 数値のベクトル
(z <- c("apple","berry","cat","dog","elephant")) # 文字列のベクトル
#' 外側の () は代入した結果の表示.print() と同義
[1] "Alice" "Bob" "Cathy" "David" [1] 1 -2 3 -4 5 [1] "apple" "berry" "cat" "dog" "elephant"
a
から b
まで
1ずつ変化するベクトル (演算子 :
)
a <- 8; b <- 15 # 変数 a,b に値を代入.複数コマンドは ; で区切る
a:b # a < b の場合は1ずつ増加する系列が作成される
a <- 29.5; b <- 24
a:b # 逆の場合は1ずつ減少する系列が作成される
29.5:24 # 直接数値を書いてもよい
[1] 8 9 10 11 12 13 14 15 [1] 29.5 28.5 27.5 26.5 25.5 24.5 [1] 29.5 28.5 27.5 26.5 25.5 24.5
a
から b
まで
c
ずつ変化するベクトル (関数 seq()
)
a <- 1; b <- 16; c <- 2 # 変数 a,b,c に値を代入
seq(a, b, by = c) # 明示する場合は seq(from = a, to = b, by = c)
[1] 1 3 5 7 9 11 13 15
ベクトルの長さの取得 (関数 length()
)
length(x) # 最後の要素を参照する場合などに利用できる
[1] 4
ベクトルの要素の取得 (演算子 []
)
x[3] # xの第3要素 (ベクトルの添え字は1から始まる)
y[c(1,3,4)] # 複数の要素 = c(y[1], y[3], y[4])
[1] "Cathy" [1] 1 3 -4
ベクトルの反転 (関数 rev()
)
rev(x)
[1] "David" "Cathy" "Bob" "Alice"
ベクトルの結合 (関数 c()
)
c(x, z) # 同じデータ型のものは単純に結合される
c(x, y) # 異なるデータ型のものは結合できないので自動的に書き換えられる
[1] "Alice" "Bob" "Cathy" "David" "apple" "berry" "cat" [8] "dog" "elephant" [1] "Alice" "Bob" "Cathy" "David" "1" "-2" "3" "-4" "5"
ベクトルの繰り返し (関数 rep()
)
rep(y, 3) # 長さは length(y) * 3
rep(y, times = 3) # 単純に繰り返す.上記と同様
rep(y, each = 3) # 各要素を繰り返す
rep(y, length.out = 12) # 繰り返した結果の長さを指定する
[1] 1 -2 3 -4 5 1 -2 3 -4 5 1 -2 3 -4 5 [1] 1 -2 3 -4 5 1 -2 3 -4 5 1 -2 3 -4 5 [1] 1 1 1 -2 -2 -2 3 3 3 -4 -4 -4 5 5 5 [1] 1 -2 3 -4 5 1 -2 3 -4 5 1 -2
すべての要素が a
である \(m\times n\) 型行列の生成
(関数 matrix()
)
a <- 2; m <- 3; n <- 4 # 変数 a,m,n に値を代入
matrix(a, m, n) # 明示する場合は matrix(data = a, nrow = m, ncol = n)
[,1] [,2] [,3] [,4] [1,] 2 2 2 2 [2,] 2 2 2 2 [3,] 2 2 2 2
長さ \(mn\) のベクトル a
を \(m\times n\) 型行列に変換
(関数 matrix()
)
a <- 2:13 # 変数 a に値を代入 (m*n = 12 文字用意)
(A <- matrix(a, m, n)) # 並び順を変えるには matrix(a,m,n,byrow = TRUE)
[,1] [,2] [,3] [,4] [1,] 2 5 8 11 [2,] 3 6 9 12 [3,] 4 7 10 13
行列のベクトル化 (関数 as.vector()
)
as.vector(A) # matrix の逆変換にあたる
[1] 2 3 4 5 6 7 8 9 10 11 12 13
長さが等しい複数のベクトルの結合
(関数 rbind(),cbind()
)
a <- 4:7; b <- 10:7; c <- c(2,4,8,16) # 変数 a,b,c に値を代入
rbind(a, b, c) # 行ベクトルとして結合 (row vector bind)
cbind(a, b, c) # 列ベクトルとして結合 (column vector bind)
[,1] [,2] [,3] [,4] a 4 5 6 7 b 10 9 8 7 c 2 4 8 16 a b c [1,] 4 10 2 [2,] 5 9 4 [3,] 6 8 8 [4,] 7 7 16
行列のサイズの取得 (関数 dim()
とその仲間)
dim(A) # 関数の返値は長さ2のベクトル (行数,列数) となることに注意
nrow(A) # 行数
ncol(A) # 列数
dim(A)[1] # nrow(A) と同値
dim(A)[2] # ncol(A) と同値
[1] 3 4 [1] 3 [1] 4 [1] 3 [1] 4
行列の成分の取得 (演算子 []
)
A[3,4] # (3,4)成分
A[3, ] # 第3行のベクトル
A[ ,4] # 第4列のベクトル
A[c(1,3),] # 1,3行からなる部分行列.2x4型行列になる
A[c(1,3),2:4] # 1,3行と,2,3,4列からなる部分行列.2x3型行列になる
[1] 13 [1] 4 7 10 13 [1] 11 12 13 [,1] [,2] [,3] [,4] [1,] 2 5 8 11 [2,] 4 7 10 13 [,1] [,2] [,3] [1,] 5 8 11 [2,] 7 10 13
cbind()/rbind()
は行数・列数が等しい行列も横・縦に結合できるrownames()/colnames()
を用いると行と列に名前を付けることができる以下に示す行列を作成してみよう
リストの生成 (関数 list()
)
(L <- list(x,y)) # x,yを要素とするリスト
[[1]] [1] "Alice" "Bob" "Cathy" "David" [[2]] [1] 1 -2 3 -4 5
リストの要素の参照 (演算子 [[]]
)
L[[1]] # リストの第1要素
[1] "Alice" "Bob" "Cathy" "David"
リストの各要素に名前を付与 (関数 names()
)
#' 方法1 (作成時に名前を付与)
(L1 <- list(first=x, second=y))
$first [1] "Alice" "Bob" "Cathy" "David" $second [1] 1 -2 3 -4 5
#' 方法2 (作成後に名前を変更)
L2 <- list(x,y)
names(L2) <- c("1st","2nd")
L2 # リストを表示
$`1st` [1] "Alice" "Bob" "Cathy" "David" $`2nd` [1] 1 -2 3 -4 5
名前によるリストの要素の取得 (演算子 [[]],$
)
#' 方法1 (リストの名前で参照)
L1[["first"]]
L2[["2nd"]]
[1] "Alice" "Bob" "Cathy" "David" [1] 1 -2 3 -4 5
#' 方法2 (記号$を用いる場合は""は不要なことに注意)
L1$first
L2$`2nd` # 数字で始まる文字列は``を用いる必要がある
[1] "Alice" "Bob" "Cathy" "David" [1] 1 -2 3 -4 5
データフレームの生成 (関数 data.frame()
)
#' 前回の練習問題
library(tibble)
(foo <-
tibble(
name = c("Alice", "Bob", "Carol", "Dave", "Eve"),
math = c(90, 80, 70, 60, 50),
phys = c(25, 50, 75,100, 80),
chem = c(65,100, 70, 40, 75),
bio = c(70, 50, 30, 80,100)))
ベクトルは太字,要素は下付き添字で表す
\begin{equation} \boldsymbol{a} =(a_{1},a_{2},\dotsc,a_{k}) \end{equation}
別の書き方
\begin{equation} (\boldsymbol{a})_{i} =\text{(ベクトル \(\boldsymbol{a}\) の第 \(i\) 成分)} \end{equation}
Rの書式 (関数 c()
)
a <- c(a1,a2,...,ak) # k次元ベクトルの作成 (擬似コード)
同じ長さのベクトル の和および差
\begin{equation} \boldsymbol{a}\pm\boldsymbol{b} =(a_{1}\pm b_{1},a_{2}\pm b_{2},\dotsc,a_{k}\pm b_{k}) \end{equation}\begin{equation} (\boldsymbol{a}\pm\boldsymbol{b})_{i} =a_{i}\pm b_{i} \end{equation}
Rの書式 (演算子 +,-
)
a + b # 同じ長さのベクトル a,b の和.同じ長さのベクトルが返る
a - b # ベクトルの差
同じ長さの2つのベクトル の乗法
2種類あることに注意する
同じ長さのベクトル の成分ごとの積
\begin{equation} \boldsymbol{a}\circ\boldsymbol{b} =(a_{1}b_{1},a_{2}b_{2},\dotsc,a_{k}b_{k}) \end{equation}\begin{equation} (\boldsymbol{a}\circ\boldsymbol{b})_{i} =a_{i}b_{i} \end{equation}
Rの書式 (演算子 *,/
)
a * b # ベクトルの成分ごとの積.同じ長さのベクトルが返る
a / b # 成分ごとの商も計算可
同じ長さのベクトル の内積
\begin{align} \boldsymbol{a}\cdot\boldsymbol{b} &=a_{1}b_{1}+a_{2}b_{2}+\dotsb+a_{k}b_{k}\\ &=\sum_{i=1}^{k}a_{i}b_{i} \end{align}
Rの書式 (演算子 %*%
)
a %*% b # ベクトルの内積.1x1型の行列が返る
行列は大文字,要素は下付き添字で表す
\begin{equation} A = \begin{pmatrix} a_{11}&\dots&a_{1n}\\ \vdots&\ddots&\vdots\\ a_{m1}&\dots&a_{mn} \end{pmatrix} % \begin{pmatrix} % a_{11}&a_{12}&\dots&a_{1n}\\ % a_{21}&a_{22}&\dots&a_{2n}\\ % \vdots&&\ddots&\vdots\\ % a_{m1}&a_{m2}&\dots&a_{mn} % \end{pmatrix} \end{equation}
別の書き方
\begin{equation} (A)_{ij} =\text{(行列 \(A\) の \(ij\) 成分)} \end{equation}
Rの書式 (関数 matrix()
)
A <- matrix(c(a11,a21,...,amn), m, n) # m x n 型行列の作成 (擬似コード)
同じ大きさの行列 の和および差
\begin{equation} (A\pm B)_{ij}=a_{ij}\pm b_{ij} \end{equation}
Rの書式
A + B # 同じサイズの行列の和.同じサイズの行列が返る
A - B # 行列の差
2つの行列の乗法
2種類あることに注意する
同じ大きさの行列 の成分ごとの積
\begin{equation} (A\circ B)_{ij}=a_{ij}b_{ij} \end{equation}
Rの書式 (演算子 *,/
)
A * B # 行列の成分ごとの積.同じサイズの行列が返る
A / B # 成分ごとの商も計算可
\(n\times m\) 型行列 \(A\) と \(m\times l\) 型行列 \(B\) の積
\begin{equation} (AB)_{ij}=\sum_{k=1}^{m}a_{ik}b_{kj} \quad\text{(\(AB\)は\(n\times l\)行列)} \end{equation}
Rの書式 (演算子 %*%
)
A %*% B # 行列の積.n x l 型行列が返る
\(n\) 次正方行列 \(A\) の行列式
\begin{equation} \det(A)\quad (=|A|) \end{equation}
Rの書式 (関数 det()
)
det(A) # 行列式
\(n\) 次正方行列 \(A\) のトレース(対角成分の総和)
\begin{equation} \mathrm{trace}(A)=\sum_{i=1}^{n}a_{ii} \end{equation}
Rの書式 (関数は用意されていないので以下を利用)
sum(diag(A)) # 行列のトレース
diag()
: 行列の対角成分を取り出す sum()
: ベクトルの総和を計算する適当な2次正方行列 \(A\) で Hamilton-Cayley の定理
\begin{equation} A^2-\mathrm{trace}(A)A+\det(A)E_{2}=O_{2} \end{equation}
の成立を確認せよ. ただし \(E_{2}\) は2次単位行列,\(O_{2}\) は2次正方零行列とする.
解答例
#' 行列を作成 (好きに設定してよい)
(A <- matrix(1:4,2,2) - diag(rep(3,2)))
#' 左辺を計算 (丸め誤差の範囲で0になる)
A %*% A - sum(diag(A)) * A + det(A) * diag(rep(1,2))
[,1] [,2] [1,] -2 3 [2,] 2 1 [,1] [,2] [1,] 1.776357e-15 0.000000e+00 [2,] 0.000000e+00 1.776357e-15
30度の回転行列を2回乗ずると60度の回転行列となることを確認せよ
\begin{equation} \text{(回転行列)} = \begin{pmatrix} \cos(\theta)&-\sin(\theta)\\ \sin(\theta)& \cos(\theta) \end{pmatrix} \end{equation}
演算子 %*%
を用いて計算する
%*%
による計算結果は 行列 で表現されるA <- matrix(1:4, 2, 2); b <- c(5,6) # 行列とベクトルを作成
A %*% b # 行列 x ベクトル = 列ベクトル
[,1] [1,] 23 [2,] 34
b %*% A # ベクトル x 行列 = 行ベクトル
[,1] [,2] [1,] 17 39
連立1次方程式
\begin{align} A\boldsymbol{x}&=\boldsymbol{b} &&\text{(連立1次方程式)}\\ \boldsymbol{x}&=A^{-1}\boldsymbol{b} &&\text{(\(A\)が正則な場合)} \end{align}
解を求めるには関数 solve()
を利用する
x <- solve(A, b)
正則な \(n\) 次正方行列 \(A\) の逆行列 \(A^{-1}\)
\begin{equation} AA^{-1}=A^{-1}A=E_{n} \quad\text{(\(E_{n}\)は\(n\)次単位行列)} \end{equation}
関数 solve()
を利用して求めることができる
\begin{equation} AX = E_{n},\quad X = A^{-1}E_{n} = A^{-1} \end{equation}
solve(A,B) # AX=B の解Xを求める
solve(A) # 逆行列 (Bが単位行列の場合省略できる)
ベクトル \(\boldsymbol{a}\) ,行列 \(A\) に関数 \(\sin\) を適用する
\begin{equation} (\sin(\boldsymbol{a}))_{i}=\sin(a_{i}) \end{equation}\begin{equation} (\sin(A))_{ij}=\sin(a_{ij}) \end{equation}
sin(a) # 成分ごとに計算される.sin(a)[i]=sin(a[i])
sin(A) # 成分ごとに計算される.sin(A)[i,j]=sin(A[i,j])
適当な3次正方行列 \(A\) と3次元ベクトル \(\boldsymbol{b}\) を作成して \(\boldsymbol{x}\) に関する以下の連立1次方程式を解きなさい
\begin{equation} A\boldsymbol{x}=\boldsymbol{b} \end{equation}
解答例
(A <- matrix(rnorm(9), 3, 3) + diag(rep(1, 3))) # 行列とベクトルを作成
#' rnorm(9) は正規乱数を9つ作成する(後の講義で詳しく説明)
(b <- 1:3)
[,1] [,2] [,3] [1,] 0.6429563 1.40193984 -0.4057059 [2,] 1.2608802 0.58336097 -0.4595474 [3,] -1.0615962 -0.03945595 1.2033202 [1] 1 2 3
(x <- solve(A, b)) # 解を計算
A %*% x # 結果の確認(b になるはず)
[1] 3.1435966 0.8032596 5.2927920 [,1] [1,] 1 [2,] 2 [3,] 3
例題の \(A\) と \(\boldsymbol{b}\) を用いて 以下を計算するとエラーになる
A %*% b + b %*% A
何故そうなるか理由を考えよ