2012-08-24 21 views
5

Gracias de antemano, y lo siento si esta pregunta ha sido respondida anteriormente. He buscado bastante extensamente. Tengo un conjunto de datos que contiene una fila de información concatenada, específicamente: nombre, código de color, alguna expresión de función. Por ejemplo, un valor puede ser:Crear una lista de funciones a partir de un vector de caracteres

costo # FF0033 @ log (x) +6.

Tengo todo el código para extraer la información, y termino con un vector de expresiones que me gustaría convertir a una lista de funciones reales.

Por ejemplo:

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

donde test.func es el vector de expresiones. Lo que me gustaría es:

func.list[[3]] 

que es equivalente a

function(x){x+3} 

Sé que puedo crear una función usando:

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

para convertir un valor de carácter en una función. El problema surge cuando intento hacer un loop para realizar múltiples funciones. Para un ejemplo de algo que he intentado no ha funcionado:

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

Basado en otro post (http://stats.stackexchange.com/questions/3836/how-to-create-a-vector-of -Funciones) también probé esto:

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])))) 
} 

que da el siguiente error: error en eval (expr, envir, enclos): objeto de 'x' que no se encuentra

el objetivo final es tomar la lista de funciones y aplique la función jth a la j-ésima columna de data.frame, para que el usuario del script pueda especificar cómo normalizar cada columna umn dentro de la información concatenada dada por el encabezado de columna.

Respuesta

3

inicializar Tal vez su lista con una sola función genérica, y luego actualizarlos usando:

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

Más específicamente, a partir de un personaje, lo que probablemente hacer algo como:

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

Gracias !! Funcionó perfectamente. Agregaré el código que utilicé para completar la tarea como una respuesta adicional para otros usuarios una vez que SO me permita hacerlo. (y disculpe por todos los comentarios/ediciones/eliminaciones/y lo que sea - obviamente soy nuevo en SO) – dayne

+0

@dayne Yo diría que ha tomado las cosas muy bien, en comparación con el visitante SO medio nuevo. – joran

2

Solo para agregar a la respuesta de joran, esto es lo que finalmente funcionó:

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)) 

Gracias aga en, joran.

1

Esto es lo que hago:

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) 
Cuestiones relacionadas