R:使用变量将单个动态定义参数的多个值传递到函数中

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

我希望能够通过两个函数传递参数,但定义与变量一起使用的参数。这将避免必须指定参数的每种可能性。

请参阅以下示例以了解我想要实现的目标:

run_multiple <- function (parameter_name, parameter_values) {
  for (value in parameter_values) {
    run_function(parameter_name = value)
  }
}

run_function <- function (x = "a", y = "a", z = "a") {
  print(sprintf("X is %s, Y is %s, Z is %s", x, y, z))
}

那么理想情况下,可以使用以下任一格式进行实施:

run_multiple("x", c("a", "b"))
run_multiple(x, c("a", "b"))
# [1] X is a, Y is a, Z is a
# [1] X is b, Y is a, Z is a

据我所知,我认为

...
中的
run_multiple
表示法不会有帮助,因为它只允许我传递单个值,而不是循环中的多个值。

如果有用,更广泛的背景将与大型功能的微基准测试一起使用,以了解启用不同版本的子功能如何影响整体性能。

其工作原理示例:

run_benchmarking <- function (parameter_name, parameter_values, run_names) {
  # currently setup with only two values allowed
  microbenchmark::microbenchmark(
      run_names[1] = run_function(parameter_name = parameter_values[1]),
      run_names[2] = run_function(parameter_name = parameter_values[2]),
    times = 1000
  )
}

run_function <- function (use_x = T, use_y = T, use_z = T) {
  x <- func1(use_x)
  y <- func2(use_y)
  z <- func3(use_z)
  
  list(x = x, y = y, z = z)
}

# example of func n
func1 <- function (use_x) {
  if (use_x) {
    x <- round(runif(1, 1, 100))
  } else {
    x <- 1
  }
}

# example of benchmarking tests, which would output results from microbenchmark
run_benchmarking(use_x, c(T, F), c("With X", "Without X"))
run_benchmarking(use_y, c(T, F), c("With Y", "Without Y"))
run_benchmarking(use_z, c(T, F), c("With Z", "Without Z"))

目前仅接受两个值作为参数,这是可以扩展的,但对于最初的 A/B 测试来说应该足够了。

如果有更好的方法来测试大量这样的 A/B 测试,我也愿意接受其他建议。

r parameter-passing microbenchmark
1个回答
0
投票

这可以使用

do.call
来完成,它允许将变量 args 传递给函数。这还允许扩展为允许传递和解析多个参数(例如
use_x
use_y

run_benchmarking <- function (parameter_combinations, run_names) {
  benchmark_list <- alist(
      do.call(run_function, list(eval(parse(text = parameter_combinations[1])))),
      do.call(run_function, list(eval(parse(text = parameter_combinations[2]))))
  )
  
  names(benchmark_list) = run_names
  
  # currently setup with only two values allowed
  microbenchmark::microbenchmark(
    list = benchmark_list,
    times = 1000
  )
}

然后可以通过以下方式调用:

run_benchmarking(c("use_x = T", "use_x = F"), c("With X", "Without X"))

# Unit: microseconds
#      expr  min   lq    mean median   uq   max neval
#     With X 15.0 15.5 17.7892   15.8 16.4 138.5  1000
#  Without X 14.1 14.7 16.5617   14.9 15.4 185.4  1000
© www.soinside.com 2019 - 2024. All rights reserved.