2016-08-09 14 views
4

Ich habe etwas entlang der Linien vonWie kann ich einen Begriff in einer R-Formel durch zwei ersetzen?

y ~ x + z 

Und ich würde es zu transformieren möchte

y ~ x_part1 + x_part2 + z 

Allgemeiner würde ich eine Funktion haben wollen, die eine Formel nimmt und diese Formel mit Alle Begriffe, die mit "^ x $" übereinstimmen, werden durch "x_part1" und "x_part2" ersetzt. Hier ist meine aktuelle Lösung, aber es fühlt sich einfach so kludgey ...

my.formula <- fruit ~ apple + banana 
var.to.replace <- 'apple' 
my.terms <- labels(terms(my.formula)) 
new.terms <- paste0('(', 
        paste0(var.to.replace, 
          c('_part1', '_part2'), 
          collapse = '+'), 
        ')') 
new.formula <- reformulate(termlabels = gsub(pattern = var.to.replace, 
              replacement = new.terms, 
              x = my.terms),         
          response = my.formula[[2]]) 

Ein weiterer Nachteil ist, dass die Eingangsformel mit Wechselwirkungen festgelegt werden kann.

y ~ b*x + z 

ausgeben sollte eine dieser (äquivalent) Formeln

y ~ b*(x_part1 + x_part2) + z 
y ~ b + (x_part1 + x_part2) + b:(x_part1 + x_part2) + z 
y ~ b + x_part1 + x_part2 + b:x_part1 + b:x_part2 + z 

MrFlick die Verwendung von

Ersatz befürwortet (y ~ b * x + z, Liste (x = Zitat (x_part1 + x_part2)))

aber wenn ich die Formel I in einer variablen ändern möchten gespeichert, wie in

my.formula <- fruit ~ x + banana 

Dieser Ansatz scheint ein wenig mehr Massieren zu verlangen:

substitute(my.formula, list(x=quote(apple_part1 + apple_part2))) 
# my.formula 

Die notwendige Änderung dieser Ansatz war:

do.call(what = 'substitute', 
     args = list(apple, list(x=quote(x_part1 + x_part2)))) 

Aber ich kann nicht herausfinden, wie dieser Ansatz zu verwenden, wenn beide 'x' und c ('x_part', 'x_part2') werden in Variablen mit Namen gespeichert, z var.to.replace und new.terms oben.

Antwort

0

Wie über die Arbeit mit der Formel als Zeichenfolge zu ersetzen? Viele Basis-R-Modelle wie lm() akzeptieren eine Zeichenfolge Formeln (und Sie können immer formula() anderenfalls verwenden).In diesem Fall können Sie so etwas wie gsub() verwenden:

f1 <- "y ~ x + z" 
f2 <- "y ~ b*x + z" 

gsub("x", "(x_part1 + x_part2)", f1) 
#> [1] "y ~ (x_part1 + x_part2) + z" 

gsub("x", "(x_part1 + x_part2)", f2) 
#> [1] "y ~ b*(x_part1 + x_part2) + z" 

Zum Beispiel mit mtcars Datensatz, und sagen wir mpg (x) mit disp + hp (x_part1 + x_part2) ersetzt werden sollen:

f1 <- "qsec ~ mpg + cyl" 
f2 <- "qsec ~ wt*mpg + cyl" 

f1 <- gsub("mpg", "(disp + hp)", f1) 
f2 <- gsub("mpg", "(disp + hp)", f2) 

lm(f1, data = mtcars) 
#> 
#> Call: 
#> lm(formula = f1, data = mtcars) 
#> 
#> Coefficients: 
#> (Intercept)   disp   hp   cyl 
#> 22.04376  0.01017  -0.02074  -0.56571 

lm(f2, data = mtcars) 
#> 
#> Call: 
#> lm(formula = f2, data = mtcars) 
#> 
#> Coefficients: 
#> (Intercept)   wt   disp   hp   cyl 
#> 20.421318  1.554904  0.026837 -0.056141 -0.876182 
#>  wt:disp  wt:hp 
#> -0.006895  0.011126 
1

Wenn Sie nur Haupteffekte ändern möchten, können Sie x subtrahieren und die beiden neuen Variablen hinzufügen.

> f <- y ~ x + z 
> update(f, .~.-x+x_part1 + x_part2) 
y ~ z + x_part1 + x_part2 
+0

Wie können Sie x_part1 aus x machen? – rcorty

+0

Ich habe es mit Zeichen ('einfügen') gemacht und dann' as.formula' angewendet und das an das 'neue' Argument von 'update' übergeben. – rcorty

+0

ah, das Problem mit der Antwort ist, dass, wenn die ursprüngliche Formel Wechselwirkungen hat, ich glaube, sie sind in der neuen Formel verloren. Ich werde die Frage aktualisieren, um dieses Szenario zu verdeutlichen. – rcorty

3

Sie können eine rekursive Funktion schreiben Sie den Ausdrucksbaum der Formel zu ändern:

replace_term <- function(f, old, new){ 
    n <- length(f) 
    if(n > 1) { 
    for(i in 1:n) f[[i]] <- Recall(f[[i]], old, new) 

    return(f) 
    } 

    if(f == old) new else f 
} 

Welche Sie zB Interaktionen verändern können:

> replace_term(y~x*a+z - x, quote(x), quote(x1 + x2)) 
y ~ (x1 + x2) * a + z - (x1 + x2) 
+1

Die eingebaute 'substitute' Funktion macht das grundsätzlich. – MrFlick

5

Sie können die substitute verwenden Funktion hierfür

substitute(y ~ b*x + z, list(x=quote(x_part1 + x_part2))) 
# y ~ b * (x_part1 + x_part2) + z 

Hier verwenden wir die genannte Liste R zu sagen, die Variable x mit dem Ausdruck x_part1 + x_part2

+0

Das scheint sehr vielversprechend. Wie würde ich den Fall behandeln, in dem die Formel, die ich verwenden möchte, in einer Variablen gespeichert wird? Scheint so, als ob die Ersatzfunktion an dem Ausdruck arbeitet, den ich in das erste Argument geschrieben habe, nicht an den Wert dieses Ausdrucks? – rcorty

+0

Es ist mir unklar, wie genau Sie die Variablen "speichern", nicht Ihre Frage. Ich bin mir nicht sicher, welcher Teil des Ersatzes für Sie unklar ist. – MrFlick

+0

Ich habe am Ende der Frage etwas Text hinzugefügt, wo ich bessere Syntaxhervorhebung machen kann. Danke für Ihre Hilfe. – rcorty

Verwandte Themen