2012-08-24 25 views
5

Grazie in anticipo, e scusate se questa domanda ha avuto una risposta in precedenza, mi è sembrato molto estesamente. Ho un set di dati contenente una riga di informazioni concatenate, in particolare: nome, codice colore, qualche espressione di funzione. Ad esempio, un valore può essere:Creare un elenco di funzioni da un vettore di caratteri

costo n. FF0033 @ log (x) +6.

Ho tutto il codice per estrarre le informazioni e alla fine ho un vettore di espressioni che vorrei convertire in un elenco di funzioni effettive.

Ad esempio:

func.list <- list() 
test.func <- c("x","x+1","x+2","x+3","x+4") 

dove test.func è il vettore di espressioni. Quello che vorrei è:

func.list[[3]] 

equivalente a

function(x){x+3} 

So che posso creare una funzione utilizzando:

somefunc <- function(x){eval(parse(text="x+1"))} 

per convertire un valore di carattere in una funzione. Il problema si presenta quando provo ad andare in loop per creare più funzioni. Per un esempio di qualcosa che ho provato non ha funzionato:

for(i in 1:length(test.func)){ 
    temp <- test.func[i] 
    f <- assign(function(x){eval(expr=parse(text=temp))}) 
    func.list[[i]] <- f 
} 

Sulla base di un altro post (http://stats.stackexchange.com/questions/3836/how-to-create-a-vector-of -Funzioni) ho provato anche questo:

makefunc <- function(y){y;function(x){y}} 
for(i in 1:length(test.func)){ 
    func.list[[i]] <- assign(x=paste("f",i,sep=""),value=makefunc(eval(parse(text=test.func[i])))) 
} 

che dà il seguente errore: errore in eval (espressione, Envir, enclos): oggetto 'x' non trovato

l'obiettivo finale è quello di prendere la lista di funzioni e applicare la funzione jth alla colonna jth del data.frame, in modo che l'utente dello script possa specificare come normalizzare ogni colonna umn all'interno delle informazioni concatenate fornite dall'intestazione della colonna.

risposta

3

Forse inizializzare la vostra lista con una singola funzione generica, e quindi aggiornare usando:

foo <- function(x){x+3} 
> body(foo) <- quote(x+4) 
> foo 
function (x) 
x + 4 

In particolare, a partire da un personaggio, si sarebbe probabilmente fare qualcosa di simile:

body(foo) <- parse(text = "x+5") 
+0

Grazie !! Ha funzionato perfettamente. Aggiungerò il codice che ho usato per completare l'attività come risposta aggiuntiva per altri utenti una volta che SO mi consentirà di farlo. (e mi dispiace per tutti i commenti/modifiche/eliminazioni/e quant'altro - Sono ovviamente nuovo a SO) – dayne

+0

@dayne Direi che hai ottenuto la mano delle cose bene, rispetto al visitatore SO nuovo di zecca medio. – joran

2

Solo per aggiungere la risposta di joran, questo è ciò che ha funzionato alla fine:

test.data <- matrix(data=rep(1,25),5,5) 
test.data <- data.frame(test.data) 

test.func <- c("x","x+1","x+2","x+3","x+4") 
func.list <- list() 

for(i in 1:length(test.func)){ 
    func.list[[i]] <- function(x){} 
    body(func.list[[i]]) <- parse(text=test.func[i]) 
} 

processed <- mapply(do.call,func.list,lapply(test.data,list)) 

Grazie aga in, joran.

1

Questo è quello che faccio:

f <- list(identity="x",plus1 = "x+1", square= "x^2") 
funCreator <- function(snippet){ 
    txt <- snippet 
    function(x){ 
    exprs <- parse(text = txt) 
    eval(exprs) 
    } 
} 
listOfFunctions <- lapply(setNames(f,names(f)),function(x){funCreator(x)}) # I like to have some control of the names of the functions 
listOfFunctions[[1]] # try to see what the actual function looks like? 
library(pryr) 
unenclose(listOfFunctions[[3]]) # good way to see the actual function http://adv-r.had.co.nz/Functional-programming.html 
# Call your funcions 
listOfFunctions[[2]](3) # 3+1 = 4 
do.call(listOfFunctions[[3]],list(3)) # 3^2 = 9 
attach(listOfFunctions) # you can also attach your list of functions and call them by name 
square(3) # 3^2 = 9 
identity(7) # 7 ## masked object identity, better detach it now! 
detach(listOfFunctions) 
Problemi correlati