[とsapplyには気をつける。
ひとりアドベントカレンダー15日目。
Rはよしなにデータを処理してくれるので、非常に使い勝手が良い。
その一方、よしなに処理しすぎてこちらが泣きをみることがある。
たとえば、Rで使わない人はいないであろう[関数。
data.frameクラスに適用される[.data.frame関数は通常データフレームを返す。
> iris[1:2,1:2] Sepal.Length Sepal.Width 1 5.1 3.5 2 4.9 3.0
しかし、返すデータフレームが1列の時はベクトルを返してくる。
> iris[1:2,1] [1] 5.1 4.9
もう慣れすぎて個人的にはこの挙動に対してなんら疑問を持たないのだが、これは一貫性が無い。
一貫性をもたせる、つまりデータフレームで返すためにはdrop=FALSEとする。
> iris[1:2,1,drop=FALSE] Sepal.Length 1 5.1 2 4.9
同様の関数にsapply関数がある。
こちらデフォルトだとベクトルを返すのだが、ベクトルの長さが0の場合はリストを返す。
> sapply(LETTERS[1:3], function(x) x == "B") A B C FALSE TRUE FALSE > sapply(LETTERS[0], function(x) x == "B") named list()
これは気を利かせるオプションsimplifyがデフォルトでTRUEとなっているからであり、FALSEにすることで常にリストで返るようになる。
> sapply(LETTERS[1:3], function(x) x == "B", simplify = FALSE) $A [1] FALSE $B [1] TRUE $C [1] FALSE > sapply(LETTERS[0], function(x) x == "B", simplify = FALSE) named list()
なお、vapplyはその辺ガチガチに返り値の型と長さも指定できるのでこちらの方が安全ではある。
> vapply(LETTERS[1:3], function(x) x == "B", logical(1)) A B C FALSE TRUE FALSE > vapply(LETTERS[0], function(x) x == "B", logical(1)) named logical(0)
この辺りの話はAdvanced Rおよび以下のSOに書いてある。
http://stackoverflow.com/questions/9668456/why-does-sapply-return-a-list
そして翻訳も出る。決断的に1月に出る。
- 作者: Hadley Wickham,石田基広,市川太祐,高柳慎一,福島真太朗
- 出版社/メーカー: 共立出版
- 発売日: 2016/02/10
- メディア: 単行本
- この商品を含むブログ (29件) を見る