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.
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..
para obter uma fórmula simplificada com,terms(y ~ . -x3, data=dt, simplify=TRUE)
mas estranhamente ainda mantémx3
o atributo de variáveis que disparalm
neg.out=
pode estar relacionada. Nos arquivos de ajuda do Sterms
, ondeneg.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
chamamodel.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 fazx3
com que se torne um fator de nível único.model.matrix()
é então chamadomf
, não os dados originais, resultando no erro que estamos observando.Respostas:
O erro que você está recebendo é porque x3 está no modelo com apenas um valor =
"men"
(veja o comentário abaixo em @Artem Sokolov)Uma maneira de resolvê-lo é fazer um subconjunto com antecedência:
Ou você pode fazer as duas coisas na mesma etapa:
fonte
-x3
em uma fórmula não fazlm
pensar que você está tentando subtrair a coluna. O "não use x3 no modelo" intenção é comunicada corretamente, mas o problema é quelm
as chamadasmodel.frame( ..., drop.unused.levels=TRUE )
causandox3
a tornar-se um fator de nível único, levando a problemas a jusantemodel.matrix()
.