我想在低级(内部)函数high_lvl_fun
中使用来自高级(外部)函数low_lvl_fun
的计算。低级函数是高级函数的参数(我想使用具有不同参数集的不同函数)。我可重复的例子:
set.seed(101)
low_lvl_fun <- function(x, y){ # low-level (inner) function
sum((x-y)^2) # Mean Squared Error
}
high_lvl_fun <- function(x, y = NULL, FUN, args){ # high level (outer) function
# Just some toy changes in y to check if the code works
if(length(y) == 0){
y <- rep(1, length(x))
}else{
y <- rep(2, length(x))
}
do.call(FUN, args = args) # Call of low_lvl_fun
}
低级功能计算均方误差。高级函数对向量y
执行一些操作并调用低级函数。声明这样的论证和高级函数调用:
x <- rnorm(100)
high_lvl_fun(x, y = NULL, FUN = "low_lvl_fun", args = list(x, y))
导致了这样的错误:
do.call出错(FUN,args = args):找不到对象'y'
我理解低级函数假定y
的值是NULL
(如在高级函数调用中声明的那样),但是,我不知道如何更改范围其中低级函数搜索y
。
我想出的唯一解决方案是在全球环境中声明y
:
high_lvl_fun2 <- function(x, y = NULL, FUN, args){ # high level (outer) function
if(length(y) == 0){
y <<- rep(1, length(x))
}else{
y <<- rep(2, length(x))
}
do.call(FUN, args = args) # Call of low_lvl_fun
}
但是,我想避免在全局环境中修改y
。
编辑:(更多细节)
低级别功能可以使用x
和y
以外的参数。它可能还只需要x
和其他参数,而不是y
,例如:
low_lvl_fun2 <- function(x){sd(x)/mean(x)}
另一个重要的事情是高级和低级函数可以使用相同名称的参数(如上所述,其中两个函数都有名为x
和y
的参数)并且它会很好没有被迫重写低级功能。不幸的是,@ Andrea建议的注释中的实现不符合这个条件,因为匹配两个具有相同名称的参数会引发错误:
high_lvl_fun <- function(x, y = NULL, FUN, ...){ # Function suggested by @Andrea
dots <- lazy_eval(lazy_dots(...))
# Just some toy changes in y to check if the code works
if(length(y) == 0){
y <- rep(1, length(x))
}else{
y <- rep(2, length(x))
}
args <- c(list(x , y) , dots)
do.call(FUN, args = args) # Call of low_lvl_fun
}
# Calling the low-level function at the beginning of the post
high_lvl_fun(x = 1:10, y = 2:11, FUN = "low_lvl_fun", x = x, y = y)
high_lvl_fun出错(x = 1:10,y = 2:11,FUN =“low_lvl_fun”,x = x, :形式参数“x”由多个实际参数匹配
答案 0 :(得分:0)
假设low_lvl_fun()
仅使用x
和y
。这应该做的工作
high_lvl_fun <- function(x, y = NULL, FUN ){ # high level (outer) function
# Just some toy changes in y to check if the code works
if(length(y) == 0){
y <- rep(1, length(x))
}else{
y <- rep(2, length(x))
}
args <- list(x = x, y = y)
do.call(FUN, args = args) # Call of low_lvl_fun
}
答案 1 :(得分:0)
作为一个更普遍的解决方案,我建议 使用...参数
require(lazyeval)
high_lvl_fun <- function(x, y = NULL, FUN, ...){ # high level (outer) function
dots <- lazy_eval(lazy_dots(...))
# Just some toy changes in y to check if the code works
y <- y+1
args <- c(list(x , y) , dots)
do.call(FUN, args = args) # Call of low_lvl_fun
}
# Ex 1
f <- function(x, y , z) {x+y+z}
high_lvl_fun (x = 1, y = 2, FUN = f, z = 3)
# Ex 2
g <- function(x, y , z, mean , sd) {
n <- x+y+z
sum(rnorm(n , mean , sd))
}
high_lvl_fun (x = 1, y = 2, FUN = g, z = 3, mean = 100, sd = 1)