初歩的なことかもしれないが忘れるのでメモ。
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.NAMES
がTRUE
だとその文字が答えのベクトルの名前になるよということ。
たとえば、次のようにA~Eまでの文字(LETTERS
で1~5を指定)をsapply()
でただ渡された値を返すだけの関数で処理するようにしたときに、USE.NAMES
がTRUE
の場合は
sapply(LETTERS[1:5], function(x) x, USE.NAMES = TRUE)
## A B C D E
## "A" "B" "C" "D" "E"
と最初に処理するために与えた文字がベクトルの名前になってくれる。USE.NAMSE
をFALSE
にすると
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"
要注意(凡ミス)。
追記
sapply()
のベクトルの名前について、上記サイトは、ちゃんと上記の挙動を理解した上でもドキュメントに書いてあることから想像される挙動とはちがう動きをしたというもの。
このUSE.NAMES
引数に関わる挙動ではこれも注意が必要そう。
-
言い訳をすると、
sapply()
がだまっていれば名前付きのベクトルを出力する関数なので、そこでUSE.NAMES
なんて名前を使う使わないみたいな引数があってこれをFALSE
にしたら名前なしのベクトルが出力されそうだなぁって思っちゃう。↩