我有一个包含因子的数据框 . 当我使用 subset()
或其他索引函数创建此数据框的子集时,会创建一个新的数据框 . 但是,因子变量保留其所有原始级别 - 即使它们不存在于新数据框中 .
这在进行分面绘图或使用依赖于因子水平的函数时会产生麻烦 .
在我的新数据框中从一个因子中删除级别的最简洁方法是什么?
这是我的例子:
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
## but the levels are still there!
levels(subdf$letters)
## [1] "a" "b" "c" "d" "e"
13 回答
查看
droplevels
方法code in the R source you can see它包装到factor
函数 . 这意味着您基本上可以使用factor
函数重新创建列 .在data.table方式下面,从所有因子列中删除级别 .
使用
dplyr
的另一种方法Edit:
还有效!感谢agenis
如果您不使用因子,请改用字符向量 . 我认为这比后来修补更有意义 . 在使用
read.table
或read.csv
加载数据之前,请尝试以下操作:缺点是您只能按字母顺序排序 . (重新排序是您的情节的朋友)
您需要做的就是在子集化后再次将factor()应用于您的变量:
EDIT
从因子页面示例:
要从数据框中的所有因子列中删除级别,您可以使用:
我写了实用程序函数来执行此操作 . 现在我知道了gdata的drop.levels,它看起来非常相似 . 他们在这里(来自here):
这是一个已知问题,gdata包中的
drop.levels()
提供了一种可能的补救措施,您的示例将成为Hmisc包中还有
dropUnusedLevels
函数 . 但是,它只能通过更改子集运算符[
来工作,并且不适用于此处 .作为必然结果,基于每列的直接方法很简单
as.factor(as.character(data))
:这是令人讨厌的 . 这就是我通常这样做,以避免加载其他包:
它让你:
请注意,新级别将替换在旧级别(subdf $ letters)中占用其索引的任何内容,因此类似于:
不行 .
当你有很多级别时,这显然不是理想的,但对于少数,它是快速和简单的 .
非常有趣的线程,我特别喜欢只想再次选择子选择的想法 . 之前我遇到过类似的问题,我只是转换为角色然后回到因素 .
这是另一种方式,我认为这相当于
factor(..)
方法:这是一种方法
为了完整起见,现在
forcats
包http://forcats.tidyverse.org/reference/fct_drop.html中也有fct_drop
.它与
droplevels
处理NA
的方式不同:自R版本2.12起,有一个
droplevels()
函数 .当我使用
data.frame
时,我现在在脚本的开头使用options(stringsAsFactors = FALSE)
. 因此,字符仍然是字符 . 因为,我不再有任何问题的问题:)