功能范围:使用低级功能中的高级功能结果

问题描述 投票:0回答:2

我想在低级(内部)函数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

编辑:(更多细节)

低级函数可以使用除xy之外的参数。它可能也只需要x和其他参数,而不是y,例如:

low_lvl_fun2 <- function(x){sd(x)/mean(x)}

另一个重要的事情是高级和低级函数可以使用相同名称的参数(如上所述,其中两个函数都有名为xy的参数),并且不会强制重写低级函数。不幸的是,@ Anrea建议的注释中的实现不符合这个条件,因为匹配两个具有相同名称的参数会引发错误:

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”由多个实际参数匹配

r function scope
2个回答
0
投票

假设low_lvl_fun()只采用xy。这应该做的工作

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
}

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) 
© www.soinside.com 2019 - 2024. All rights reserved.