Ich versuche eine sparsamere Version der this Lösung zu erstellen, die die Angabe der RHS einer Formel in der Form d1 + d1:d2
beinhaltet.Definition eines Infix-Operators zur Verwendung in einer Formel
Da *
in Zusammenhang mit einer Formel ist ein prägnanter Stand-in für die vollständige Interaktion (dh d1 * d2
gibt d1 + d2 + d1:d2
), hat mein Ansatz gewesen, einen alternativen Betreiber zu versuchen und zu definieren, sagen %+:%
den Infix-Ansatz Ich habe in anderen Anwendungen gewohnt gewachsen, a la:
"%+:%" <- function(d1,d2) d1 + d2 + d1:d2
dies ist jedoch nicht vorhersagbar, weil ich über Auswertung nicht vorsichtig gewesen; Lassen Sie uns ein Beispiel vorstellen zu meinen Fortschritt veranschaulichen:
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)
Mit diesem Beispiel, es ist hoffentlich klar, warum nur die beiden Begriffe auszuschreiben könnte unerwünscht sein:
y ~ cut(v2, breaks = c(0, .25, .8, 1)) +
cut(v2, breaks = c(0, .25, .8, 1)):I(v1 < .3)
Eine Abhilfe, die auf meine gewünschte Ausgabe Nähe ist die gesamte Formel als eine Funktion zu definieren:
plus.times <- function(outvar, d1, d2){
as.formula(paste0(quote(outvar), "~", quote(d1),
"+", quote(d1), ":", quote(d2)))
}
dies das erwartete Koeffizienten gibt, wenn zu lm
, aber mit den Namen übergeben, die ein re schwieriger zu interpretieren direkt (vor allem in den realen Daten, wo wir kümmern d1
und d2
Namen, im Gegensatz zu diesem allgemeinen Beispiel geben):
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"
Also das weniger als optimal ist.
Gibt es eine Möglichkeit, den Code so anzupassen, dass der oben erwähnte Infix-Operator wie erwartet funktioniert? Wie wäre es, die Form von plus.times
so zu ändern, dass die Variablen nicht umbenannt werden?
Ich habe Stochern (?formula
, ?"~"
, ?":"
, getAnywhere(formula.default)
, this Antwort, etc.), aber noch nicht gesehen, wie genau R *
interpretiert, wenn es in einer Formel begegnet ist, so dass ich meine gewünschten kleineren Anpassungen vornehmen kann .
sie in Statistiken ::: model.frame.default in c interpretiert https://github.com/wch/r-source/blob/ed66b715221d2720f5b334470335635bada520b1/src/library/stats/src/model.c#L888 – rawr
@rawr danke. Ich kann nicht sagen, dass ich eine Ahnung davon habe, was im C-Code vor sich geht - ich sehe, dass sie jedes der Symbole definieren, die von 'formula' verstanden werden, aber sie scheinen nur' tildeSymbol' zu verwenden. Bedeutet das überhaupt, dass ich nicht in der Lage sein werde, mein eigenes Infix zu bekommen, ohne zu C & defining zu gehen, sagen wir "plusColonSymbol" wie hier? – MichaelChirico
@ HeatherTurner Antwort scheint genau richtig zu mir. Wenn Sie wirklich anfangen wollen, sich mit expandierenden Formeln zu messen, würde ich vorschlagen, mit (1) die 'terms' Komponente der Ergebnisse von' model.frame() 'zu betrachten und (2) den Code [hier] zu betrachten (https : //github.com/glmmTMB/glmmTMB/blob/master/glmmTMB/R/utils.R) ... –