编辑:最初的共鸣表明我的文章将人们的注意力集中在最佳实践问题而不是技术问题上。但是,我想关注一个技术问题,下面只是一个玩具示例:
如果有人将列表传递给函数参数,您如何捕获和检查该列表中的各个元素,而不会冒系统尝试调用/评估这些元素的风险?
例如,如果用户向参数传递一个可能合适或不合适的函数列表,或者加载了相关的包,该函数如何安全地检查请求的函数?
假设我想构建一个迭代可能应用的其他函数的函数。实际示例会调用不同的建模函数,但这里有一个更容易看到的玩具示例:
newfunc <- function(func.list){
lapply(func.list,
function(f){
f(letters)
}
)
}
假设 newfunc() 可以使用的函数包括函数 nchar() 和 length()。如果我们提供这些,我们会得到以下信息:
newfunc(
func.list = list(nchar, length)
)
[[1]]
[1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
[[2]]
[1] 26
但是,假设 newfunc() 也能够采用 str_to_upper() 之类的东西,它来自包stringr。传递 str_to_upper() 可以正常工作,但前提是预先加载了stringr :
newfunc(
func.list = list(nchar, length, str_to_upper)
)
Error in lapply(func.list, function(f) f(letters)) :
object 'str_to_upper' not found
require(stringr)
newfunc(func.list = list(nchar, length, str_to_upper))
[[1]]
[1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
[[2]]
[1] 26
[[3]]
[1] "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O"
[16] "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z"
我想将代码放在可以调查列表元素并确定是否需要加载任何包(如stringr )的函数中。另外,我想检查列出的函数是否来自可接受的集合(如果有人通过mean()
,或者更糟糕的是,rcorr()
来自未加载的Hmisc ,它会捕获)。
# This works here but is undesireable:
newfunc(func.list = list(nchar, length, str_to_upper, mean))
# This creates issues no matter what:
newfunc(func.list = list(nchar, length, str_to_upper, rcorr))
require(Hmisc)
newfunc(func.list = list(nchar, length, str_to_upper, rcorr))
我知道如何func.list.test <- deparse(substitute(func.list)
获取参数的文字文本,但我不知道如何在单个元素上执行此操作而不会在某些函数不存在时触发错误。
(而且我不想对 的整体解析输出采取字符串操作的hacky路线func.list.test
)
理想情况下,对于这个用例,我想知道这是否可以使用基本 R 技术来完成。但是,如果这是最好的/唯一的方法,请随时解释如何使用更新的方法(如整洁的评估/quosures)来做到这一点(尽管知道我目前对这些方法的熟悉程度非常有限)。
任何帮助,将不胜感激。