2017-05-01 2 views
0

Ich versuche, einen String-Eingang für eine Funktion zu verwenden, die dann beispielsweise in nutzbare Form in R. umgewandelt werden muss:R: Konvertieren eine Zeichenfolge aus einer Funktion eingegeben Teil eines Ausdrucks in der Funktion

Ich habe folgende Funktion:

MyFunction <- function(MyDataFrame){ 
Fit <- aov(VariableA ~ A * B * C, MyDataFrame) 
model = lme(VariableA ~ A * B * C, random=~1| Sample, method="REML", MyDataFrame) 
return(anova(model)) 
} 

Das funktioniert gut. Manchmal möchte ich jedoch verschiedene Formeln mit einer einzigen Funktion verwenden, so dass mein "Ausdruck" "A * B * C" oder "A * C" sein kann. Ich versuchte mit:

MyFunction <- function(MyDataFrame, Expression = "A * B * C"){ 
Fit <- aov(VariableA ~ Expression, MyDataFrame) 
model = lme(VariableA ~ Expression, random=~1| Sample, method="REML", MyDataFrame) 
return(anova(model)) 
} 

Dies funktioniert nicht. Irgendwelche Vorschläge?

+1

Versuchen 'as.formula (paste0 ("Variablea ~", Expression))' – Lamia

+0

Verwenden eine Formel anstelle einer Zeichenkette, dh 'Ausdruck = ~ A * B * C 'und dann' lme (update (VariableA ~., Ausdruck)) 'innerhalb Ihrer Funktion. Der Aufruf von 'update' aktualisiert Ihre Formel' VariableA ~ .' auf 'VariableA ~ A * B * C' – yeedle

Antwort

1

R wissen muss, dass die Formel ist eigentlich eine Formel, und Sie laufen in Probleme mit der Auswertung von Ausdrücken, Umgebungen und so weiter, wenn Sie eine Zeichenfolge, die Sie wollen, wie ein verwenden, Ausdruck in einer Formel. Nach dem, was es sieht aus wie Sie versuchen zu tun, würde ich wahrscheinlich meine Funktion wie so ein:

library(nlme) 

fun <- function(df, response, predictors){ 
    model_formula <- as.formula(paste0(response, " ~ ", predictors)) 
    fit <- aov(model_formula, df) 
    model = nlme::lme(model_formula, df) 
    return(anova(model)) 
} 

fun(Orthodont, "distance", "age") 
#>    numDF denDF F-value p-value 
#> (Intercept)  1 80 3096.4889 <.0001 
#> age    1 80 85.8464 <.0001 
fun(Orthodont, "distance", "age + Sex") 
#>    numDF denDF F-value p-value 
#> (Intercept)  1 80 4226.931 <.0001 
#> age    1 80 111.949 <.0001 
#> Sex    1 25 4.429 0.0456 
1

Für Ihre Zwecke müssen Sie nicht einmal Zeichenfolgen verwenden, Sie könnten den Ausdruck direkt übergeben und match.call() mit einem eval() verwenden. Ein Spielzeug Beispiel ist:

fun <- function(data, expression){ 
    m <- match.call() 
    lm(hp ~ eval(m$expression), data) 
} 


fun(mtcars, cyl) 
#Call: 
#lm(formula = hp ~ eval(m$expression), data = data) 

#Coefficients: 
#  (Intercept) eval(m$expression) 
#   -51.05    31.96 
+1

Sie brauchen nicht einmal den match.call Teil. Sie können 'lm (update (hp ~., expression), data)' verwenden und dann die Funktion wie 'fun (mtcars, ~ cyl)' aufrufen – yeedle

Verwandte Themen