R で行ごとに要素を総数で割りたい。
例えば次のような行列があったとする。
R
> mat <- matrix(1:6, 3, 2)
> mat
[,1] [,2]
[1,] 1 4
[2,] 2 5
[3,] 3 6
1行目は 1+4=5 なので 1/5 と 4/5、2行目は 2+5=7 なので 2/7 と 5/7 というように行ごとに sum
した値で各行の要素を割りたい。
普通に書くとこんな感じになると思う。
R
> t(apply(mat, 1, function(row) row / sum(row)))
[,1] [,2]
[1,] 0.2000000 0.8000000
[2,] 0.2857143 0.7142857
[3,] 0.3333333 0.6666667
しかし、もっと良い書き方がある。
R
> mat / rowSums(mat)
[,1] [,2]
[1,] 0.2000000 0.8000000
[2,] 0.2857143 0.7142857
[3,] 0.3333333 0.6666667
こちらの方が簡潔でしかも速い。
R
> library(microbenchmark)
> microbenchmark(
+ `use apply` = t(apply(mat, 1, function(row) row / sum(row))),
+ `use rowSums` = mat / rowSums(mat)
+ )
Unit: microseconds
expr min lq mean median uq max neval cld
use apply 19.159 20.645 32.06376 21.0920 21.5540 1072.263 100 b
use rowSums 2.623 3.034 3.68557 3.5825 3.8215 16.668 100 a
ちなみに列ごとだと次のようになる。
R
> microbenchmark(
+ `use apply` = apply(mat, 2, function(col) col / sum(col)),
+ `use colSums` = t(t(mat) / colSums(mat))
+ )
Unit: microseconds
expr min lq mean median uq max neval cld
use apply 15.303 17.0210 32.31973 17.538 18.0725 1456.862 100 a
use colSums 8.499 8.9665 10.94210 10.182 10.6365 62.848 100 a
Enjoy!