2016-04-17 1 views
1

J'ai une fonction que a besoin pour attendre un formula comme une entrée, sous la forme de y~x, par exemple. Ensuite, je dois passer une série de x-values dans cette formule pour sortir le y. Par exemple, si ma formule est y~x^2, et ma série de valeurs x est (1,2,3,4), alors je devrais attendre (1,4,9,16) en sortie.Comment convertir une formule en fonction, ou appliquer la formule à certaines valeurs?

Dire que j'ai la formule comme ceci: formula1 <- y~x:

Voici ce que j'ai essayé jusqu'ici:

  • Conversion de la formule en fonction: as.function(formula1)
  • En utilisant model.frame et model.matrix comme si :

Comme ceci:

formula1 <- y~x^2 
x <- c(1,2,3,4) 
my_data <- data.frame("x" = x, "y" = rep(0,length(x))) 
model_frame <- model.frame(formula1, data = my_data) 
my_design_matrix <- model.matrix(formula1, model_frame) 
  • J'essayé d'utiliser nls2, mais je n'ai pas de paramètres d'optimisation, donc je ne vois pas le point.

Que puis-je utiliser pour cela?

Voici les ressources que j'ai consultées:
How to apply a formula to a vector in R?

Pass formula to function in R?

Répondre

1

Je ne suis pas sûr que ce soit la façon la plus élégante, mais il devrait le faire que vous avez besoin:

L'idée est pour extraire le côté droit de l'objet de formule et l'analyser en tant que chaîne. Le résultat peut alors être évalué.

as.function <- function(formula) { 
    cmd <- tail(as.character(formula),1) 
    exp <- parse(text=cmd) 
    function(...) eval(exp, list(...)) 
} 

Notez cependant qu'il existe des formules valides qui ne peuvent pas être évalués de cette façon, par exemple y ~ a:c.

qui nous donne

> f <- as.function(y ~ x^2) 
> f(x=1:10) 
[1] 1 4 9 16 25 36 49 64 81 100 

Si vous souhaitez soumettre une data.frame à la fonction générée vous pouvez simplement faire

as.function <- function(formula) { 
    cmd <- tail(as.character(formula),1) 
    exp <- parse(text=cmd) 
    function(df) eval(exp, df) 
} 

et obtenir

> f <- as.function(y ~ x^2) 
> f(data.frame(x=1:10)) 
[1] 1 4 9 16 25 36 49 64 81 100 
+0

C'est chouette. Je vous remercie. – Candic3