Estoy tratando de ejecutar lm () solo en un subconjunto de mis datos y me encuentro con un 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)
Lo anterior no funciona porque el conjunto de datos ahora solo tiene hombres y, por lo tanto, no podemos incluir x3, la variable de género, en el modelo. PERO...
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 es un problema con la notación de "signo menos" en la fórmula? Por favor aconséjame. Nota: Por supuesto que puedo hacerlo de otra manera; por ejemplo, podría excluir las variables antes de ponerlas en lm (). Pero estoy enseñando una clase sobre estas cosas, y no quiero confundir a los estudiantes, ya que les dije que pueden excluir variables usando un signo menos en la fórmula.
model.matrix(y ~ . - x3, data = dt[x3 == "men"])
ymodel.matrix(y ~ x1 + x2, data = dt[x3 == "men"])
trabajo (lm
llamadasmodel.matrix
internas). La única diferencia entre ambas matrices modelo es un"contrasts"
atributo (que todavía contienex3
) y que se recoge más adelante dentro de lalm
rutina, lo que probablemente cause el error que está viendo. Entonces, creo que el problema tiene que ver con cómomodel.matrix
crea y almacena la matriz de diseño al eliminar términos..
para obtener una fórmula simplificada,terms(y ~ . -x3, data=dt, simplify=TRUE)
pero curiosamente aún conservax3
el atributo de variables que se disparalm
neg.out=
opción no implementada en R podría estar relacionada. De los archivos de ayuda S paraterms
, dóndeneg.out=
se implementa: marca que controla el tratamiento de los términos que ingresan con el signo "-". Si es VERDADERO, los términos serán verificados para cancelación y de otra manera ignorados. Si es FALSO, los términos negativos se conservarán (con orden negativo).lm
llamadasmodel.matrix
en una versión modificada de los datos. En el principio,lm
compone y evalúa la siguiente expresión:mf <- stats::model.frame( y ~ . -x3, dt[x3=="men"], drop.unused.levels=TRUE )
. Esto hacex3
que se convierta en un factor de un solo nivel.model.matrix()
luego se llamamf
, no los datos originales, lo que resulta en el error que estamos observando.Respuestas:
El error que está recibiendo es porque x3 está en el modelo con un solo valor =
"men"
(vea el comentario a continuación de @Artem Sokolov)Una forma de resolverlo es subconjunto de antemano:
O puede hacer ambas cosas en el mismo paso:
fuente
-x3
en una fórmula no hacelm
pensar que estás tratando de restar la columna. El "no utilice x3 en el modelo de" intención se comunica correctamente, pero el problema es quelm
las llamadasmodel.frame( ..., drop.unused.levels=TRUE )
causandox3
a convertirse en un factor de un solo nivel, lo que lleva a problemas aguas abajo enmodel.matrix()
.