如何在data.table存储函数名并通过lapply执行对应函数?
从data.table提取函数名并执行同名函数
我计划将待执行的函数名存储在data.table中,实际函数定义在代码的其他位置,再通过lapply调用并执行这些函数。我尝试过get和do.call方法,但似乎它们仅支持列表类型。目前我正尝试用parse/eval来解决该问题,请问是否有其他方法可以从data.table中提取函数名并执行同名函数?
以下是我的最新尝试代码:
library(DT) library(data.table) conds <- setDT(data.table( c( "Func1", "Func2", "Func3", "Func4"), #column 1 c( 7, 7, 7, 7), #column 2 c( 0, 8, 15, 22), #column 3 c( 7, 14, 21, 28) #column 4 )) lapply(1:nrow(conds), function(f) { func <- conds[[f, "V1"]] funcAsText <- deparse(func) newMyFunc <- eval(parse(text=funcAsText)) newMyFunc() }) Func1 <- function(x) { x <- 1 print(x) } Func2 <- function(x) { x <- 1+1 print(x) } Func3 <- function(x) { x <- 1+2 print(x) } Func4 <- function(x) { x <- 1+3 print(x) }
问题修正与解决方案
首先,你的代码存在一个基础问题:函数定义在lapply调用之后,导致执行lapply时函数尚未被创建,会触发找不到函数的错误。请先将函数定义移至lapply调用之前。
其次,get和do.call并非仅支持列表类型,它们完全可以处理从data.table提取字符型函数名并执行的场景,以下是几种更简洁的实现方式:
方法1:用get直接获取并执行函数
get()可以从当前环境中提取指定名称的对象(包括函数),直接传入字符型函数名即可:
library(data.table) # 先定义函数 Func1 <- function(x) { x <- 1 print(x) } Func2 <- function(x) { x <- 1+1 print(x) } Func3 <- function(x) { x <- 1+2 print(x) } Func4 <- function(x) { x <- 1+3 print(x) } # 构造data.table conds <- setDT(data.table( V1 = c("Func1", "Func2", "Func3", "Func4"), V2 = c(7, 7, 7, 7), V3 = c(0, 8, 15, 22), V4 = c(7, 14, 21, 28) )) # 遍历函数名执行 lapply(conds$V1, function(func_name) { get(func_name)() # 你的函数参数x未实际使用,所以传空括号调用 })
方法2:用do.call执行函数
do.call可直接接收字符型函数名,第二个参数是函数所需的参数列表:
lapply(conds$V1, function(func_name) { do.call(func_name, args = list()) # args为函数参数列表,此处为空 })
方法3:贴合data.table风格的写法
如果需要用到data.table中的其他列作为函数参数,可结合by行遍历实现:
# 修改函数,实际接收参数 Func1 <- function(x) { print(x) } Func2 <- function(x) { print(x + 1) } Func3 <- function(x) { print(x + 2) } Func4 <- function(x) { print(x + 3) } # 按行遍历,将V2列作为参数传入对应函数 conds[, .(result = get(V1)(V2)), by = seq_len(nrow(conds))]
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

