スタートページ> JavaScript> 他言語> R言語
apply は、主に配列内での一括処理を記述するための関数です。
# 行列
# [,1] [,2] [,3]
m <- matrix(c(11, 12, 13, # [1,] 11 12 13
21, 22, 23), # [2,] 21 22 23
nrow=2, byrow=T)
v <- apply(m, 1, sum) # 各行の合計、列方向への計算
v # 36 66
apply には、次のファミリがあります。
allay 標準 lallay 各行の計算 出力はリスト形式 sapply 各行の計算 出力はベクトル形式 tapply 処理行の選択など複雑な条件指定ができる。ここでは省略します。 mapply applyの多変量版。ここでは省略します。
機能が比較的単純な sapply, 1apply から説明します。
# ===== リスト形式 ===== a <- list(c(11, 12, 13), c(21, 22, 23)) ba <- sapply(a, sum) ba # 36・66 ba[1] # 36 ┐ ba[2] # 66 ├ ★直観と一致 ba[1] + ba[2] # 102 ┘ # ===== 行列形式 ===== # [,1] [,2] [,3] m <- matrix(c(11, 12, 13, # [1,] 11 12 13 21, 22, 23), # [2,] 21 22 23 nrow=2, byrow=T) bm <- sapply(m, sum) bm # 11・21・12・22・13・23 ★ m の内容 bm[1] + bm[2] # 32 # ===== データフレーム形式 ===== # 縦横が転置 df <- data.frame( # c1 c2 c1 = c(11, 12, 13), # 1 11 21 c2 = c(21, 22, 23)) # 2 12 22 # 3 13 23 bf <- sapply(df, sum) bf # c1:36 c2:66 bf[1] + bf[2] # c1:102 bf["c1"] # c1: 36 bf["c2"] # c2: 66 bf["c1"] + bf["c2"] # c1:102
sapply: [i]、 [[i]] 可
# ====== sapply ======= a <- list(c(11, 12, 13), c(21, 22, 23)) ba <- sapply(a, sum) ba # 36・66 ba[1] # 36 OK ba[1] + ba[2] # 102 OK ba[[1]] # 36 OK ba[[1]] + ba[[2]] # 102 OK |
lapply: [[i]] のみ可
# ====== iapply ======= a <- list(c(11, 12, 13), c(21, 22, 23)) ba <- iapply(a, sum) ba # 1. 36 2.66 ba[[1]] # 36 OK ba[[1]] + ba[[2]] # 102 OK ba[1] # 1. 36 ba[1] + ba[2] # ★エラー |
# ===== リスト形式 ===== エラーになる # a <- list(c(11, 12, 13), # c(21, 22, 23)) # ba <- apply(a, 1, sum) ★ここでエラーになる # # ===== 行列形式 ===== # [,1] [,2] [,3] m <- matrix(c(11, 12, 13, # [1,] 11 12 13 21, 22, 23), # [2,] 21 22 23 nrow=2, byrow=T) bm <- apply(m, 1, sum) bm # 36・66 bm[1] # 36 bm[1] + bm[2] # 102 bm[[1]] # 36 bm[[1]] + bm[[2]] # 102 # ===== データフレーム形式 ===== # 縦横が転置 df <- data.frame( # c1 c2 c1 = c(11, 12, 13), # 1 11 21 c2 = c(21, 22, 23)) # 2 12 22 # 3 13 23 bf <- apply(df, 2, sum) # 転置しているので MARGIN = 2 とする bf # 36・66 bf[1] # 36 bf[1] + bf[2] # 102 bf[[1]] # 36 bf[[1]] + bf[[2]] # 102 bf["c1"] # c1: 36 bf["c1"] + bf["c2"] # c1: 102
一般に apply での関数は、sum や mean など、行あるいは列を一次元配列とした加工が主ですが、 sqrt のような要素単位での加工もできます。
●sqrt
# [,1] [,2] [,3] m <- matrix(c(11, 12, 13, # [1,] 11 12 13 21, 22, 23), # [2,] 21 22 23 nrow=2, byrow=T) bm <- apply(m, 1, sqrt) bm # [, 1] [, 2] # [1, ] 3.316625 4.582576 # [2, ] 3.464102 4.690416 # [3, ] 3.605551 4.795832 bm[1, 2] # 4.582576 bm <- apply(m, 2, aqrt) # こちらが入力データと同じ順序になる。 bm # [, 1] [, 2] [, 3] # [1, ] 3.316625 3.464102 3.605551 # [2, ] 4.582576 4.690416 4.795832 bm[1, 2] # 3.464102
●sort(降順)
# [,1] [,2] [,3] m <- matrix(c(11, 12, 13, # [1,] 11 12 13 21, 22, 23), # [2,] 21 22 23 nrow=2, byrow=T) bm <- apply(m, 1, sort, decreasing = TRUE) bm # [, 1] [, 2] # [1, ] 23 23 # [2, ] 12 22 # [3, ] 11 21 bm[1, 2] # 23 bm <- apply(m, 2, sort, decreasing = TRUE) # こちらが入力データと同じ順序になる。 bm # [, 1] [, 2] [, 3] # [1, ] 21 22 23 # [2, ] 11 12 13 bm[1, 2] # 22
apply グループでは、加工関数を自作することができます。
apply(m, 1, sum) と同じです。
function(x) の x は、名称は任意ですが、sum(x) のように、関数は ( ) を付ける必要があり、その引数と同一名になります。
# ========= 入力データ # [,1] [,2] [,3] m <- matrix(c(11, 12, 13, # [1,] 11 12 13 21, 22, 23), # [2,] 21 22 23 nrow=2, byrow=T) # 縦横が転置 df <- data.frame( # c1 c2 c1 = c(11, 12, 13), # 1 11 21 c2 = c(21, 22, 23)) # 2 12 22 # 3 13 23 # ========= 例1 apply(m, 1, sum) と同じ bm <- apply(m, 1, function(x) { sum(x) }) bm[1] # 36 bm[1] + bm[2] # 102 bf <- apply(df, 2, function(x) { sum(x) }) # 転置しているので MARGIN = 2 とする bf[1] # c1: 36 bf[1] + bf[2] # c1: 102 bf["c1"] # c1: 36 bf["c1"] + bf["c2"] # c1: 102
例えば sum(x) の結果に y=100 を加えるような処理です。
function の引数
# ========= 入力データ # [,1] [,2] [,3] m <- matrix(c(11, 12, 13, # [1,] 11 12 13 21, 22, 23), # [2,] 21 22 23 nrow=2, byrow=T) # 縦横が転置 df <- data.frame( # c1 c2 c1 = c(11, 12, 13), # 1 11 21 c2 = c(21, 22, 23)) # 2 12 22 # ========= 例A 計算結果に y=100(function内指定) を加える bm <- apply(m, 1, function(x) { y <- 100 z <- sum(x) + y return(z); } ) bm[1] # 136 bm[1] + bm[2] # 302 bf <- apply(df, 2, function(x) { y <- 100 z <- sum(x) + y return(z); } ) bf[1] # c1: 136 bf[1] + bf[2] # c1: 302 bf["c1"] # c1: 136 bf["c1"] + bf["c2"] # c1: 302 # ========= 例B 外部で与えた変数を内部でそのまま使う y <- 100 bm <- apply(m, 1, function(x) { z <- sum(x) + y return(z); } ) bm[1] # 136 bm[1] + bm[2] # 302
# ======= DATA を外部で設定 自作関数 <- function(x, y) { z <- sum(x) + y return(z) } df <- data.frame( # c1 c2 c1 = c(11, 12, 13), # 1 11 21 c2 = c(21, 22, 23)) # 2 12 22 bf = apply(df, 2, 自作関数, 100) # 100 を y=100 としてもよい bf[1] + bf[2] # c1: 302 bf["c1"] + bf["c2"] # c1: 302 # ======= DATA を内部で設定 自作関数 <- function(x, y) { df <- data.frame( # c1 c2 c1 = c(11, 12, 13), # 1 11 21 c2 = c(21, 22, 23)) # 2 12 22 z <- sum(x) + y return(z) } bf = apply(df, 2, 自作関数, 100) # 100 を y=100 としてもよい bf[1] + bf[2] # c1: 302 bf["c1"] + bf["c2"] # c1: 302