Mathematica的等价物

时间:2016-09-29 14:34:17

标签: r rscript

Mathematica Which函数是一个广义的If

  

Which[test_1, value_1, test_2, value_2, …]

     

依次评估每个test_i,返回与产生value_i的第一个True对应的if (test_1) value_1 else if (test_2) value_2 else ... value_n else default 的值。

它只是一种方便的方法,可以从嵌套的简单if-else测试的长序列中删除多余的语法。

R是否具有等效功能?

顺便说一句,我知道我总能做点什么

if (test_1) value_1 else
if (test_2) value_2 else
            ...
if (test_n) value_n else
            default

或等同地

Which

...但是,正如我已经提到的,与if-else相比,嵌套的ifelse(t_1, v_1, ifelse(t_2, v_2, ..., ifelse(t_n, v_n, default)...)) 语句带来了许多多余的语法。

另外,我知道

if-else

...但结果对测试的形状很敏感,因此它并不严格等同于嵌套的switch语句。

最后,R switch(expr, case_1 = value_1, case_2 = value_2, ... case_n = value_n, default) 声明与我正在寻找的声明类似,因为它将调度封装在一系列测试中,但它并不完全相同事情。在

expr

...测试都是case_iWhich的相等比较,而在{{1}}等中,测试是任意的布尔表达式。

2 个答案:

答案 0 :(得分:3)

根据Mathematica的帮助,

  

其中[test1,value1,test2,value2,...] 依次评估每个testi,返回对应于产生True的第一个值的valuei的值。

我们可以在R中执行此操作,即获取与计算结果为true的第一个表达式的位置对应的值,如下所示:

<强> 1。评估所有表达式的简单版本:

values = c("value1", "value2", "value3", "value4", "value5", "value6", "value7")
expressions = c(1==2, 1==3, 1==1, 1==4, T==F, F==T, T==T)
values[which.max(expressions)]
# [1] "value3"

虽然,如果没有一个表达式为真,which.max将返回第一个false,所以我们也应检查这个

if (any(expressions))  values[which.max(expressions)] else NA

<强> 2。版本“短路”

然而,Mathematica的上述行为存在一个差异:mathematica短路中的which - 即它只评估找到第一个TRUE所需的表达式。如果表达式计算成本高或速度瓶颈,那么我们也可能希望在R中复制此行为。我们可以使用Position进行短路,并结合eval(parse)来确保我们在我们准备测试表达式之前不要评估表达式

values = c("value1", "value2", "value3", "value4", "value5", "value6", "value7")
expressions = c("1==2", "1==3", "1==1", "1==4", "T==F", "F==T", "T==F")

values[Position(function(text) eval(parse(text=text)), expressions, T)]

答案 1 :(得分:1)

您可以编写自己的函数,可以用作这样的控制结构。接下来是基于match.call支持惰性评估的事实。 (参见this接受的答案):

which.val <- function(...){
  clauses <- match.call(expand.dots = FALSE)$`...`
  n <- length(clauses)
  for(i in seq(1,n,2)){
    condition = eval(clauses[[i]], envir = parent.frame())
    if(condition) return(eval(clauses[[i+1]], envir = parent.frame()))
  }
}

出于测试目的:

test <- function(a,b){
  print(b)
  a == b
}

副作用可用于查看实际评估的内容。

例如:

> x <- 3
> which.val(test(x,1),10,test(x,2),20,test(x,3),30,test(x,4),40)
[1] 1
[1] 2
[1] 3
[1] 30

请注意永远不会评估test(x,4)