R

R で行ごとに要素を総数で割る

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!