r - 查找一系列 `n` TRUE 中第一个 TRUE 的位置

标签 r performance count boolean

来自 TRUE/FALSE 的向量

set.seed(1)
x = rnorm(1503501) > 0

我正在寻找一种高性能(快速)方法来获取第一个 n TRUE 系列中第一个 TRUE 的位置。

我正在处理的向量 (x) 恰好包含 1503501 元素(除了其中一些短得多的元素)。以下是我目前的解决方案。它使用 for 循环,但 for 循环在 R 中非常慢。是否有更好、尤其更快的解决方案?

n = 20

count = 0
solution = -1
for (i in 1:length(x)){
    if (x[i]){
        count = count + 1
        if (count == n){solution = i+1-n; break}
    } else {count = 0}
}
print(solution)
1182796

我正在考虑使用向量化函数并做类似 y = which(x) 或最终 y = paste(which(x)) 并寻找特定模式但我不确定该怎么做。

最佳答案

你可以使用Rcpp:

library(Rcpp)
cppFunction('int fC(LogicalVector x, int n) {
  int xs = x.size();
  int count = 0;
  int solution = -1;
  for (int i = 0; i < xs; ++i) {
    if (x[i]){
      if (++count == n){solution = i+2-n; break;}
    } else {
      count = 0;
    }
  }
  return solution;
}')

这是一个小型基准研究:

f1 <- function(x,n) {
  count = 0
  solution = -1
  for (i in 1:length(x)){
    if (x[i]){
      count = count + 1
      if (count == n){solution = i+1-n; break}
    } else {count = 0}
  }
  solution
}


set.seed(1)
x = rnorm(150350100) > 0
n = 20

print(f1(x,n)==fC(x,n))
# [1] TRUE


library(rbenchmark)
benchmark(f1(x,n),fC(x,n))
#       test replications elapsed relative user.self sys.self user.child sys.child
# 1 f1(x, n)          100  80.038  180.673    63.300   16.686          0         0
# 2 fC(x, n)          100   0.443    1.000     0.442    0.000          0         0

[更新基准]

# Suggested by BondedDust
tpos <- function(x,pos) { rl <- rle(x); len <- rl$lengths; 
                          sum(len[ 1:(which( len == pos & rl$values==TRUE)[1]-1)],1)}

set.seed(1)
x = rnorm(1503501) > 0
n = 20

print(f1(x,n)==fC(x,n))
# [1] TRUE
print(f1(x,n)==tpos(x,n))
# [1] TRUE


benchmark(f1(x,n),fC(x,n),tpos(x,n),replications = 10)
#         test replications elapsed relative user.self sys.self user.child sys.child
# 1   f1(x, n)           10   4.756  110.605     4.735    0.020          0         0
# 2   fC(x, n)           10   0.043    1.000     0.043    0.000          0         0
# 3 tpos(x, n)           10   2.591   60.256     2.376    0.205          0         0

关于r - 查找一系列 `n` TRUE 中第一个 TRUE 的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28685834/

相关文章:

javascript - 更高效的 Javascript

mysql - 选择另一个 ID 数量最多的 ID

c# - 使用 LINQ 计算嵌套的导航表行

r - R 中按天的观察次数

Rmarkdown 不在 For In 循环中生成表

r - 有 pmin 和 pmax 分别取 na.rm,为什么没有 psum?

带有两个连接表的 MySQL 查询、COUNT 和 SUM

r - 在 substr() 函数中使用 ls() 函数时出现问题

java - 额外字符串比较与 HashMap 查找的性能

.net - C++ ~ 1M 在 unordered_map 中使用字符串键查找比 .NET 代码慢得多