2

如何以编程方式解析函数、参数及其返回值的名称?

我有兴趣使用drake 生成工作计划数据框以自动化 R 数据分析工作流。workplan可以使用该功能生成此类工作计划数据框。

我有一个 R 脚本,其中包含我想使用的功能。例如:

funA <- function(x){
  y <- x + 2
  y
}

funB <- function(y){
  z <- y^2
  z
}

我想以编程方式生成一个如下所示的数据框。如何解析函数名称、参数和返回值,并使用drake::workplan或其他函数创建这样的 data.frame?

  target command
1     y  funA(5)    
2     z  funB(3)      

一个人会像这样手动做到这一点:

my_plan <- drake::workplan(z=funB(5), y=funA(3))

然后使用以下命令运行工作流:

drake::make(my_plan)

谢谢你。

4

2 回答 2

3

假设你有一个这样的源文件:

funA <- function(x, y){
  y <- x + 2
  y

}

funB <- function(y){
  z <- y^2
  z

}

命名test.r,你可以做这样的事情:

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

这很脆弱但不太脆弱,因为它在 eval 和临时环境分配之前过滤掉了语言对象和函数。

我假设您可以从params列中提取参数名称,然后最终生成您需要的内容。

于 2017-11-08T20:55:49.533 回答
3

你可以得到论据formals()

funA <- function(x, b = "default"){
  y <- x + 2
  y
}    
formals(funA)

您还可以使用 and 提取函数的主体和body()环境environment()

无法获取函数的名称。一个函数实际上没有名字,一个名字指的是一个函数(如果你不知道名字,你怎么知道引用什么?)。

也没有办法获得返回值。在您的示例中,您可以通过手动解析函数来获取zand ,但这是一个非常糟糕的主意,并且只有在您以特定方式编写函数源时才有效。即使你这样做了,也没有任何意义。并在函数返回时被销毁。ybody()zy

也许你可以详细说明为什么你需要返回值和函数 namen,我相信还有另一种方法可以解决你想要实现的目标。

于 2017-11-08T20:31:07.133 回答