備忘ログ

チラシの裏的備忘録&メモ

Rのsapply()のUSE.NAMESのメモ

初歩的なことかもしれないが忘れるのでメモ。

Rのsapply()mapply()の引数についてUSE.NAMESドキュメントちゃんと読めばわかるんだけど、引数の名前と関数の処理から邪推していつも勘違いする。ちゃんと理解したつもりでも時間が経つと、また「あれ、あれっていけるんだっけか?」とすぐに忘れる。

なにを勘違いするかというと、sapply()USE.NAMESはデフォルトでTRUEになっているが、これをFALSEにすると出力結果が名前付きのベクトルから、名前無しのベクトルになるんじゃないかということ1

これは完全な勘違いで、簡単なコードとして次のようなものでもわかる。IRISデータの最初の4列つまり名前付きの値の平均値を求める処理するsapply()を書く。

sapply(iris[1:4], mean, USE.NAMES = FALSE)
## Sepal.Length  Sepal.Width Petal.Length  Petal.Width 
##     5.843333     3.057333     3.758000     1.199333

完全に名前がついてくる。

名前付きの値を処理させて、名前無しのベクトルが欲しかったらおとなしくunname()すべし。

unname(sapply(iris[1:4], mean))
## [1] 5.843333 3.057333 3.758000 1.199333

ちゃんとドキュメント読むと

USE.NAMES

logical; if TRUE and if X is character, use X as names for the result unless it had names already. Since this argument follows … its name cannot be abbreviated.

と書いてあって、最初に与えた処理するベクトルやリストが文字だったときに、USE.NAMESTRUEだとその文字が答えのベクトルの名前になるよということ。

たとえば、次のようにA~Eまでの文字(LETTERSで1~5を指定)をsapply()でただ渡された値を返すだけの関数で処理するようにしたときに、USE.NAMESTRUEの場合は

sapply(LETTERS[1:5], function(x) x, USE.NAMES = TRUE)
##   A   B   C   D   E 
## "A" "B" "C" "D" "E"

と最初に処理するために与えた文字がベクトルの名前になってくれる。USE.NAMSEFALSEにすると

sapply(LETTERS[1:5], function(x) x, USE.NAMES = FALSE)
## [1] "A" "B" "C" "D" "E"

と名前はつかない。

もちろん最初と同じで、ベクトルにそもそも名前がついていたら、FALSEでも名前がつく。

AtoE <- LETTERS[1:5]
names(AtoE) <- LETTERS[1:5]
sapply(AtoE, function(x) x, USE.NAMES = FALSE)
##   A   B   C   D   E 
## "A" "B" "C" "D" "E"

要注意(凡ミス)。

追記

rion778.hatenablog.com

sapply()のベクトルの名前について、上記サイトは、ちゃんと上記の挙動を理解した上でもドキュメントに書いてあることから想像される挙動とはちがう動きをしたというもの。

このUSE.NAMES引数に関わる挙動ではこれも注意が必要そう。


  1. 言い訳をすると、sapply()がだまっていれば名前付きのベクトルを出力する関数なので、そこでUSE.NAMESなんて名前を使う使わないみたいな引数があってこれをFALSEにしたら名前なしのベクトルが出力されそうだなぁって思っちゃう。