我有一个包含因子的数据帧。当我使用子集或其他索引函数创建这个数据帧的子集时,就创建了一个新的数据帧。然而,因子变量保留其所有原始水平,即使它们不存在于新的数据框架中。
这在绘制面图或使用依赖于因子级别的函数时会导致问题。
在新的数据框架中从一个因子中移除级别最简洁的方法是什么?
这里有一个例子:
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")
不能工作。
当你有很多关卡时,这显然不太理想,但对于少数关卡来说,这是快速而简单的。
这是令人讨厌的。我通常是这样做的,以避免加载其他包:
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")
不能工作。
当你有很多关卡时,这显然不太理想,但对于少数关卡来说,这是快速而简单的。
你所要做的就是在子集设置后再次应用factor()到你的变量:
> subdf$letters
[1] a b c
Levels: a b c d e
subdf$letters <- factor(subdf$letters)
> subdf$letters
[1] a b c
Levels: a b c
EDIT
因子页的例子如下:
factor(ff) # drops the levels that do not occur
要从数据框架中的所有因子列中删除级别,您可以使用:
subdf <- subset(df, numbers <= 3)
subdf[] <- lapply(subdf, function(x) if(is.factor(x)) factor(x) else x)
这是一个已知的问题,您的示例所在的gdata包中的drop.levels()提供了一个可能的补救措施
> drop.levels(subdf)
letters numbers
1 a 1
2 b 2
3 c 3
> levels(drop.levels(subdf)$letters)
[1] "a" "b" "c"
在Hmisc包中还有一个dropUnusedLevels函数。但是,它只能通过修改子集操作符[来工作,在这里不适用。
因此,基于每列的直接方法是简单的As .factor(As .character(data)):
> levels(subdf$letters)
[1] "a" "b" "c" "d" "e"
> subdf$letters <- as.factor(as.character(subdf$letters))
> levels(subdf$letters)
[1] "a" "b" "c"
不幸的是,factor()在使用RevoScaleR的rxDataStep时似乎不起作用。我分两步做:
1)转换为字符并存储在临时外部数据帧(.xdf)。
2)转换回因子并存储在确定的外部数据帧中。这消除了任何未使用的因子级别,而无需将所有数据加载到内存中。
# Step 1) Converts to character, in temporary xdf file:
rxDataStep(inData = "input.xdf", outFile = "temp.xdf", transforms = list(VAR_X = as.character(VAR_X)), overwrite = T)
# Step 2) Converts back to factor:
rxDataStep(inData = "temp.xdf", outFile = "output.xdf", transforms = list(VAR_X = as.factor(VAR_X)), overwrite = T)