使用assign在R

时间:2017-05-28 04:03:55

标签: r

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

我使用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()

但是,在创建函数后,它们每个只返回name的&#34; c&#34;或向量to_name中的最后一个值。

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

相反,func_a("foo")应返回&#34; key_name:a ----- value_x:foo&#34;。

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

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

谢谢你看看!

1 个答案:

答案 0 :(得分: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循环一样)为每个元素创建一个新函数。您只需确保在.GlobalEnv电话中将环境设置为assign()即可。对于像这样的事情,我不太了解环境范围,并且觉得我已经知道这有时候是一个坏主意,但它似乎做了你所描述的。希望这会有所帮助。

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"