【问题标题】:Use assign to create multiple functions inside of a function in R使用assign在R中的函数内部创建多个函数
【发布时间】:2017-05-28 04:03:55
【问题描述】:

我想创建一些功能略有不同的函数,并且每个函数都可以接受一个全局变量。

我使用assign 将函数this_value 分配给它应该具有的名称this_key。它应该创建的三个函数是func_afunc_bfunc_c

每个新创建的函数都应该能够接受输入 x 并对 x 执行特定于该函数的操作;在这种情况下,打印“key_name:name ----- value_x:x”。所以name应该取决于函数是func_afunc_b,还是func_c;例如,调用func_a 应该给我们“key_name:a”。

to_name <- c("a", "b", "c")

create_funcs <- function() {
  all_funcs <- list()

  for (name in to_name) {
    this_key <- paste0("func_", name)

    this_value <<- function(x) { 
      paste0("key_name:  ", name, " -----  value_x: ", x)
    }
    assign(this_key, this_value, envir = .GlobalEnv) 

    all_funcs <- c(all_funcs, this_key)
  }
  return(all_funcs)
}

create_funcs()

但是,在创建函数之后,它们每个都只返回一个“c”的name,或者向量中的最后一个值to_name

func_a("foo")  # key_name:  c -----  value_x: foo
func_b("bar")  # key_name:  c -----  value_x: bar

相反,func_a("foo") 应该返回“key_name: a ----- value_x: foo”。

对于它的价值,这适用于类似的对象分配功能:

create_objects <- function() {
  all_objs <- list()

  for (name in to_name) {
    this_key <- paste0("key_", name)

    this_value <- paste0("value_", name)

    assign(this_key, this_value, envir = .GlobalEnv)

    all_objs <- c(all_objs, this_key)
  }
  return(all_objs)
}

create_objects()

例子:

key_a  # value_a

感谢观看!

【问题讨论】:

    标签: r


    【解决方案1】:

    我不完全确定这是否能解决您的问题,因为您的实际用例可能比这个可重现的示例更复杂。但您可能想查看purrr::partial

    这是我使用该功能想出的一个可能的解决方案。

    library(purrr)
    
    func_ <- function(x, key_name) {
      paste0("key_name:  ", key_name, " -----  value_x: ", x)
    }
    
    
    func_a <- partial(func_, key_name = "a")
    
    func_a("foo")
    
    #> [1] "key_name:  a -----  value_x: foo"
    
    
    assign("func_b", partial(func_, key_name = "b"))
    
    func_b("foo")
    
    #> [1] "key_name:  b -----  value_x: foo"
    

    编辑:

    在这里,您可以使用 purrr::walk 获取字符向量并迭代每个元素(如使用 for 循环),为每个元素创建一个新函数。您只需确保在assign() 调用中将环境设置为.GlobalEnv。我对这样的事情的环境范围了解不多,并且觉得我已经读过这有时可能是一个坏主意,但它似乎做了你所描述的事情。希望这会有所帮助。

    letters %>% walk(~ assign(x = paste0("func_", .x),
                              value = partial(func_, key_name = .x),
                              envir = .GlobalEnv))
    
    func_x("foo")
    
    #> [1] "key_name:  x -----  value_x: foo"
    

    【讨论】:

    • 一件事是我仍然希望能够在 for 循环中进行分配,因此我不必在函数之外单独命名每个函数。像all_funcs &lt;- c(all_funcs, partial(func_, name = name, envir = .GlobalEnv)) 这样的东西给出与上面相同的结果(即func_a("foo") # key_name: c ----- value_x: foo
    • @amanda 我已经编辑了答案以添加一个使用循环创建多个这样的函数的示例。希望对你有帮助
    • 完美,非常感谢。我想我最好上purrr 火车!
    • @amanda 很高兴这很有帮助。是的,purrr 很棒——除了purrr.tidyverse.org,你可能还想看看这个chapter in R for Data Science
    • 总之,你让我相信本章的结尾比开头更有用。很棒的书。如果您对如何使用您的解决方案感兴趣,您可以在construct_funcs.R 此处github.com/aedobbyn/beer-data-science 中找到它。仍处于早期阶段,所以还没有什么可展示的,但希望能尽快将其中的一些结合在一起!
    猜你喜欢
    • 2021-12-21
    • 1970-01-01
    • 2022-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-08
    • 1970-01-01
    • 2019-12-10
    相关资源
    最近更新 更多