3

サブセット化が以前に発生したときに未使用のファクターレベルをドロップする問題。一般的な解決策には、可能な場合は宣言することによって文字ベクトルを使用することが含まれます

options(stringsAsFactors = FALSE)

ただし、プロットに順序付けられた要素が必要な場合もあります。その場合、次droplevelsのラッパーを作成するなどの便利な関数を使用できますsubset

subsetDrop <- function(...){droplevels(subset(...))}

私はsubsetDropほとんどこの問題を解決することを理解していますが、viaをサブセット化する[方が便利な(そして入力が少ない)状況もあります。

私の質問は、便宜上、[データフレームをオーバーライドして因子レベルを自動的にドロップすることにより、これをRの「デフォルト」の動作にどれだけプッシュできるかということです。たとえば、Hmiscパッケージには、単一の要素をサブセット化するためのdropUnusedLevelsオーバーライドが含まれています(デフォルトには未使用のレベルを削除するための引数があるように見えるため[.factor、これは不要になりました)。未使用の因子レベルを使用してデータフレームをサブセット化できるが、自動的にドロップする(そしてもちろん、順序付けられた因子の場合は順序を維持する)同様のソリューションを探しています。[.factordrop[

4

3 に答える 3

6

デフォルトの動作を変更することには本当に注意が必要です。使用する別の関数が通常のデフォルトの動作にいつ依存するかはわかりません。代わりに、あなたと同様の関数を記述しますsubsetDrop[

sel <- function(x, ...) droplevels(x[...])

それで

> d <- data.frame(a=factor(LETTERS[1:5]), b=factor(letters[1:5]))
> str(d[1:2,])
'data.frame':   2 obs. of  2 variables:
 $ a: Factor w/ 5 levels "A","B","C","D",..: 1 2
 $ b: Factor w/ 5 levels "a","b","c","d",..: 1 2
> str(sel(d,1:2,))
'data.frame':   2 obs. of  2 variables:
 $ a: Factor w/ 2 levels "A","B": 1 2
 $ b: Factor w/ 2 levels "a","b": 1 2

本当にデフォルトを変更したい場合は、次のようなことを行うことができます

foo <- `[.data.frame`
`[.data.frame` <- function(...) droplevels(foo(...))

ただし、名前空間がどのように機能するかを知っていることを確認してください。これは、グローバル名前空間から呼び出されたものに対して機能しますが、ベース名前空間のバージョンは変更されません。これは良いことかもしれませんが、それはあなたが確実に理解したいことです。この変更後、出力は希望どおりになります。

> str(d[1:2,])
'data.frame':   2 obs. of  2 variables:
 $ a: Factor w/ 2 levels "A","B": 1 2
 $ b: Factor w/ 2 levels "a","b": 1 2
于 2011-06-19T01:11:00.353 に答える
5

この作業は、drop引数のデフォルト値を次のように上書きすることで実行できます。

formals(`[.factor`)$drop <- TRUE

アップデート

data.frameに関しては、次の方法で実行できます。

`[.data.frame` <- function(...)droplevels(base::`[.data.frame`(...))

実際には@Aaronのものと似ています。

この動作をキャンセルする場合は、次のようにします。

rm(`[.data.frame`)

それをします。

> d <- data.frame(a=letters[1:10], b=LETTERS[1:10])
> str(d[1:5, ])
'data.frame':   5 obs. of  2 variables:
 $ a: Factor w/ 10 levels "a","b","c","d",..: 1 2 3 4 5
 $ b: Factor w/ 10 levels "A","B","C","D",..: 1 2 3 4 5
> `[.data.frame` <- function(...)droplevels(base::`[.data.frame`(...))
> str(d[1:5, ])
'data.frame':   5 obs. of  2 variables:
 $ a: Factor w/ 5 levels "a","b","c","d",..: 1 2 3 4 5
 $ b: Factor w/ 5 levels "A","B","C","D",..: 1 2 3 4 5
> rm(`[.data.frame`)
> str(d[1:5, ])
'data.frame':   5 obs. of  2 variables:
 $ a: Factor w/ 10 levels "a","b","c","d",..: 1 2 3 4 5
 $ b: Factor w/ 10 levels "A","B","C","D",..: 1 2 3 4 5
于 2011-06-19T00:13:05.033 に答える
2

デフォルトを変更することは非常に危険だと思います。ここで私の応答を参照してください。

人々がファクターレベルの低下に関心を持っているほとんどの場合、あなたが本当に必要としないか(1つの値を強制したものを要約するのはばかげています)、またはあなたが試みていることを達成するためのより良い方法があります。自動ドロップによって発生する可能性のある副作用は、保存された2、3のキーストロークよりも潜在的に悪化します。また、再現性のある研究を行っている場合は、特にそう言わずに、コンピューターがデータを変更することに依存したり、許可したりするべきではありません。

于 2011-06-19T02:49:02.963 に答える