簡體   English   中英

將R中的任意函數列表組合成新函數[元編程]

[英]Combining arbitrary list of functions in R into new function [meta-programming]

我想獲取函數的任意列表,每個函數都帶有一個參數,然后將它們變成一個大函數,依次運行每個組成函數。

例如,讓我們看一下采用單個參數的三個函數( fgh )。 我想將它們作為參數提供給我的函數組合器,如下所示:

function_maker(f,g,h)

並輸出以下功能:

function(x) {
  f(x)
  g(x)
  h(x)
}

一個人怎么做? 作為參數提供的函數不會彼此“交互”,我只是希望它們按順序運行,而新函數返回的最終值就是按該順序求值所返回的值。

我主要擔心的是保持所有環境等正確無誤,以便新創建的函數可以在調用的任何環境中工作。

到目前為止,這是我所擁有的,但是我懷疑它非常脆弱:

f <- function(x) {
  print("this is f")
  x + 2
}
g <- function(x) {
  print("this is g")
  x + 4
}
h <- function(x) {
  print("this is h")
  x + 9
}

function_maker <- function(...) {
  l <- rlang::enexprs(...) %>%
    purrr::map(~substitute(zzzz(cond), c(zzzz=.)))
  e <- rlang::expr({!!!l})
  e <- rlang::expr(function(cond) !!e)
  rlang::eval_tidy(e)
}

fgh <- function_maker(f,g,h)
body(fgh)
fgh(2)

這似乎可以完成工作:

function_maker <- function(...) {
  ret  <- function(x) {}
  for(f in list(...)) {
    n <- length(body(ret))
    body(ret)[(n+1):(n + length(body(f)) - 1)] <- body(f)[-1]
  }
  ret
}

結果:

> function_maker(f, g, h)
function (x)
{
    print("this is f")
    x + 2
    print("this is g")
    x + 4
    print("this is h")
    x + 9
}

或者,一些更簡單的方法:

function_maker <- function(...) {
  calls <- mapply(function(x) paste0(x, "(x)"), as.list(substitute(list(...)))[-1])
  as.call(c(as.name("{"), parse(text=calls)))
}

結果是:

> function_maker(f,g,h)
{
    f(x)
    g(x)
    h(x)
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM