在R中自动为函数数组添加函数

时间:2016-08-20 09:14:32

标签: r

所有函数都接收相同的参数,我想在同一个数据上运行所有函数,所以我创建了手动函数列表:

foo_1 <- function(data){
  .
  .
}

foo_2 <- function(data){
  .
  .
}

foo_3 <- function(data){
  .
  .
}

而不是:funcs <- c(foo_1, foo_2, foo_3)

这种方法的缺点是如果我创建一个新函数,比如foo_4我需要手动将此函数添加到funcs向量。有没有办法自动进行这种思考?

3 个答案:

答案 0 :(得分:2)

让我们首先将您的函数放入一个文件中,然后从中获取它们...

# creating the source file for the functions 

funcs_text <- 
"
foo_1 <- function(data){}
foo_2 <- function(data){}
foo_3 <- function(data){}
"

fname <- tempfile()
writeLines(funcs_text, fname)

现在我们可以通过source()读取文件。诀窍是首先创建一个新环境(new.env()),其中源文件中定义的函数。此环境通过source()参数传递给local。此后,我们将环境转换为列表 - 等等。

# reading in file
funcs <- new.env() 
source(fname, local=funcs)
funcs <- as.list(funcs)

现在,您可以进一步使用功能列表进行处理。

# accessing a function

funcs[[1]]
funcs$foo_1
funcs[["foo_1"]]


# calling a function

funcs[[1]]()
funcs$foo_1()
funcs[["foo_1"]]()

答案 1 :(得分:2)

你可以超越source()并实际为这些功能制作一个软件包,这样你就可以获得丰富的文档 - 即。 :

#' Multiply x by 2
#'
#' Spiffy long description here
#'
#' @param x the data
#' @return atomic numeric value
#' @export
f1 <- function(x) { x * 2 }

#' Divide x by 2
#'
#' Spiffy long description here
#'
#' @param x the data
#' @return atomic numeric value
#' @export
f2 <- function(x) { x / 2 }

#' Subtract 3 from x
#'
#' Spiffy long description here
#'
#' @param x the data
#' @return atomic numeric value
#' @export
f3 <- function(x) { x - 3 }

将它们放入并构建一个名为myfuncs的包,然后您可以执行以下操作:

library(myfuncs)
library(purrr)

lsf.str("package:myfuncs") %>% 
  invoke_map_dbl(list(x=100))

如果您不关心类型安全或返回比invoke_map()支持的更复杂的对象,您可以使用purrr

如果您需要支持暴露功能的功能,也可以将非导出功能添加到该包中。

答案 2 :(得分:1)

通过您的示例,枚举您的函数并使用模式。然后,您可以使用greplsf.str的组合。我们最终使用get来获取列表中的函数调用。

foo_1 <- function(data){
    data*2
}
foo_2 <- function(data){
    data*3
}
bar <- function(data){
    data+22
}

## Vector output of functions that match string
funcs_names <- lsf.str()[grep("foo_",lsf.str())]  

## Get function calls
funcs <- sapply(funcs_names,get)
funcs
## $foo_1
## function (data) 
## {
##     data * 2
## }
## 
## $foo_2
## function (data) 
## {
##     data * 3
## }