Вы должны использовать факторы. Да, они могут причинять боль, но моя теория состоит в том, что 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
Предупреждающее сообщение: В model.matrix.default(mt, mf, contrasts)
:
переменная Species
преобразована в factor
Одна хитрая вещь - это целый 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()
отличается: см. в этом письме или ?"[.data.frame"
. Использование drop=TRUE
на data.frame
s не работает, как вы думаете:
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
s являются целыми числами с векторным символом уровня атрибута (см. attributes(iris$Species)
и class(attributes(iris$Species)$levels)
), который является чистым. Если бы вам пришлось изменить имя уровня (и вы использовали строки символов), это было бы на намного менее эффективной операцией. И я сильно меняю названия уровней, особенно для ggplot
легенд. Если вы имитируете факторы с помощью векторов символов, есть риск, что вы измените только один элемент и случайно создадите отдельный новый уровень.