我有一个包含因子的数据帧。当我使用子集或其他索引函数创建这个数据帧的子集时,就创建了一个新的数据帧。然而,因子变量保留其所有原始水平,即使它们不存在于新的数据框架中。
这在绘制面图或使用依赖于因子级别的函数时会导致问题。
在新的数据框架中从一个因子中移除级别最简洁的方法是什么?
这里有一个例子:
df <- data.frame(letters=letters[1:5],
numbers=seq(1:5))
levels(df$letters)
## [1] "a" "b" "c" "d" "e"
subdf <- subset(df, numbers <= 3)
## letters numbers
## 1 a 1
## 2 b 2
## 3 c 3
# all levels are still there!
levels(subdf$letters)
## [1] "a" "b" "c" "d" "e"
这是令人讨厌的。我通常是这样做的,以避免加载其他包:
levels(subdf$letters)<-c("a","b","c",NA,NA)
这就得到了:
> subdf$letters
[1] a b c
Levels: a b c
注意,新级别将取代旧级别中占据其索引的任何内容(subdf$letters),因此如下所示:
levels(subdf$letters)<-c(NA,"a","c",NA,"b")
不能工作。
当你有很多关卡时,这显然不太理想,但对于少数关卡来说,这是快速而简单的。
我写了效用函数来做这个。现在我知道了gdata的drop。水平,看起来很相似。他们在这里(从这里):
present_levels <- function(x) intersect(levels(x), x)
trim_levels <- function(...) UseMethod("trim_levels")
trim_levels.factor <- function(x) factor(x, levels=present_levels(x))
trim_levels.data.frame <- function(x) {
for (n in names(x))
if (is.factor(x[,n]))
x[,n] = trim_levels(x[,n])
x
}