2017-08-17 1 views
1

J'ai besoin d'une fonction créée par une liste de commandes pour l'évaluer complètement afin qu'elle soit identique à la version "manuelle" de la fonction. Contexte: J'utilise des fonctions ScaleR dans Microsoft R Server et j'ai besoin d'appliquer un ensemble de transformations en tant que fonction. Scaler est très pointilleux sur besoin d'être passé une fonction qui est formulée exactement comme indiqué ci-dessous:Evaluer les chaînes listées pour créer un objet fonction dans r

functionThatWorks <- function(data) { 
    data$marital_status_p1_ismarried <- impute(data$marital_status_p1_ismarried) 
    return(data) 
} 

J'ai une fonction qui crée cette liste de transformations (et des centaines d'autres, d'où la nécessité de fonctionnaliser son écriture).

transformList <- list ("data$ismarried <- impute(data$ismarried)", 
       "data$issingle <- impute(data$issingle)") 

Cette ligne fournit en sortie la chaîne évaluée que je veux la console, mais je ne connais pas un moyen de le déplacer de la sortie de la console d'être utilisé dans une fonction:

cat(noquote(unlist(bquote( .(noquote(transformList[1])))))) 

Je dois évalue functionIWant afin qu'il soit identique à functionThatWorks.

functionIWant <- function(data){ 
    eval( cat(noquote(unlist(bquote( .(noquote(transformList[1]))))))) 
    return(data) 
} 

identical(functionThatWorks, functionIWant) 

EDIT: Ajout dans la réponse basée sur le code de @dww. Cela fonctionne bien dans ScaleR. C'est identique, moins espacement sans signification.

functionIWant <- function(){} 
formals(functionIWant) <- alist(data=NULL) 
functionIWant.text <- parse(text = c(
    paste(bquote( .(noquote(transformList[1]))), ";", "return(data)\n") 
)) 
body(functionIWant) <- as.call(c(as.name("{"), functionIWant.text)) 
+0

peut-être essayer quelque chose avec eval (parse (text = ...)) ou eval (substitut (...)) –

+0

Merci, mais je l'ai fait beaucoup de danse autour de ce code en utilisant eval(), parse(), bquote(), unlist() et noquote() et n'ont pas eu de succès. Aucune tentative de combinaison ne crée un objet fonction identique à l'entrée "manual". L'objet fonction contient uniquement le code entré, pas ce que ce code devrait évaluer. – nb01

Répondre

0

Peut-être que quelque chose comme ça?

# 1st define a 'hard-coded' function  
f1 <- function (x = 2) 
{ 
    y <- x + 1 
    y^2 
} 

f1(3) 
# [1] 16 

# now create a similar function from a character vector 
f2 <- function(){} 
formals(f2) <- alist(x=2) 
f2.text <- parse(text = c('y <- x + 1', 'y^2')) 
body(f2) <- as.call(c(as.name("{"), f2.text)) 

f2(3) 
# [1] 16