R 中的基本数据类型之一是因子。根据我的经验,因素基本上是一种痛苦,我从不使用它们。我总是转换为字符。我奇怪地觉得我错过了什么。
是否有一些重要的函数示例使用因子作为需要因子数据类型的分组变量?是否有特定情况下我应该使用因子?
最佳答案
你应该使用因子。是的,它们可能很痛苦,但我的理论是,它们痛苦的 90% 是因为在 read.table
和 read.csv
中,参数 stringsAsFactors = TRUE
默认情况下(大多数用户都忽略了这个微妙之处)。我说它们很有用,因为像 lme4 这样的模型拟合包使用因子和有序因子来差异地拟合模型并确定要使用的对比类型。图形包也使用它们进行分组。 ggplot
和大多数模型拟合函数将字符向量强制为因子,因此结果相同。但是,您最终会在代码中收到警告:
lm(Petal.Length ~ -1 + Species, data=iris)
# Call:
# lm(formula = Petal.Length ~ -1 + Species, data = iris)
# Coefficients:
# Speciessetosa Speciesversicolor Speciesvirginica
# 1.462 4.260 5.552
iris.alt <- iris
iris.alt$Species <- as.character(iris.alt$Species)
lm(Petal.Length ~ -1 + Species, data=iris.alt)
# Call:
# lm(formula = Petal.Length ~ -1 + Species, data = iris.alt)
# Coefficients:
# Speciessetosa Speciesversicolor Speciesvirginica
# 1.462 4.260 5.552
一件棘手的事情是整个
drop=TRUE
位。在向量中,这可以很好地去除不在数据中的因素级别。例如:s <- iris$Species
s[s == 'setosa', drop=TRUE]
# [1] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [11] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [21] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [31] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [41] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# Levels: setosa
s[s == 'setosa', drop=FALSE]
# [1] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [11] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [21] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [31] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [41] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# Levels: setosa versicolor virginica
但是,对于
data.frame
s, [.data.frame()
的行为是不同的:参见 this email 或 ?"[.data.frame"
。在 drop=TRUE
s 上使用 data.frame
并不像您想象的那样工作:x <- subset(iris, Species == 'setosa', drop=TRUE) # susbetting with [ behaves the same way
x$Species
# [1] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [11] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [21] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [31] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [41] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# Levels: setosa versicolor virginica
幸运的是,您可以使用
droplevels()
轻松删除因子以删除单个因子或 data.frame
中的每个因子的未使用因子级别(自 R 2.12):x <- subset(iris, Species == 'setosa')
levels(x$Species)
# [1] "setosa" "versicolor" "virginica"
x <- droplevels(x)
levels(x$Species)
# [1] "setosa"
这是如何防止您选择的级别进入
ggplot
图例。在内部,
factor
是具有属性级字符向量的整数(参见 attributes(iris$Species)
和 class(attributes(iris$Species)$levels)
),这是干净的。如果您必须更改级别名称(并且您使用的是字符串),这将是一个效率低得多的操作。而且我经常更改关卡名称,尤其是对于 ggplot
图例。如果您使用字符向量伪造因子,则存在仅更改一个元素并意外创建一个单独的新关卡的风险。关于r - R : more than an annoyance?中的因素,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3445316/