【问题标题】:What is the fastest way to perform multiple logical comparisons in R?在 R 中执行多个逻辑比较的最快方法是什么?
【发布时间】:2015-12-29 22:05:05
【问题描述】:

在 R 中执行多重逻辑比较的最快方法是什么?

例如考虑向量x

set.seed(14)
x = sample(LETTERS[1:4], size=10, replace=TRUE)

我想测试x 的每个条目是“A”还是“B”(而不是其他)。以下作品

x == "A" | x == "B"
[1]  TRUE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE

上面的代码在整个向量的长度上循环了三遍。 R中有没有办法只循环一次并测试每个项目是否满足一个或另一个条件?

【问题讨论】:

  • 怎么样:x %in% c("A","B")
  • @MrFlick 我一直在玩弄这两个选项的时间,但我并没有看到太大的区别,真的。即使我把它变大,规模也是纳秒级的,所以我有点迷茫。
  • @joran 是的,我不认为你会看到速度大幅提升(我非常怀疑这是任何性能瓶颈所在),但这只是一种语法替代。

标签: r performance logical-operators


【解决方案1】:

如果你的目标只是一次通过,那么用 Rcpp 编写非常简单,即使你对 C++ 没有太多经验:

#include <Rcpp.h>

// [[Rcpp::export]]
Rcpp::LogicalVector single_pass(Rcpp::CharacterVector x, Rcpp::String a, Rcpp::String b) {
  R_xlen_t i = 0, n = x.size();
  Rcpp::LogicalVector result(n);

  for ( ; i < n; i++) {
    result[i] = (x[i] == a || x[i] == b);
  }

  return result;
}

对于您示例中使用的这样一个小对象,.Call 的轻微开销(大概)掩盖了 Rcpp 版本的速度,

r_fun <- function(X) X == "A" | X == "B"
##
cpp_fun <- function(X) single_pass(X, "A", "B")
##
all.equal(r_fun(x), cpp_fun(x))
#[1] TRUE
microbenchmark::microbenchmark(
  r_fun(x), cpp_fun(x), times = 1000L)
#Unit: microseconds
#expr         min    lq     mean median     uq    max neval
#r_fun(x)   1.499 1.584 1.974156 1.6795 1.8535 37.903  1000
#cpp_fun(x) 1.860 2.334 3.042671 2.7450 3.1140 51.870  1000

但是对于更大的向量(我假设这是你的真正意图),它要快得多:

x2 <- sample(LETTERS, 10E5, replace = TRUE)
##
all.equal(r_fun(x2), cpp_fun(x2))
# [1] TRUE
microbenchmark::microbenchmark(
  r_fun(x2), cpp_fun(x2), times = 200L)
#Unit: milliseconds
#expr              min        lq      mean    median        uq      max neval
#r_fun(x2)   78.044518 79.344465 83.741901 80.999538 86.368627 149.5106   200
#cpp_fun(x2)  7.104929  7.201296  7.797983  7.605039  8.184628  10.7250   200

如果您有任何用处,这里有一个quick attempt 用于概括上述内容。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    • 2021-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多