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.tablee read.csv, o argumento stringsAsFactors = TRUEpor 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. ggplote 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 Speciesconvertida 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.frames, o comportamento de [.data.frame()é diferente: consulte este e-mail ou ?"[.data.frame". Usar drop=TRUEno data.frames 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 ggplotlendas.
Internamente, factors 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 ggplotlendas. Se você falsificar fatores com vetores de personagens, existe o risco de alterar apenas um elemento e, acidentalmente, criar um novo nível separado.