data.frame をフィルタリングする必要がある場合、つまり特定の条件を満たす行を抽出する必要がある場合は、次のsubset
関数を使用することをお勧めします。
subset(airquality, Month == 8 & Temp > 90)
関数ではなく[
:
airquality[airquality$Month == 8 & airquality$Temp > 90, ]
私がこれを好む主な理由は 2 つあります。
コードは左から右に読む方が読みやすいと思います。R について何も知らない人でも、
subset
上記のステートメントが何をしているかはわかります。列は式の中で変数として参照できるため
select
、キー入力を少し節約できます。上記の例では、airquality
では 1 回だけ入力すれば済みましたsubset
が、 では 3 回入力する必要があります[
。
それで、私は幸せに暮らしていました。subset
短くて読みやすいのでどこでも使い、仲間の R プログラマーにもその素晴らしさを説いていました。しかし、昨日、私の世界は崩壊しました。subset
ドキュメントを読んでいるときに、次のセクションに気づきました。
警告
これは対話的に使用するための便利な関数です。プログラミングでは、[ のような標準のサブセット化関数を使用する方が適切です。特に、引数サブセットの非標準の評価は予期しない結果をもたらす可能性があります。
著者の意図を明確に説明してくれる人はいませんか?
まず、「対話型で使用する」とはどういう意味ですか? バッチ モードで実行されるスクリプトとは対照的に、対話型セッションが何であるかは知っていますが、どのような違いがあるのかわかりません。
それでは、「引数サブセットの非標準評価」について、またそれがなぜ危険なのか、例を挙げて説明していただけますか?
ベストアンサー1
この質問は@Jamesのコメントでうまく答えられており、Hadley Wickhamによる危険性subset
(および同様の機能)についての優れた説明が示されています。[ここ]ぜひ読んでみてください!
少し長いので、Hadley が「何が問題になるのか?」という質問に最も直接的に答えている例をここに記録しておくと役立つかもしれません。
Hadley は次の例を提案しています。次の関数を使用してデータ フレームをサブセット化し、並べ替えたいとします。
scramble <- function(x) x[sample(nrow(x)), ]
subscramble <- function(x, condition) {
scramble(subset(x, condition))
}
subscramble(mtcars, cyl == 4)
次のエラーが返されます:
eval(expr, envir, enclos) でエラーが発生しました: オブジェクト 'cyl' が見つかりません
なぜなら、R はもはや 'cyl' というオブジェクトがどこにあるかを「知らない」からです。彼はまた、偶然にグローバル環境に 'cyl' というオブジェクトがある場合に発生する可能性のある、実に奇妙な事柄についても指摘しています。
cyl <- 4
subscramble(mtcars, cyl == 4)
cyl <- sample(10, 100, rep = T)
subscramble(mtcars, cyl == 4)
(実行して自分で確かめてください。かなりすごいですよ。)