【问题标题】:nested lapply to allow calling functions with multiple inputs嵌套 lapply 以允许调用具有多个输入的函数
【发布时间】:2019-10-02 19:27:38
【问题描述】:

编辑:我有一些带有多个参数的函数,我想将其应用于列表列表。其中一个参数也是列表列表。 这两个函数都有多个参数。其中两个我必须在列表列表中递归地指出。 假设我有以下两个列表。

mylist <- list(list(10,12,13,14,15), list(5,6,7,8,9))
m <- list(list(2,2,2,3,4), list(3,3,4,4,5))

和功能

func1 <- function(x, att1 = m, const = 10){
 e <- x^m + const
 return(e)
}

func2 <- function(x, att2 = m, const = 10){
 d <- sqrt(x)/m + const
 return(d)
}

当我想调用每个函数时,我不知道如何处理正确的参数att1att2。 我使用eval(substitute(att1 = a)) 尝试了下面的功能

nested_function <- function(df_list, FUN = func1, changing_param = a, ...){

 nested_output <- lapply(seq(df_list), function(i){
   lapply(seq(df_list[[i]]), function(j){
     FUN(df[[i]][[j]], eval(substitute(changing_param))[[i]][[j]],...)
   })
 })

 return(nested_output)
}

result <- nested_function(df_list, FUN = func1, changing_param = 'att1 = a')

并得到以下错误:

 Error in df[[i]] : object of type 'closure' is not subsettable 
6.
FUN(df[[i]][[j]], eval(substitute(changing_param))[[i]][[j]], 
...) 
5.
FUN(X[[i]], ...) 
4.
lapply(seq(df_list[[i]]), function(j) {
    FUN(df[[i]][[j]], eval(substitute(changing_param))[[i]][[j]], 
        ...)
}) 
3.
FUN(X[[i]], ...) 
2.
lapply(seq(df_list), function(i) {
    lapply(seq(df_list[[i]]), function(j) {
        FUN(df[[i]][[j]], eval(substitute(changing_param))[[i]][[j]], 
            ...) ... 
1.
nested_function(mylist, changing_param = m) 

我的问题是如何让FUN() 调用将a 识别为func1 中的att1func2 中的att2,因为我必须为每个函数指定它们(我不能只把论点放在那里)。

有什么建议吗?

【问题讨论】:

  • 如果您包含一个简单的reproducible example,其中包含可用于测试和验证可能解决方案的示例输入和所需输出,则更容易为您提供帮助。你不能把值作为一个未命名的位置参数传递吗?
  • 我修改了我的问题以添加一些我需要的可重现示例。

标签: r nested lapply


【解决方案1】:

如果您需要动态构建参数名称,您通常必须最终使用do.call(至少使用基本 R)。我很确定你的所有变量在你的例子中应该如何工作,所以这是一个运行的改编版本。

df_list   <- list(list(10,12,13,14,15), list(5,6,7,8,9))
param_list <- list(list(2,2,2,3,4), list(3,3,4,4,5))

func1 <- function(x, att1 = m, const = 10){
  e <- x^att1 + const
  return(e)
}

func2 <- function(x, att2 = m, const = 10){
  d <- sqrt(x)/att2 + const
  return(d)
}

nested_function <- function(df_list, param_list, FUN = func1, changing_param = "a", ...){
  nested_output <- lapply(seq(df_list), function(i){
    lapply(seq(df_list[[i]]), function(j){
      params <- list(df_list[[i]][[j]], param_list[[i]][[j]], ...)
      names(params)[2] <- changing_param
      do.call(FUN, params)
    })
  })

  return(nested_output)
}

nested_function(df_list, param_list, func1, changing_param = 'att1', const=1)
nested_function(df_list, param_list, func2, changing_param = 'att2', const=2)

这里我们将我们想要的参数名称作为字符串传入。然后,当我们构建要传递给函数的参数时,我们将传入的参数重命名为提供的名称,然后调用函数。

【讨论】:

  • do.call 将是我的下一次尝试。非常感谢!