Você deve usar fatores. Sim, eles podem ser uma dor, mas minha teoria é que 90% da razão pela qual eles são uma dor é porque em read.table
e read.csv
, o argumento stringsAsFactors = TRUE
por padrão (e a maioria dos usuários não percebe essa sutileza). Eu digo que eles são úteis porque os pacotes de ajuste de modelo como o lme4 usam fatores e fatores ordenados para ajustar os modelos de forma diferenciada e determinar o tipo de contraste a ser usado. E os pacotes de gráficos também os usam para agrupar. ggplot
e a maioria das funções de ajuste de modelo coage os vetores de caracteres a fatores, de modo que o resultado é o mesmo. No entanto, você acaba com avisos em seu código:
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
Mensagem de aviso: Em model.matrix.default(mt, mf, contrasts)
:
variável Species
convertida em umfactor
Uma coisa complicada é a parte inteira drop=TRUE
. Em vetores, isso funciona bem para remover níveis de fatores que não estão nos dados. Por exemplo:
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
Porém , com data.frame
s, o comportamento de [.data.frame()
é diferente: consulte este e-mail ou ?"[.data.frame"
. Usar drop=TRUE
no data.frame
s não funciona como você imagina:
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
Felizmente, você pode eliminar fatores facilmente com droplevels()
a redução dos níveis de fator não utilizados para um fator individual ou para cada fator em a data.frame
(desde R 2.12):
x <- subset(iris, Species == 'setosa')
levels(x$Species)
# [1] "setosa" "versicolor" "virginica"
x <- droplevels(x)
levels(x$Species)
# [1] "setosa"
É assim que você evita que os níveis selecionados cheguem às ggplot
lendas.
Internamente, factor
s são inteiros com um vetor de caracteres de nível de atributo (consulte attributes(iris$Species)
e class(attributes(iris$Species)$levels)
), que é limpo. Se você tivesse que alterar o nome de um nível (e estivesse usando cadeias de caracteres), esta seria uma operação muito menos eficiente. E eu mudo muito os nomes dos níveis, especialmente para ggplot
lendas. Se você falsificar fatores com vetores de personagens, existe o risco de alterar apenas um elemento e, acidentalmente, criar um novo nível separado.