スタートページ> JavaScript> 他言語> R言語> →基本記述規則
・配列(ベクトル・行列・データフレーム)の生成 ・配列の部分指定 ・ベクトル・行列・データフレームの相互変換 ・配列間の演算
Rでは、スカラーも1x1のベクトルになっています。 一次元配列 ベクトル v ベクトル 行(横)ベクトル 二次元配列 行列 m ベクトルからの行列 df データフレーム 列名あり、列(縦)ベクトルの集合 列ベクトルは数値と文字列は混在しない この他に list 構造がありますが、ここでは省略します。 ● Rでは、要素番号は(0ではなく)1から始まります。
# 直接入力 一般式 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
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
# 直接入力 一般形: 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')
# ===== データフレーム df <- data.frame( # c1 c2 c1 = c(11, 21, 31), # r1 11 12 c2 = c(12, 22, 32)) # r2 21 22 rownames(df) <- c('r1','r2','r3') # r3 31 32 dfc <- data.frame( # c3 c3 = c(13, 23, 33)) # r1 13 rownames(dfc) <- c('r1','r2','r3') # r2 23 # r2 23 dfr <- data.frame( # c1 c2 c1 = 41, # r4 41 42 c2 = 42) rownames(dfr) <- c('r4') # ===== cbind 列方向の結合 df1 <- cbind(df, dfc) # c1 c2 c3 # r1 11 12 13 # r2 21 22 23 # r3 31 32 33 # ===== rbind 行方向の結合 df2 <- rbind(df, dfr) # c1 c2 # r1 11 12 # r2 21 22 # r3 31 32 # r4 41 42
実務では、行数が大きいので、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 [,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 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 <- c(10,50,30,20,40) v1 <- v[v > 25] # 50 30 40 v1[1] # 50
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 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
マトリクスの制限により対象行・列の要素はすべて同一の型でなければなりません。
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
行列と行列、行列とデータフレームでの演算では、対応する要素間にするには二つの配列が同じサイズでなければならないが、そのようなケースは稀なので省略します。
# ● ベクトルの直積 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