解析R函数名、参数和返回值
如何通过编程解析函数名、参数名及其返回值 我对使用解析R函数名、参数和返回值,r,reproducible-research,R,Reproducible Research,如何通过编程解析函数名、参数名及其返回值 我对使用drake自动生成R数据分析工作流的工作计划数据帧感兴趣。可以使用workplan函数生成这样的工作计划数据帧 我有一个R脚本,其中包含我想要使用的函数。例如: funA <- function(x){ y <- x + 2 y } funB <- function(y){ z <- y^2 z } 我们可以这样用手来做: my_plan <- drake::workplan(z=funB(5),
drake
自动生成R数据分析工作流的工作计划数据帧感兴趣。可以使用workplan
函数生成这样的工作计划数据帧
我有一个R脚本,其中包含我想要使用的函数。例如:
funA <- function(x){
y <- x + 2
y
}
funB <- function(y){
z <- y^2
z
}
我们可以这样用手来做:
my_plan <- drake::workplan(z=funB(5), y=funA(3))
funA <- function(x, y){
y <- x + 2
y
}
funB <- function(y){
z <- y^2
z
}
library(purrr)
library(dplyr)
fenv <- new.env()
parse("test.r") %>%
keep(is.language) %>%
keep(~grepl(", function", toString(.x))) %>%
map(eval, envir=fenv) %>%
map_df(~{
params <- list(names(formals(.x)))
bdy <- deparse(body(.x))
bdy <- bdy[length(bdy)-1]
data_frame(target = trimws(bdy), params = params)
}) %>%
mutate(fname = ls(fenv))
谢谢。您可以使用
formals()获取参数。
funA假设您有这样一个源文件:
my_plan <- drake::workplan(z=funB(5), y=funA(3))
funA <- function(x, y){
y <- x + 2
y
}
funB <- function(y){
z <- y^2
z
}
library(purrr)
library(dplyr)
fenv <- new.env()
parse("test.r") %>%
keep(is.language) %>%
keep(~grepl(", function", toString(.x))) %>%
map(eval, envir=fenv) %>%
map_df(~{
params <- list(names(formals(.x)))
bdy <- deparse(body(.x))
bdy <- bdy[length(bdy)-1]
data_frame(target = trimws(bdy), params = params)
}) %>%
mutate(fname = ls(fenv))
产生:
## # A tibble: 2 x 3
## target params fname
## <chr> <list> <chr>
## 1 y <chr [2]> funA
## 2 z <chr [1]> funB
####一个tible:2x3
##目标参数fname
##
##1 y funA
##2 z funB
这是脆弱的,但不太脆弱,因为它在赋值和临时环境之前过滤掉了语言对象和函数
我假设您可以从params
列中提取参数名称,然后最终生成所需的内容。是否要解析原始脚本文本文件而不执行它?或者这些是您正在加载到活动R会话中的对象吗?@MrFlick:我想通过执行类似于source(“functions.R”)
的操作来解析我正在加载到活动R会话中的对象。如果您确实想对特定文件进行源代码分析,可以查看parse(“functions.R”)
。我仍然认为您试图做的有点不可靠,但我对drake了解不够,无法给您任何真正的提示:/n您可以使用lsf.str()
列出所有指向函数的变量。感谢lsf.str()
提示,@MrFlick@Stefan F:为什么手动解析函数体是个坏主意?我的意思是,你从函数中返回变量的名称中获取函数值的名称的策略听起来真是个坏主意。我试图在我的回答中解释它,我不知道如何更好地陈述它。还要注意,通过body()
获得的源代码可能与编写函数时的原始源代码不同(主要是格式化)。我认为您最好的选择是按照hrbrmstr的建议熟悉parse()
。谢谢您的回答,@StefanFThank you,@hrbrmstr。我要试试这个。