2015-09-16 14 views
12

Próbuję utworzyć bardziej oszczędną wersję rozwiązania this, co pociąga za sobą określenie RHS formuły w postaci d1 + d1:d2.Definiowanie operatora nawożenia do użycia w formule

Zważywszy, że * w kontekście formuły jest treściwy stand-in dla pełnej interakcji (tj d1 * d2 daje d1 + d2 + d1:d2), moje podejście było spróbować zdefiniować alternatywnego operatora, powiedzmy %+:% stosując podejście Infix ja już przyzwyczajeni w innych aplikacjach, a la:

"%+:%" <- function(d1,d2) d1 + d2 + d1:d2 

to jednak przewidywalny powiodło się, ponieważ nie byłem ostrożny oceny; niech wprowadzi przykład do zilustrowania moje postępy:

set.seed(1029) 
v1 <- runif(1000) 
v2 <- runif(1000) 
y <- .8*(v1 < .3) + .2 * (v2 > .25 & v2 < .8) - 
    .4 * (v2 > .8) + .1 * (v1 > .3 & v2 > .8) 

W tym przykładzie, mam nadzieję, że to jasne, dlaczego po prostu wypisując te dwa terminy mogą być niepożądane:

y ~ cut(v2, breaks = c(0, .25, .8, 1)) + 
    cut(v2, breaks = c(0, .25, .8, 1)):I(v1 < .3) 

Jeden obejście który jest zbliżony do mojego żądanego wyjścia jest określenie cały wzór jako funkcję:

plus.times <- function(outvar, d1, d2){ 
    as.formula(paste0(quote(outvar), "~", quote(d1), 
        "+", quote(d1), ":", quote(d2))) 
} 

daje oczekiwanych współczynników po przejściu do lm, ale z nazwami, że re trudniej zinterpretować bezpośrednio (zwłaszcza w rzeczywistych danych, gdzie dbamy aby dać d1 i d2 nazw opisowych, w przeciwieństwie do typowego przykładu):

out1 <- lm(y ~ cut(v2, breaks = c(0, .25, .8, 1)) + 
      cut(v2, breaks = c(0, .25, .8, 1)):I(v1 < .3)) 
out2 <- lm(plus.times(y, cut(v2, breaks = c(0, .25, .8, 1)), I(v1 < .3))) 
any(out1$coefficients != out2$coefficients) 
# [1] FALSE 
names(out2$coefficients) 
# [1] "(Intercept)"   "d1(0.25,0.8]"  "d1(0.8,1]"   "d1(0,0.25]:d2TRUE" 
# [5] "d1(0.25,0.8]:d2TRUE" "d1(0.8,1]:d2TRUE" 

Więc to jest mniej niż optymalne.

Czy istnieje sposób zdefiniowania korygowania kodu tak, aby operator infiksów, o którym wspomniałem powyżej, działał zgodnie z oczekiwaniami? Co powiesz na zmianę formy plus.times, aby zmienne nie zostały zmienione?

Byłem wywiercenie (?formula, ?"~", ?":", getAnywhere(formula.default), this odpowiedź, etc.), ale nie widać, jak dokładnie R interpretuje * kiedy to napotkanych w formule tak, że mogę uczynić moje pożądanych drobnych korekt .

+0

są one interpretowane w statystykach ::: model.frame.default wc https://github.com/wch/r-source/blob/ed66b715221d2720f5b334470335635bada520b1/src/library/stats/src/model.c#L888 – rawr

+0

@rawr dzięki. nie mogę powiedzieć, że mam pojęcie o tym, co dzieje się w kodzie C - widzę, że "definiują" każdy z symboli rozumianych przez "formułę", ale wydają się używać tylko "tyldaSymbola". Czy to znaczy, że nie będę mógł uzyskać własnego infiksu bez zejścia do C i zdefiniowania, powiedzmy, że "plusColonSymbol' jak tu jest? – MichaelChirico

+1

@ Odpowiedź HeatherTurner wydaje mi się całkiem słuszna. Jeśli naprawdę chcesz zacząć mieszać się z rozszerzającymi się formułami, proponuję zacząć od (1) oglądania komponentu "terms" wyników 'model.frame()' i (2) patrząc na kod [tutaj] (https) : //github.com/glmmTMB/glmmTMB/blob/master/glmmTMB/R/utils.R) ... –

Odpowiedz

6

W tym przypadku nie trzeba definiować nowego operatora: w formule d1/d2 rozwija się do d1 + d1:d2. Innymi słowy, d1/d2 określa, że ​​d2 jest zagnieżdżony w d1. Kontynuując swój przykład:

out3 <- lm(y ~ cut(v2,breaks=c(0,.25,.8,1))/I(v1 < .3)) 
all.equal(coef(out1), coef(out3)) 
# [1] TRUE 

dalszych uwag

Czynniki mogą być przekroczył lub zagnieżdżony. Przekracza się dwoma czynnikami, jeśli można zaobserwować każdą kombinację poziomów obu czynników, np. płeć i leczenie, temperatura i pH itd. Czynnik jest zagnieżdżony w innym, jeśli każdy poziom tego czynnika można zaobserwować tylko w obrębie jednego z poziomów innego czynnika, np. miasto i kraj, pracownik i sklep itp.

Zależności te znajdują odzwierciedlenie w parametryzacji modelu.W przypadku współczynników krzyżowych używamy d1*d2 lub d1 + d2 + d1:d2, aby dać główny efekt każdego czynnika plus interakcję. W przypadku czynników zagnieżdżonych używamy d1/d2 lub d1 + d1:d2, aby uzyskać osobny podmodel formularza 1 + d2 dla każdego poziomu d1.

Idea zagnieżdżania nie jest ograniczona do czynników, na przykład możemy użyć sex/x, aby dopasować osobną liniową regresję do x dla mężczyzn i kobiet.

W formule %in% jest odpowiednikiem :, ale może być użyty do podkreślenia zagnieżdżonej lub hierarchicznej struktury danych/modelu. Na przykład a + b %in% a jest taki sam jak a + a:b, ale odczytanie go jako "a plus b wewnątrz a" daje lepszy opis dopasowywanego modelu. Mimo to, używanie metody / ma tę zaletę, że upraszcza modelową formułę, jednocześnie podkreślając jej strukturę.

Powiązane problemy