从字符向量创建函数列表

7
感谢您的提前帮助,如果这个问题之前已经得到解答,我很抱歉——我已经进行了相当广泛的搜索。我有一个数据集包含一行连接信息,具体来说是:名称、颜色代码、一些函数表达式。例如,一个值可能是:
cost#FF0033@log(x)+6.
我已经编写好了提取信息的所有代码,并且最终获得了一个表达式向量,我想将其转换为实际函数列表。
例如:
func.list <- list()
test.func <- c("x","x+1","x+2","x+3","x+4")

其中test.func是表达式向量。我希望的是:

func.list[[3]]

相当于
function(x){x+3}

我知道可以使用以下方法创建一个函数:

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

将字符值转换为函数。当我尝试循环进行多个函数时,问题就出现了。以下是我尝试但未成功的示例:

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

基于另一篇文章(http://stats.stackexchange.com/questions/3836/how-to-create-a-vector-of-functions),我也尝试了以下代码:

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

这会导致以下错误:Error in eval(expr, envir, enclos) : object 'x' not found

最终的目标是将函数列表应用于数据框的第j列,以便脚本的用户可以指定如何规范化列头所给出的连接信息中的每一列。

3个回答

4
也许可以使用一个通用函数初始化您的列表,然后使用以下方法进行更新:
foo <- function(x){x+3}
> body(foo) <- quote(x+4)
> foo
function (x) 
x + 4

更具体地说,从一个字符开始,您可能会执行以下操作:
body(foo) <- parse(text = "x+5")

谢谢!它完美地运行了。一旦SO允许我这样做,我将添加我用来完成任务的代码作为其他用户的额外答案。(对于所有的评论/编辑/删除/等等,我很抱歉 - 我显然是SO的新手) - dayne
@dayne,我认为你已经比普通的全新SO访问者更好地掌握了事物。 - joran

2

补充joran的回答,以下是最终解决方案:

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

再次感谢你,joran。


2

我所从事的工作:

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)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接