Estou tentando executar lm () em apenas um subconjunto dos meus dados e encontrando um problema.
dt = data.table(y = rnorm(100), x1 = rnorm(100), x2 = rnorm(100), x3 = as.factor(c(rep('men',50), rep('women',50)))) # sample data
lm( y ~ ., dt) # Use all x: Works
lm( y ~ ., dt[x3 == 'men']) # Use all x, limit to men: doesn't work (as expected)
O exemplo acima não funciona porque o conjunto de dados agora possui apenas homens e, portanto, não podemos incluir x3, a variável de gênero, no modelo. MAS...
lm( y ~ . -x3, dt[x3 == 'men']) # Exclude x3, limit to men: STILL doesn't work
lm( y ~ x1 + x2, dt[x3 == 'men']) # Exclude x3, with different notation: works great
Este é um problema com a notação "sinal de menos" na fórmula? Conselho por favor. Nota: Claro que posso fazer de uma maneira diferente; por exemplo, eu poderia excluir as variáveis antes de colocá-las em lm (). Mas estou dando uma aula sobre esse assunto e não quero confundir os alunos, já tendo dito a eles que podem excluir variáveis usando um sinal de menos na fórmula.
.
para obter uma fórmula simplificada com, terms(y ~ . -x3, data=dt, simplify=TRUE)
mas estranhamente ainda mantém x3
o atributo de variáveis que disparalm
neg.out=
pode estar relacionada. Nos arquivos de ajuda do S terms
, onde neg.out=
é implementado: sinalizador que controla o tratamento dos termos inseridos com o sinal "-". Se TRUE, os termos serão verificados quanto ao cancelamento e, caso contrário, serão ignorados. Se FALSE, termos negativos serão mantidos (com ordem negativa).
lm
chama model.matrix
uma versão modificada dos dados. Logo no início, lm
compõe e avalia a seguinte expressão: mf <- stats::model.frame( y ~ . -x3, dt[x3=="men"], drop.unused.levels=TRUE )
. Isso faz x3
com que se torne um fator de nível único. model.matrix()
é então chamado mf
, não os dados originais, resultando no erro que estamos observando.
model.matrix(y ~ . - x3, data = dt[x3 == "men"])
emodel.matrix(y ~ x1 + x2, data = dt[x3 == "men"])
trabalho (lm
chamadasmodel.matrix
internamente). A única diferença entre as duas matrizes de modelo é um"contrasts"
atributo (que ainda contémx3
) e é captado posteriormente nalm
rotina, provavelmente causando o erro que você está vendo. Então, sinto que a questão está relacionada à maneira comomodel.matrix
cria e armazena a matriz de design ao remover termos.