在R中,如果我将一个函数作为输入传递给另一个函数(如stackoverflow.com/questions/74044185中),我如何参数判断该函数?作为一个最小的例子,该函数要求传递的函数为空(不做任何事情)、upper.tri或lower.tri

mytri <- function(tri.func = NULL){
  test <- matrix(1:25,5,5)
  if(is.function(tri.func)){
     test[!tri.func(test)] <-NA
  }
  return(test)
}
mytri()
mytri(upper.tri)
mytri(lower.tri)

但如何判断该函数是否在我允许的列表中呢?例如,mytri(log)将无错误地返回错误的结果.我try 了if(is.function(tri.func) && all(names(formals(tri.func)) ==c("x","diag"))),但不起作用,因为显然all(logical(0) == c("x", "diag"))就是TRUE

推荐答案

正如我在对这个问题的 comments 中所说,match.arg中的第一个例子可以适应这个问题.主要的转折是可能存在缺失论点,即问题中的NULL默认.在这里,我用missing来测试它.

mytri <- function(tri.func = c("upper.tri", "lower.tri")) {
  test <- matrix(1:25, 5, 5)
  if(!missing(tri.func)) {
    tri.func <- match.arg(tri.func)
    i <- switch(tri.func,
                upper.tri = upper.tri(test),
                lower.tri = lower.tri(test))
    test[i] <- NA
  }
  test
}

mytri()
#>      [,1] [,2] [,3] [,4] [,5]
#> [1,]    1    6   11   16   21
#> [2,]    2    7   12   17   22
#> [3,]    3    8   13   18   23
#> [4,]    4    9   14   19   24
#> [5,]    5   10   15   20   25
mytri("upper.tri")
#>      [,1] [,2] [,3] [,4] [,5]
#> [1,]    1   NA   NA   NA   NA
#> [2,]    2    7   NA   NA   NA
#> [3,]    3    8   13   NA   NA
#> [4,]    4    9   14   19   NA
#> [5,]    5   10   15   20   25
mytri("lower.tri")
#>      [,1] [,2] [,3] [,4] [,5]
#> [1,]    1    6   11   16   21
#> [2,]   NA    7   12   17   22
#> [3,]   NA   NA   13   18   23
#> [4,]   NA   NA   NA   19   24
#> [5,]   NA   NA   NA   NA   25
mytri("log")
#> Error in match.arg(tri.func): 'arg' should be one of "upper.tri", "lower.tri"

创建于2024年5月2日,共有reprex v2.1.0


Edit

回复 comments

但我并没有寻找替代方法来获得同样的结果.原则上,在不更改任何其他代码的情况下,是否有任何逻辑判断可以添加到我的问题中的if陈述中?

here is a version with an added logical test. The new test is a series of identical checks because %in% and == do not work with function objects.
When the function is not one of the allowed functions an error trappable with try or tryCatch is thrown.

mytri <- function(tri.func = NULL) {
  test <- matrix(1:25,5,5)
  if(is.function(tri.func) && 
     (identical(tri.func, lower.tri) || identical(tri.func, upper.tri))) {
    test[!tri.func(test)] <-NA
  } else if(!is.null(tri.func)) {
    f <- deparse(substitute(tri.func))
    msg <- sprintf("'%s' not an allowed function.", f)
    stop(msg)
  }
  test
}

mytri()
#>      [,1] [,2] [,3] [,4] [,5]
#> [1,]    1    6   11   16   21
#> [2,]    2    7   12   17   22
#> [3,]    3    8   13   18   23
#> [4,]    4    9   14   19   24
#> [5,]    5   10   15   20   25
mytri(upper.tri)
#>      [,1] [,2] [,3] [,4] [,5]
#> [1,]   NA    6   11   16   21
#> [2,]   NA   NA   12   17   22
#> [3,]   NA   NA   NA   18   23
#> [4,]   NA   NA   NA   NA   24
#> [5,]   NA   NA   NA   NA   NA
mytri(lower.tri)
#>      [,1] [,2] [,3] [,4] [,5]
#> [1,]   NA   NA   NA   NA   NA
#> [2,]    2   NA   NA   NA   NA
#> [3,]    3    8   NA   NA   NA
#> [4,]    4    9   14   NA   NA
#> [5,]    5   10   15   20   NA
mytri(log)
#> Error in mytri(log): 'log' not an allowed function.

创建于2024年5月2日,共有reprex v2.1.0

R相关问答推荐

在集合群体模型中计算时间步依赖的速率/参数

从R中的地址提取街道名称

通过R访问MoveApps API

如何将y轴上的线定位得彼此更近

根据固定值范围在tible中添加新行

在ggplot的注释表格中突出显示最大值

ggplot 2中的地块底图(basemaps_gglayer()不起作用)

geom_Ribbon条件填充创建与数据不匹配的形状(ggplot 2 r)

将年度数据插入月度数据

如何使用R对每组变量进行随机化?

非线性混合效应模型(NLME)预测变量的置信区间

使用R闪光显示所有数据点作为默认设置

在rpart. plot或fancyRpartPlot中使用带有下标的希腊字母作为标签?

R中的哈密顿滤波

如何在PDF格式的kableExtra表格中显示管道字符?

如何创建累加到现有列累计和的新列?

如何使用字符串从重复的模式中提取多个数字?

如何删除设置大小的曲线图并添加条形图顶部数字的百分比

如何阻止围堵地理密度图?

如何合并不同列表中的数据文件,包括基于名称的部分匹配,而不是一对一等价