---
title: "統計データ解析I"
subtitle: "第2講 練習問題 解答例"
date: "`r Sys.time()`"
format:
    html: 
      toc: true
      html-math-method: katex
      self-contained: true
      grid: 
        margin-width: 350px
execute: 
  echo: true
  warning: false
reference-location: margin
citation-location: margin
tbl-cap-location: margin
fig-cap-location: margin
editor: visual
editor_options: 
  chunk_output_type: console
---

## ベクトルの操作

### 問題

以下に示すベクトルを作成しなさい．

-   1から10までの自然数のベクトル
-   1以上30以下の奇数を昇順に並べたベクトル
-   すべての要素が1からなる長さ10のベクトル

作成したベクトルを操作しなさい．

-   ベクトルの長さを求める．
-   3番目の要素を取り出す．
-   最後の要素を取り出す．

### 解答例

1から10までの自然数のベクトルを作成する．

```{r}
(foo <- 1:10) # () は表示．"foo <- 1:10; print(foo)" と等価
```

1以上30以下の奇数を昇順に並べたベクトルを作成する．

```{r}
(bar <- seq(from = 1, to = 30, by = 2)) # 変数名を含めた丁寧な書き方
```

すべての要素が1からなる長さ10のベクトルを作成する．

```{r}
(baz <- rep(1, length.out = 10)) # 関数rep_len() を用いても良い
rep(1, len = 10)                 # 変数名は見分けられれば短くてもOK
```

ベクトルの長さを求める．

```{r}
length(foo)
```

3番目の要素を取り出す．

```{r}
bar[3]
```

最後の要素を取り出す．

```{r}
bar[length(bar)] # 長さを用いて最後の要素番号を指定すれば良い
tail(bar, n = 1) # 関数tail() を用いる方法もある
```

::: callout-note
関数 rep() や関数 seq() には高速化された派生型がいくつかあるので調べてみよ．
:::

## 行列の操作

### 問題

以下に示す行列を作成しなさい．

$$
  \begin{equation}
    M = 
    \begin{pmatrix}
      1  & 2  & 3  \\
      4  & 5  & 6 
    \end{pmatrix}
  \end{equation}
$$

行列を操作しなさい．

-   2行2列成分を取り出す．
-   転置行列を作成する．
-   行名をつける．

## 解答例

行列を作成する．

```{r}
(M <- matrix(1:6, 2, 3, byrow = TRUE))
(M2 <- rbind(1:3, 4:6))                # cbind を使って作ることもできる
```

2行2列成分を取り出す．

```{r}
M[2,2]
```

転置行列を作成する．

```{r}
matrix(1:6, 3, 2)  # 愚直に作成し直す
t(M)               # 関数t()を調べてみよ
```

行名をつける．

```{r}
rownames(M) <- c("first","second")
M                                  # print(M) と同義
```

列名をつけることもできる．

```{r}
colnames(M2) <- c("alpha","beta","gamma")
M2
```

## ベクトルと行列の計算

### 問題

以下の問いに答えなさい．

-   1から10の2乗値からなるベクトルを作成せよ．
-   1から10までの和を計算せよ．
-   行列を用いて九九の表を作成せよ．
-   30度の回転行列を2回乗ずると60度の回転行列となることを確認せよ． $$
    \begin{equation}
      \text{(回転行列)}
      =
      \begin{pmatrix}
        \cos(\theta)&-\sin(\theta)\\
        \sin(\theta)& \cos(\theta)
      \end{pmatrix}
    \end{equation}
    $$

## 解答例

1から10までの2乗値からなるベクトルを作成する．

```{r}
1:10        # 1から10までのベクトル
1:10 * 1:10 # Hadamard積を利用する
```

1から10までの和を計算する．

```{r}
1:10 %*% rep(1, 10) # (1,2,...,10)と(1,1,...,1)の内積
sum(1:10)           # 関数sum()はベクトルの成分の合計を計算することもできる
```

九九の表を作成する．

```{r}
matrix(rep(1:9, 9), 9, 9) # 行ごとに1から9を並べる
matrix(rep(1:9, 9), 9, 9, byrow = TRUE) # 列ごとに1から9を並べる
matrix(rep(1:9, 9), 9, 9) * matrix(rep(1:9, 9), 9, 9, byrow = TRUE)
#' 行列とその転置を利用してもよい
(M <- matrix(rep(1:9, 9), 9, 9)) # 9x9型行列の積による方法
M * t(M) 
(M9 <- matrix(1:9,9,1))          # 9x1型行列の積による別の方法
M9 %*% t(M9) 
(V9 <- 1:9); V9 %o% V9           # 講義の範囲外の方法 (%o% はベクトルの積の一つ)
```

30度の回転行列の2乗は60度の回転行列であることを確かめる．

```{r}
theta <- pi/6  # 30度のラジアン値
(R30 <-        # 30度の回転行列
     matrix(c(cos(theta),-sin(theta),
              sin(theta), cos(theta)), 2, 2, byrow = TRUE))
(R60 <-        # 60度の回転行列
     matrix(c(cos(2*theta),-sin(2*theta),
              sin(2*theta), cos(2*theta)), 2, 2, byrow = TRUE))
R30 %*% R30    # 30度の回転行列の2乗を表示
```

### 問題

以下の問いに答えなさい．

-   1から10の2乗値からなるベクトルを作成せよ．

-   例題の $A$ と $\boldsymbol{b}$ を用いて 以下を計算するとエラーになる．

    ``` r
      A %*% b + b %*% A   
    ```

    何故そうなるか理由を考えよ．

-   適当な2次元ベクトルを用いて，2次元ベクトルが回転行列で変換しても長さが変わらないことを確かめよ．

## 解答例

1から10までの2乗値からなるベクトルを作成する．

```{r}
(1:10)^2 # ^2も関数として成分ごとに計算される
```

例題と同様に $A$ と $\boldsymbol{b}$ を作成する．

```{r}
(A <- matrix(rnorm(9), 3, 3) + diag(rep(1, 3)))
(b <- 1:3)
```

エラーになる理由を考察する．

```{r}
#| error: true
A %*% b           # 列ベクトル (3x1型行列)
b %*% A           # 行ベクトル (1x3型行列)
A %*% b + b %*% A # 異なる次元(大きさ)の行列は足し算できない
```

::: callout-tip
計算途中でエラーが生じても，出力を停めないようにするには 以下の chunk option を指定すれば良い(ソースコードを参照)．

``` r
#| error: true
```
:::

回転してもベクトルの長さが変わらないことを確認する．

```{r}
#' 回転行列とベクトルを作成する (好きに設定してよい)
theta <- 2*pi/3 # 120度のラジアン値
(R <- matrix(c(cos(theta),-sin(theta),
               sin(theta), cos(theta)), 2, 2, byrow = TRUE))
(x <- 1:2)
(y <- R %*% x) # xを回転してyを作成 (結果は行列になるので扱いに注意が必要)
#' 長さを確認する
x %*% x                       # xの長さの2乗はベクトルの内積で計算できる
as.vector(y) %*% as.vector(y) # yの長さの2乗 (ベクトルに変換して計算)
t(y) %*% y                    # 行列の積として計算することもできる
sum(y*y)                      # 行列の要素積を計算して全ての成分の和を計算
sum(y^2)                      # 上記は各成分の2乗和として計算することも可能(xも同様)
```
