R是否允许运算符为复合表达式?

时间:2014-08-29 20:50:34

标签: r functional-programming

在Harold Abelson"计算机程序的结构和解释"中,使用Lisp编程语言,其中一个练习要求您评估以下代码:

(define (a-plus-abs-b a b)
((if (> b 0) + -) a b))

R中执行此操作的一种方法当然是:

APlusAbsB <- function(a, b){
  if(b > 0) a + b else a - b
}

然后我重复ab s。

我的问题是:R是否允许运算符为复合表达式(例如if (> b 0) + -))?例如,有没有办法做类似

的事情
APlusAbsB <- function(a, b){  ## this doesn't work
  if(b > 0) "+" else "-" (a, b)    ## gives "+" or "-"
}

2 个答案:

答案 0 :(得分:9)

尝试

APlusAbsB <- function(a, b){
  (if(b > 0) `+` else `-`)(a, b)
}

这里if将返回一个函数,然后用括号语法调用它。例如

APlusAbsB(1,5)
# [1] 6
APlusAbsB(1,-1)
# [1] 2

答案 1 :(得分:2)

感谢优秀的程序员,我有三种选择。我进行了基准测试,替代品1和2几乎与使用ifelse的备选方案3完全相同且更快。

APlusAbsB1 <- function(a, b){(if(b > 0) `+` else `-`)(a, b)}
APlusAbsB2 <- function(a, b) {`if`(`>`(b, 0), `+`, `-`)(a, b)}
APlusAbsB3 <- function(a, b) { ifelse(b > 0, `+`, `-`)(a, b)}

microbenchmark(APlusAbsB1(sample(10, 1), sample(-10:10, 1)),
               APlusAbsB2(sample(10, 1), sample(-10:10, 1)),
               APlusAbsB3(sample(10, 1), sample(-10:10, 1)), times=10000)
Unit: microseconds
                                         expr   min    lq median    uq     max neval
 APlusAbsB1(sample(10, 1), sample(-10:10, 1)) 3.925 4.529  4.831 5.133 912.546 10000
 APlusAbsB2(sample(10, 1), sample(-10:10, 1)) 3.925 4.529  4.830 5.132 854.587 10000
 APlusAbsB3(sample(10, 1), sample(-10:10, 1)) 4.831 5.736  5.737 6.340 851.568 10000