スタートページJavaScript他言語R言語>    →基本記述規則

配列の操作

・配列(ベクトル・行列・データフレーム)の生成
・配列の部分指定
・ベクトル・行列・データフレームの相互変換
・配列間の演算

               
Rでは、スカラーも1x1のベクトルになっています。
一次元配列 ベクトル
  v     ベクトル 行(横)ベクトル
二次元配列 行列
  m     ベクトルからの行列
  df    データフレーム  列名あり、列(縦)ベクトルの集合 
                列ベクトルは数値と文字列は混在しない
この他に list 構造がありますが、ここでは省略します。

● Rでは、要素番号は(0ではなく)1から始まります。

配列の生成

matrixの生成

# 直接入力 一般式 m <- matrix(数値列, nrow=列数,  byrow=T)

# 行順入力
    m <- matrix(c(11,12,13,  21,22,23), nrow=2, byrow=T)  #        [,1] [,2] [,3] 
                                                          #  [1,]   11   12   13
                                                          #  [2,]   21   22   23
# 列順入力
    m <- matrix(c(11,12,13,  21,22,23), nrow=3, byrow=F)  #        [,1] [,2]
                                                          #  [1,]   11   21
                                                          #  [2,]   12   22
                                                          #  [3,]   13   23
# ベクトルの結合による生成
    v1 <- c(11, 12, 13)
    v2 <- c(21, 22, 23)
# 行順
    m <- matrix(c(v1, v2), nrow=2, byrow=T)   #        [,1] [,2] [,3] 
                                              #  [1,]   11   12   13
                                              #  [2,]   21   22   23
# 列順
    m <- matrix(c(v1, v2), nrow=3, byrow=F)   #        [,1] [,2]
                                              #  [1,]   11   21
                                              #  [2,]   12   22
                                              #  [3,]   13   23

rbind/cbind によるベクトル結合による生成

    v1 <- c(11, 12, 13)
    v2 <- c(21, 22, 23)
# 行結合
    m <- rbind(v1, v2)                        #        [,1] [,2] [,3] 
                                              #  [1,]   11   12   13
                                              #  [2,]   21   22   23
# 列結合
    m <- cbind(v1, v2)                        #        [,1] [,2]
                                              #  [1,]   11   21
                                              #  [2,]   12   22
                                              #  [3,]   13   23

特殊行列の生成

# ゼロ行列
    matrix(0, nrow=2, ncol=3)                 #        [,1] [,2] [,3] 
                                              #  [1,]   0    0    0
                                              #  [2,]   0    0    0

# 単位行列 diag(n)
   diag(3)                                    #        [,1] [,2] [,3] 
                                              #  [1,]   1    0    0
                                              #  [2,]   0    1    0
                                              #  [3,]   0    0    1

df の生成


# 直接入力 一般形: data.frame(列名1 = ベクトル1, 列名2 = ベクトル2, ... )

    df <- data.frame(                         #      c1  c2  c3 ← 列名
              c1 = c(11, 21, 31, 41),         #   1  11  12  13
              c2 = c(12, 22, 32, 42),         #   2  21  22  23
              c3 = c(13, 23, 33, 43))         #   3  31  32  33
                                              #   4  41  42  43
                                              #   └行番号
# 行名を付ける
    rownames(df) <- c('r1','r2','r3','r4')    #      c1  c2  c3
                                              #  r1  11  12  13
                                              #  r2  21  22  23
                                              #  r3  31  32  33
                                              #  r4  41  42  43
                                              #  └行名
# 行列 m から生成
#      直接入力では、列単位に入力するが、実務的には行単位のほうが自然です。
    m <- matrix(c(11, 12, 13,       # 行単位での入力
                  21, 22, 23,                #      c1  c2  c3
                  31, 32, 33,                #  r1  11  12  13
                  41, 42, 43),               #  r2  21  22  23
                 nrow=4, byrow=F)            #  r3  31  32  33
    df <- data.frame(m)                      #  r4  41  42  43
    colnames(df) <- c('c1','c2','c3')
    rownames(df) <- c('r1','r2','r3','r4')

CSVファイルの読込み

実務では、行数が大きいので、Excelで作成したデータをCSVファイルで保管しておき、それを読み込んでデータフレームにするのが一般的です。<br> Google Colaboratry 環境の場合、Rが作動しているのはPCではなく Google Drive のサーバーですから、CSVファイルをサーバにアップデートする必要があります。

一般形:df <- read.csv(URL, options)
     URL:CSVファイルのURL、クリップボードからの読込みならば 'clipboard'
     options:
         header=T           # ファイルの先頭行が列名。デフォルトが列名なし。列番号が振られる 
         sep=','            # デフォルトはカンマ区切り(空白区切りなら sep=" ")
         roenames='name'    # 行名、あるいは行名のある列番号。指定がないと行番号が振られる

上の例ならば、CSVファイルは次のようになっています。
url = test,csv
    r,c1,c2,c3
   r1,11,12,13
   r2,21,22,23
   r3,31,32,33
   r4,41,42,43

df <- read.csv('test.csv', header=T, rownames='r')

配列の部分指定

m の部分指定

    m         [,1] [,2] [,3] [,4]
        [1,]   11   12   13   14
        [2,]   21   22   23   24
        [3,]   31   32   33   34 

    m[2, 3]          # 23
    m[2][3]          # エラー   ★

    m[2, ]           # 第2行全体   21 22 23 24
    m[ ,3]           # 第3列全体 13 23 33

    m[1:2, ]         # 1~2行全体 11 12 13 14
                     #               21 22 23 24

    m[ , c(3,4)]     # 第3列と第4列      13 14
                     #                     23 24
                     #                     33 34
    m[ , -c(3,4)]    # 同列以外      11 12
                     #               21 22
                     #               31 32

    m[1:2, c(3,4)]   #                     13 14
                     #                     23 24 

df の部分指定

    df       c1  c2  c3 ← 列名          c1  c2  c3
          1  11  12  13              r1  11  12  13
          2  21  22  23              r2  21  22  23
          3  31  32  33              r3  31  32  33
          4  41  42  43              r4  41  42  43
         └行番号                    └行名

# 〓〓〓 df[] 形式

# df[列] 列内全体の指定
    df[1]
    df['c1']           #      c1
                       #  r1  11
                       #  r2  21
                       #  r3  31
                       #  r4  41
    df[c(1,2)]
    df[c('c1','c2')]   #      c1 c2
                       #  r1  11 12
                       #  r2  21 22
                       #  r3  31 32
                       #  r4  41 42

# df(行, ) 行内全体
    df[3, ]
    df['r3', ]         #      c1 c2 c3
                       #  r3  31 32 33

    df[3:4, ]          #      c1 c2 c3
                       #  r3  31 32 33
                       #  r4  41 42 43

# df(行, 列) 要素
    df[3, 'c1']
    df['r3', 'c1']     # 31 スカラー
   
    df[3:4, 'c1']      # 31 41 ベクトルになる

# 〓〓〓 df$列名 形式  単一の列名しか指定できない
# 列内全体
    df$c1          #  11 21 31 41 ベクトルになる

# 要素
    df$c1[3]       #  31
    df$c1['r3']    # エラー

# 範囲
    df$c1[2:4]     # 21 31 41
    df$c1[c(2,4)]  # 21 41

条件式による指定

[ ] の中に条件式を記述することにより、複雑な部分指定をすることができます。いくつかの例を掲げます。

vの条件式指定

    v <- c(10,50,30,20,40)
    v1 <- v[v > 25]              # 50 30 40
    v1[1]                        # 50

mの条件式指定

    m <- matrix(c(511,312,413, 121,412,113), nrow=2, byrow=F)
           #      [,1] [,2] [,3]
           # [1,]  511  413  412
           # [2,]  312  121  113

# 列1が400以下の行の全要素
    m1 <- m[m[,1]<400, ]
         #  ─┬
         #    └ 第1列の全要素 511, 312
         #  ──┬─
         #      └ そのうち <400 のもの 312
         #  ───┬──      
         #        └  312をもつ行の全列
       #         m1 = 312 121 113

# 行1が500以下の列の全要素
    m1 <- m[ ,m[1,]<500] 
         #    ─┬
         #      └ 第1列の全要素 511, 413, 412 
         #     ──┬──
         #         └ そのうち <500 のもの 413, 412
         #     ───┬──      
         #           └  413, 412をもつ列の全行
         #               m1 =    [,1] [,2]
         #                  [1,]  413  412
         #                  [2,]  121  113
    m1[1, 1]  # 413

# (列1<400)&(行1<500)
    m1 <- m[m[,1]<500, m[1,]<500] 
         #         m1 =    [,1] [,2]
         #                 [1,]  121  113

dfの条件式指定

      df
         c1  c2  c3
      1 311 212 413
      2 421 122 223
      3 131 432 333
      4 241 342 143

# 単一条件
    df1 <- df[df['c1']>300, ]
    df1 <- df[df$c1>300, ]    # どちらも同じ
        # df1 =   c1  c2  c3
        #       1 311 212 413
        #       2 421 122 223

# 複数の条件
    df1 <- df[(df['c1']>300) & (df['c2']>200), ]
    df1 <- df[(df$c1>300) & (df$c2>200), ]
        # df1 =   c1  c2  c3
        #       1 311 212 413

# 取り出す列の指定
    df1 <- df[c('c1','c2')][df['c1']>300, ]
    df1 <- df[c('c1','c2')][df$c1>300, ]
        #           ──┬──
        #     ──┬──     └ 条件を適用した結果に対して
        #         └ 列 c1 c2 だけを取り出す
        # df1 =   c1  c2
        #       1 311 212
        #       2 421 122

配列間の変換と配列の追加

ベクトル → 行列

# 行の結合 rbind
    v1 <- c(11, 12, 13)
    v2 <- c(21, 22, 23)

    m <- rbind(v1, v2)    #     [,1] [,2] [,3]
                          # v1   11   12   13
                          # v2   21   22   23
    m[1, 2]
    m['v1', 2]            # v1
                          # 12

# 行の追加
    v3 <- c(31, 32, 33)

    m1 <- rbind(m, v3)    #    [,1] [,2] [,3]
                          # v1   11   12   13
                          # v2   21   22   23
                          # v3   31   32   33
# 列の結合 cbind
    m <- cbind(v1, v2)    #      v1 v2
                          # [1,] 11 21
                          # [2,] 12 22
                          # [3,] 13 23
# 列の追加
    v4 <- c(14, 24, 34)

    m1 <- cbind(m, v4)    #      v1 v2 v4
                          # [1,] 11 21 14
                          # [2,] 12 22 24
                          # [3,] 13 23 34

行列 → ベクトル

    m <- matrix(c(11,12,13,  21,22,23), nrow=2, byrow=T)
                          #        [,1] [,2] [,3] 
                          #  [1,]   11   12   13
                          #  [2,]   21   22   23
# 1行の取出し
    v <- m[1, ]           #  11 12 13

# 1列の取出し
    v <- m[ , 1]          #  11 21

ベクトル → データフレーム

# 列の結合
    v1 <- c(11, 21, 31)
    v2 <- c(12, 22, 32)

    df <- data.frame(c1=v1, c2=v2)  #   c1 c2
                                     # 1 11 12
                                     # 2 21 22
                                     # 3 31 32
# 列の追加
    v3 = c(13, 23, 33)

    df1 <- data.frame(df, c3=v3)     #   c1 c2 c3
                                     # 1 11 12 13
                                     # 2 21 22 23
                                     # 3 31 32 33

    df['c3'] <- v3
    df$c3 <- v3                  # df が変わる
    df                               #   c1 c2 c3
                                     # 1 11 12 13
                                     # 2 21 22 23
                                     # 3 31 32 33

# 条件による列の追加
    c1 < 20 なら c3 = 0
    c1 > 20 なら c3 = 1
                                 # df が変わる
    df[df$c1 < 20, "c3"] <- 0        #   c1 c2 c3
    df[df$c1 > 20, "c3"] <- 1        # 1 11 12  0
    df                               # 2 21 22  1
                                     # 3 31 32  1

# 三項演算子による新列の追加
    # ifelse(条件式, 真の場合, 偽の場合)
      df$c3 <- ifelse(df$c1 < 20, 0, 1) # 上の c3 が作られる

    #  apply(条件式, 真の場合, 偽の場合)
       df$c3 <- apply(df$ci <20, 0, 1)   # 上の c3 が作られる

# 行の結合と追加
    # 最初の行
      v1 <- c(11, 12)
      df <- data.frame(c1=v1[1], c2=v1[2]) #   c1 c2
                                         # 1 11 12
    # 次行以降
      v2 <- c(21, 22)
      df[2, ] = v2
      df                                 #   c1 c2
                                         # 1 11 12
                                         # 2 21 22

データフレーム → ベクトル

   df   c1 c2
      1 11 12
      2 21 22
      3 31 32

#1列の取出し
    v <- df$c1         #  11 21 31 おすすめ
    v[2]               #  21

    v <- df['c1']      #   c1 データフレームのまま
                       # 1 11
                       # 2 21
                       # 3 31
    v[2]               # エラー
    v[2, ]             # 21

# 1行の取出し
    v <- df[2, ]       #   c1 c2
                       # 2 21 22

    v[1]               #   c1
                       # 2 21

行列 → データフレーム

# 行列が列単位になっているとき
      m      [,1] [,2]
        [1,]  11   21
        [2,]  12   22
        [3,]  13   23

    df <- data.frame(m)      #   X1 X2 ← 仮列名
                             # 1 11 21
                             # 2 12 22
                             # 3 13 23
                             #└ 行番号

# 行列が行単位になっているとき
      m     [,1] [,2] [,3]
         [1,]   11   12   13
         [2,]   21   22   23

           # m の転置行列 t(m) にすればよい。
    df <- data.frame(t(m))   #   X1 X2 ← 仮列名
                             # 1 11 21
                             # 2 12 22
                             # 3 13 23
                             #└ 行番号
# 列名と行名の設定 
    colnames(df) <- c('c1', 'c2')
    rownames(df) <- c('r1', 'r2', 'r3')
    df                       #    c1 c2
                             # r1 11 21
                             # r2 12 22
                             # r3 13 23

データフレーム → 行列  as

マトリクスの制限により対象行・列の要素はすべて同一の型でなければなりません。

    df   c1 c2
      r1 11 21
      r2 12 22
      r3 13 23
# 全体の変換
    m <- as.matrix(df)        # m    c1 c2
                              #   r1 11 12
                              #   r2 12 22
                              #   r3 13 23
                          # 表ではdfと変わらないが、構造は matrix になっています。
    m[1, 1]                   # 11
    m[1, 'c1']                # 11
    m['r1', 'c1']             # 11

    vc <- colnames(df)        #  "c1" "c2"
    vr <- rownames(df)        #  "r1" "r2" "r3"

# 指定列の取出し
    m <- as.matrix(df$c1)     #     [,1]
                              # [1,]   11
                              # [2,]   12
                              # [3,]   13
    m <- as.matrix(df[c('c1','c2')]) #    c1 c2
                                     # r1 11 21
                                     # r2 12 22
                                     # r3 13 23
# 指定行の取出し
    m <- as.matrix(df[c(1,2), ])     #    c1 c2
                                     # r1 11 21
                                     # r2 12 22

配列間の演算

配列の四則演算

ここでの演算は、配列の対象要素に同じ処理をすることを指します。そのため、配列のサイズの不一致がある場合の演算は対象外とします。 また、ここでの四則演算とは、+ - * / 以外に %(剰余), ^(累乗) などの二項演算子、abs(絶対値), sqrt(平方根) などの関数も含みます。
参照:biostatistics「数学基本関数」 https://stats.biopapyrus.jp/r/basic/math-function.html

スカラーとの演算

    v <- c(11, 12, 13)
    v + 100       #  111 112 113

    m <- matrix(c(11,12,13,  21,22,23), nrow=2, byrow=F)   # m         [,1] [,2] [,3]
                                                           #     [1,]   11   13   22
                                                           #     [2,]   12   21   23
    m + 100       #      [,1] [,2] [,3]
                  # [1,]  111  113  122
                  # [2,]  112  121  123

    df <- data.frame(m)
    colnames(df) <- c('c1', 'c2', 'c3')                       #  df  c1 c2 c3
                                                              #    1 11 13 22
                                                              #    2 12 21 23
    df + 100      #   c1  c2  c3
                  # 1 111 113 122
                  # 2 112 121 123

ベクトルとの演算


# ● ベクトルとベクトル
    # v1 と v2 のサイズが同じで、対応する要素間での演算
    v1 <- c(11, 12, 13)
    v2 <- c(100, 200, 300)

    v1 + v2        # 111 212 313

# ● ベクトルと行列
# ベクトル v のサイズが行列の列数と同じで、行列の列m[,j]全体に、v1[j] を加える
    v <- c(100, 200, 300)
    m <- matrix(c(11,12,13,  21,22,23), nrow=2, byrow=F)   # m         [,1] [,2] [,3]
                                                           #     [1,]   11   13   22
                                                           #     [2,]   12   21   23

    m + v          #      [,1] [,2] [,3]
                   # [1,]  111  313  222
                   # [2,]  212  121  323

# ベクトル v のサイズが行列の行数と同じで、行列の行m[i,]全体に、v2[i] を加える
    v <- c(500, 600)
    m <- matrix(c(11,12,13,  21,22,23), nrow=2, byrow=F)   # m         [,1] [,2] [,3]
                                                           #     [1,]   11   13   22
                                                           #     [2,]   12   21   23

    m[ ,1:3] + v   #     [,1] [,2] [,3]       m[ ,1:3]
                   # [1,]  511  513  522       ┬ ─┬
                   # [2,]  612  621  623   m の全行 └ m の全列 これを明示するので列の計算になる

# ● ベクトルとデータフレーム
# データフレームは列ベクトルがベースになるので、「ベクトルと行列」での行と列が逆になります。
    v <- c(500, 600)
    df <- data.frame(m)
    colnames(df) <- c('c1', 'c2', 'c3')                       #  df  c1 c2 c3
                                                              #    1 11 13 22
                                                              #    2 12 21 23
    df + v         #    c1  c2  c3
                   #  1  511 513 522
                   #  2  612 621 623

# 列ごとに異なる値を全行に加えるには、次のようにします。
    v <- c(100, 200, 300)
    df <- data.frame(m)
    colnames(df) <- c('c1', 'c2', 'c3')                       #  df  c1 c2 c3
                                                              #    1 11 13 22
                                                              #    2 12 21 23
    df[ ,c('c1','c2','c3')] + v
                   #     c1  c2  c3
                   #  1  111 313 222
                   #  2  212 121 323

行列と行列、行列とデータフレームでの演算では、対応する要素間にするには二つの配列が同じサイズでなければならないが、そのようなケースは稀なので省略します。

配列の積 直積 %o% 内積 %*%

# ● ベクトルの直積
    v1 <- c( 1,  2,  3)
    v2 <- c(10, 20)

    v1 %o% v2      #       [,1] [,2]    v1を縦に、v2を横にした、全ての組合せの行列
                   # [1,]   10   20     1*10  1*20
                   # [2,]   20   40     2*10  2*20
                   # [3,]   30   60     3*10  3+20

# ● ベクトルの内積
    v1 <- c( 1,  2,  3)
    v2 <- c(10, 20, 30)

    v1 %*% v2      # 140   1*10 + 2*20 + 3+30

# ● 行列とベクトルの内積
    m <- matrix(c(11, 12, 13,      #       [,1] [,2] [,3]
                  21, 22, 23),     # [1,]   11   13   22
                nrow=2, byrow=T)   # [2,]   12   21   23 
    v <- c(1, 2, 3)

    m %*% v        #       [,1]
                   # [1,]   74    11*1 + 12*2 + 13*3
                   # [2,]  134    21*1 + 22*2 + 23*3

# ● 行列同士の内積
    m1 <- matrix(c(11, 12, 13,     #       [,1] [,2] [,3]
                  21, 22, 23),     # [1,]   11   13   22
                nrow=2, byrow=T)   # [2,]   12   21   23 
 
    m2 <- matrix(c(0,1, 1,0, 1,1), #       [,1] [,2]
                 nrow=3, byrow=T)  # [1,]    0    1
                                   # [2,]    1    0
                                   # [3,]    1    1

    m1 %*% m2                      #       [,1] [,2]
                                   # [1,]   25   24   11*0 + 12*1 + 13*1,   11*1 + 12*0 + 13*1
                                   # [2,]   45   44   21*0 + 22*1 + 23*1,   21*1 + 22*0 + 23*1      

# ● データフレーム同士の内積(結合)
#    データフレームの内積とは、結合(join)といわれる操作です。
#    df1 と df2 をキー c1 により結合して1つのデータフレームにします。

    df1 <- data.frame(                  #   c1 c2 c3
              c1 = c('A','B','A','B'),  # 1  A 12 13 
              c2 = c(12, 22, 32, 42),   # 2  B 22 23
              c3 = c(13, 23, 33, 43))   # 3  A 32 33
                                        # 4  B 42 43

    df2 <- data.frame(                  #   c1  c4
              c1 = c('A','B'),          # 1  A 100
              c4 = c(100,200))          # 2  B 200

    merge(df1, df2, 'c1')               #   c1 c2 c3  c4
                                        # 1  A 12 13 100
                                        # 2  A 32 33 100
                                        # 3  B 22 23 200
                                        # 4  B 42 43 200