3

以前出现过在子集时删除未使用的因子水平的问题。常见的解决方案包括通过声明尽可能使用字符向量

options(stringsAsFactors = FALSE)

然而,有时,有序因子是绘图所必需的,在这种情况下,我们可以使用方便的函数,比如droplevels为 创建一个包装器subset

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

我意识到这subsetDrop主要解决了这个问题,但在某些情况下,子集 via[更方便(而且打字更少!)。

我的问题是,为了方便起见,我们可以通过覆盖[数据框以自动删除因子级别来推动这成为 R 的“默认”行为。例如,Hmisc 包包含用于子集单个因子的dropUnusedLevels覆盖[.factor(不再需要,因为默认值[.factor似乎有一个drop用于删除未使用级别的参数)。我正在寻找一个类似的解决方案,它允许我使用[但自动删除未使用的因子级别(当然在有序因子的情况下保留顺序)对数据帧进行子集化。

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

我认为更改默认值非常危险,请参阅我的回复here

大多数情况下,人们关心的是降低你真的不需要的因子水平(总结你被迫拥有 1 值的东西是愚蠢的)或者有更好的方法来完成你正在尝试的事情。自动丢弃可能产生的副作用可能比节省的几次击键更糟。此外,如果您正在进行可重复的研究,那么您不应该依赖甚至允许计算机在没有您具体说明的情况下更改数据。

于 2011-06-19T02:49:02.963 回答