Переопределите [.data.frame для удаления неиспользуемых уровней факторов по умолчанию - PullRequest
3 голосов
/ 19 июня 2011

Проблема сброса неиспользованных уровней факторов, когда поднаборы возникли до .Распространенные решения включают использование векторов символов, где это возможно, путем объявления

options(stringsAsFactors = FALSE)

Иногда, однако, упорядоченные факторы необходимы для построения графика, и в этом случае мы можем использовать вспомогательные функции, такие как droplevels, чтобы создать оболочку для subset:

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

Я понимаю, что subsetDrop в основном решает эту проблему, но есть некоторые ситуации, когда поднабор через [ более удобен (и меньше набирает!).

Мой вопроснасколько дальше, для удобства, можем ли мы выдвинуть это поведение «R» по умолчанию, переопределив [ для фреймов данных, чтобы автоматически отбрасывать уровни факторов.Например, пакет Hmisc содержит dropUnusedLevels, который переопределяет [.factor для поднабора одного фактора (который больше не нужен, так как по умолчанию [.factor имеет аргумент drop для отбрасывания неиспользуемых уровней).Я ищу подобное решение, которое позволило бы мне подбирать кадры данных с использованием [, но автоматически отбрасывать неиспользуемые уровни факторов (и, конечно, сохранять порядок в случае упорядоченных факторов).

Ответы [ 3 ]

6 голосов
/ 19 июня 2011

Я бы очень опасался менять поведение по умолчанию;Вы никогда не знаете, когда другая функция, которую вы используете, зависит от обычного поведения по умолчанию.Вместо этого я бы написал аналогичную функцию для вашего 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
5 голосов
/ 19 июня 2011

вы можете сделать эту работу, переписав значение по умолчанию для аргумента сброса, как это:

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

ОБНОВЛЕНИЕ

как и для data.frame, вы можете сделать:

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

на самом деле похоже на @ Aaron's.

, если вы хотите отменить это поведение, тогда:

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
2 голосов
/ 19 июня 2011

Я думаю, что изменение значения по умолчанию очень опасно, см. Мой ответ здесь .

В большинстве случаев люди обеспокоены падением уровней факторов, которые вам либо не нужны (что-то глупо подытоживать то, что вы заставили иметь значение 1), либо есть лучший способ выполнить то, что вы пытаетесь. Возможные побочные эффекты от автоматического отбрасывания потенциально хуже, чем пара сохраненных нажатий клавиш. Кроме того, если вы проводите воспроизводимые исследования, вам не следует полагаться или даже позволять компьютеру изменять данные без вашего особого разрешения.

...