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 .
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
@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
@ 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) ... –