R包:使用lapply来做一个内部函数列表

时间:2018-05-08 11:36:20

标签: r package

我正在开发一个R包,其中我有一个导出的函数,需要调用几个未导出的函数并将每个函数的结果存储在列表中。 调用哪些函数是可变的,取决于用户输入。

我对此的处理方法是lapply一个带有do.call的函数名称(字符)向量,但似乎这使得未导出的函数对导出的函数不可见。

考虑以下示例包代码:

tmp1 <- function(x) print(paste("Function 1 called with x =", x))
tmp2 <- function(x) print(paste("Function 2 called with x =", x))
tmp3 <- function(x) print(paste("Function 3 called with x =", x))

#' @export
test1 <- function() {
  tmp1("test")
  tmp2("test")
  tmp3("test")
}

#' @export
test2 <- function() {
  funs <- c("tmp1", "tmp2", "tmp3")
  for (fun in funs) do.call(fun, list(x = "test"))
}

#' @export
test3 <- function() {
  funs <- c("tmp1", "tmp2", "tmp3")
  lapply(funs, do.call, list(x = "test"))
}

构建并加载包后,运行三个test函数会产生以下输出:

test1()
#> [1] "Function 1 called with x = test"
#> [1] "Function 2 called with x = test"
#> [1] "Function 3 called with x = test"

test2()
#> [1] "Function 1 called with x = test"
#> [1] "Function 2 called with x = test"
#> [1] "Function 3 called with x = test"

test3()
#> Error in tmp1(x = "test"): could not find function "tmp1"

直接调用这些函数是有效的,并且在do.call直接使用do.call时调用它们会有效,但在通过lapply调用它时会失败。 我可以使用for循环进行解决,但我很好奇为什么会发生这种情况。

所以,我的问题有两个:

  1. 为什么在do.call内调用lapply时,未导出的函数不可见?
  2. 我可以使lapply(funs, do.call, list(...))方法有效吗?

2 个答案:

答案 0 :(得分:0)

这部分已在其他地方介绍过,我建议你在全局变量和作用域分配的stackoverflow上阅读这两个(12)线程。

要解决您的问题,请添加&#34; id&#34;在分配你的功能时,即

var items = document.querySelectorAll('.content__products__item');

for (var i = 1; i < items.length; i++) {
    var btnMinus = document.querySelector('#item' + i + ' .quantity-arrow-minus');
    var btnPlus = document.querySelector('#item' + i + ' .quantity-arrow-plus');
    var input = document.querySelector('#item' + i + ' .quantity-num span');
    var currentPrice = document.querySelector('#item' + i + ' .content__products__item__price span');
    var pricePerGram = currentPrice.textContent / 50;
    btnPlus.onclick = function (e) {
        input.textContent = +input.textContent + 50;
        currentPrice.textContent = (+input.textContent * pricePerGram).toFixed(2);
    }
    btnMinus.onclick = function (e) {
        if (input.textContent > 50) {
            input.textContent = +input.textContent - 50;
            currentPrice.textContent = (+input.textContent * pricePerGram).toFixed(2);
        }
    }
}

<强>输出:

<<-

答案 1 :(得分:0)

根据对问题的评论,我有一个(部分)答案:

    默认情况下,
  1. do.call评估parent.frame()中的字符参数,当在lapply内调用时,这与tmp函数定义的环境不同(尽管我不确定具体细节)
  2. 将当前环境提供给do.call会使lapply方法有效: lapply(funs, do.call, args = list(x = "test"), envir = environment())
相关问题