R 中的向量化参数验证?

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

我正在尝试通过改编我在其他地方看到的示例来矢量化参数函数验证。现在,所有内容都返回 0。使用

browser()
函数,我可以进入 apply 函数,我发现它不是寻找参数名称(即
P1
)来确定允许的值,而是寻找参数名称“M”(即参数值) )。我相信我需要有人将传递的参数值分配给每个参数名称,但我不确定如何执行此操作。或者,如果我完全偏离基地,是否有更好的方法来做到这一点?明显的解决方案是通过重复代码来单独检查每个参数,但这看起来很草率/效率低下,我希望学习更好的方法。

任何帮助将不胜感激。谢谢!

myFunc <- function(P1 = c("F", "M"), 
                          P2 = c("HighSchool_GPA", "SAT"), 
                          P3 = 2007:2012, 
                          P4 = c("Yes", "No")
                          ) {
  browser()
  # Validate parameter values
  allowed_values <- list(P1 = c("F", "M"), 
                         P2 = c("HighSchool_GPA", "SAT"), 
                         P3 = 2007:2012, 
                         P4 = c("Yes", "No"))

  # Attempt to validate all values at once
  valid_indexes <- sapply(
    c(P1, P2, P3, P4), 
    function(param) {
      allowed <- allowed_values[[names(param)]] 
      match(param, allowed, nomatch = 0)
      }
    )
  
  if (any(valid_indexes == 0)) {
    stop("Invalid parameter value(s). 
         Please check values passed. Use only allowed values.")
  }
}

example <- myFunc("M", "HighSchool_GPA", 2010, "No")
r parameter-passing
1个回答
0
投票

我认为问题在于

allowed <- allowed_values[[names(param)]]
。我认为参数的名称在
sapply
的每次迭代期间都不可用。

我的解决方案是首先创建一个在主函数调用中传递的参数的命名列表(

call_params <- as.list(match.call())
)。然后将参数 names
c("P1", "P2", "P3", "P4")
的向量传递给
sapply
,并使用这些名称从
call_params
访问相关参数。

所以在

sapply
内部的匿名函数中,我们使用
allowed_values[[param]]
而不是
allowed_values[[names(param)]]
。我们在
call_params[[param]]
函数中使用
param
代替
match()

myFunc <- function(P1 = c("F", "M"), 
                   P2 = c("HighSchool_GPA", "SAT"), 
                   P3 = 2007:2012, 
                   P4 = c("Yes", "No")
) {
  browser()
  # Validate parameter values
  allowed_values <- list(P1 = c("F", "M"), 
                         P2 = c("HighSchool_GPA", "SAT"), 
                         P3 = 2007:2012, 
                         P4 = c("Yes", "No"))
  
  # create the named list of arguments
  call_params <- as.list(match.call())

  # Attempt to validate all values at once
  valid_indexes <- sapply(
    c('P1', 'P2', 'P3', 'P4'), 
    function(param) {
      allowed <- allowed_values[[param]] 
      match(call_params[[param]], allowed, nomatch = 0)
    },
    USE.NAMES = TRUE
  )
  
  if (any(valid_indexes == 0)) {
    stop("Invalid parameter value(s). 
         Please check values passed. Use only allowed values.")
  }
}

example <- myFunc("M", "HighSchool_GPA", 2010, "No")
© www.soinside.com 2019 - 2024. All rights reserved.