Próbuję uruchomić lm () tylko na podzbiorze moich danych i napotkałem problem.
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)
Powyższe nie działa, ponieważ w zestawie danych są teraz tylko mężczyźni, dlatego nie możemy włączyć do modelu zmiennej x3, zmiennej płci. ALE...
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
Czy to problem z notacją „znak minus” w formule? Proszę o poradę. Uwaga: Oczywiście mogę to zrobić w inny sposób; na przykład, mógłbym wykluczyć zmienne przed umieszczeniem ich w lm (). Ale prowadzę zajęcia na ten temat i nie chcę mylić uczniów, którzy już powiedzieli, że mogą wykluczyć zmienną za pomocą znaku minus w formule.
model.matrix(y ~ . - x3, data = dt[x3 == "men"])
imodel.matrix(y ~ x1 + x2, data = dt[x3 == "men"])
praca (lm
połączeniamodel.matrix
wewnętrzne). Jedyną różnicą między obiema matrycami modelu jest"contrasts"
atrybut (który wciąż zawierax3
), który zostaje później wykryty wlm
procedurze, prawdopodobnie powodując błąd, który widzisz. Mam więc wrażenie, że problem dotyczy sposobumodel.matrix
tworzenia i przechowywania matrycy projektu podczas usuwania terminów..
aby uzyskać uproszczoną formułę,terms(y ~ . -x3, data=dt, simplify=TRUE)
ale dziwnie nadal zachowujex3
atrybut zmiennych, który sięlm
neg.out=
opcja niezaimplementowana w R może być powiązana. Z plików pomocy S dlaterms
, gdzieneg.out=
jest zaimplementowany: flaga kontrolująca sposób traktowania haseł wprowadzanych znakiem „-”. Jeśli PRAWDA, warunki zostaną sprawdzone pod kątem anulowania i w inny sposób zignorowane. Jeśli FAŁSZ, negatywne warunki zostaną zachowane (w kolejności ujemnej).lm
wywołujemodel.matrix
zmodyfikowaną wersję danych. Na samym początku,lm
komponuje i ocenia następujące wyrażenie:mf <- stats::model.frame( y ~ . -x3, dt[x3=="men"], drop.unused.levels=TRUE )
. To powoduje,x3
że staje się czynnikiem jednopoziomowym.model.matrix()
są następnie wywoływanemf
, a nie oryginalne dane, co powoduje błąd, który obserwujemy.Odpowiedzi:
Występuje błąd, ponieważ x3 jest w modelu z tylko jedną wartością =
"men"
(patrz komentarz poniżej z @Artem Sokolov)Jednym ze sposobów rozwiązania tego jest podzbiór z wyprzedzeniem:
Lub możesz zrobić oba w tym samym kroku:
źródło
-x3
w formule nie powodujelm
, że próbujesz odjąć kolumnę. W „nie używaj x3 w modelu” intencją jest przekazywana poprawnie, ale problem jest to, żelm
rozmowymodel.frame( ..., drop.unused.levels=TRUE )
spowodowaniex3
, aby stać się czynnikiem single-level, co prowadzi do dalszych problemówmodel.matrix()
.