当然,我们可以编写一个函数来实现这一点!
首先,将输入字符串拆分为
::
-
如果没有拆分(长度=1),则将其视为常规函数名
-
如果存在拆分(长度=2),则将第一部分视为包名,第二部分视为函数名
然后它使用
get()
或
getExportedValue()
以检索实际功能。
最后,它返回该函数的环境。
这应该会给你与直接在函数上使用fn_env()相同的结果,但具有接受字符串输入的灵活性。
using<-function(...) {
libs<-unlist(list(...))
req<-unlist(lapply(libs,require,character.only=TRUE))
need<-libs[req==FALSE]
if(length(need)>0){
install.packages(need)
lapply(need,require,character.only=TRUE)
}
}
using("rlang")
my_fn_env <- function(fun_name) {
# Split the string in case it contains namespace specification
parts <- strsplit(fun_name, "::")[[1]]
if (length(parts) == 1) {
# Case 1: Regular function name without namespace
fn <- tryCatch(
get(fun_name, mode = "function"),
error = function(e) stop("Function '", fun_name, "' not found")
)
return(environment(fn))
} else if (length(parts) == 2) {
# Case 2: Function with namespace specification
pkg <- parts[1]
fun <- parts[2]
# Check if package is installed and loaded
if (!requireNamespace(pkg, quietly = TRUE)) {
stop("Package '", pkg, "' is not installed")
}
# Get the function from the namespace
fn <- tryCatch(
getExportedValue(pkg, fun),
error = function(e) stop("Function '", fun, "' not found in package '", pkg, "'")
)
return(environment(fn))
} else {
stop("Invalid function name format")
}
}
# normal way using fn_env
f <- function(x) x + y
fn_env(f)
# Test our function!
my_fn_env("f")
my_fn_env("mean")
my_fn_env("plyr::count")