R中的NAND运算符

aeo*_*ail 2 r operators

在R中是否存在"适当的"NAND运算符,例如

nand(condition1, condition 2)
Run Code Online (Sandbox Code Playgroud)

或者它只是最佳实践/唯一的可能性

!(condition1 & condition2)
Run Code Online (Sandbox Code Playgroud)

还有哪些其他选择?

nru*_*ell 5

为了解决这个问题,nandR中没有内置函数,我想到的唯一改进建议的方法!(x & y)是将此操作转换为编译语言,例如

#include <Rcpp.h>

// [[Rcpp::export]]
Rcpp::LogicalVector nand(Rcpp::LogicalVector lhs, Rcpp::LogicalVector rhs) {
  R_xlen_t i = 0, n = lhs.size();
  Rcpp::LogicalVector result(n);

  for ( ; i < n; i++) {
    result[i] = !(lhs[i] && rhs[i]);
  }

  return result;
}

/*** R

Lhs <- rbinom(10e4, 1, .5)
Rhs <- rbinom(10e4, 1, .5)

r_nand <- function(x, y) !(x & y)

all.equal(nand(Lhs, Rhs), r_nand(Lhs, Rhs))
#[1] TRUE

microbenchmark::microbenchmark(
  nand(Lhs, Rhs), r_nand(Lhs, Rhs),
  times = 200L)
#Unit: microseconds
#            expr      min       lq     mean   median       uq       max neval
#  nand(Lhs, Rhs)  716.140  749.926 1215.353  771.015 1856.734  6332.284   200
#r_nand(Lhs, Rhs) 3337.494 3397.809 5106.614 3461.845 4985.807 95226.834   200

*/
Run Code Online (Sandbox Code Playgroud)

这是否值得麻烦可能取决于您需要多久拨打一次电话nand.出于大多数目的,上述内容r_nand应该足够了.事实上,base::xor实施方式类似:

base::xor
#function (x, y) 
#{
#  (x | y) & !(x & y)
#}
#<bytecode: 0x2fbbb90>
#<environment: namespace:base>
Run Code Online (Sandbox Code Playgroud)

  • 从逻辑上讲,NA&FALSE肯定是FALSE(NA可能是TRUE或FALSE,但这不会改变第二个操作数为FALSE的事实).NA&TRUE是另一个故事 - 如果NA为TRUE,那么我们有TRUE,但如果NA为FALSE,那么我们就有FALSE,所以既然我们不知道NA的逻辑值,我们就不会知道结果.R在逻辑上是正确的,即使它看起来不合理!我认为你的代码可以实现回收和NA(我不足以确定Rcpp的爱好者,但我认为有些配方可以"开箱即用"). (4认同)
  • 我不知道这是否更好,但另一种选择是定义一个`nand`运算符:`\`%nand%\`< - function(x,y)!(x&y)`可以使用像这样:`a%nand%b`.(仅供参考,如果其中一个参数为"NA"而另一个为"TRUE"或"NA",则返回"NA".) (2认同)