R:通过选择多个子区域有效地过滤数字向量

时间:2017-06-07 13:50:43

标签: r select vector

我有一个相对较大的数字向量x,我只对在nlower边界指定的upper个子区域内找到的值感兴趣(包括在内) )。什么是最有效(最重要),简洁(只要代码是可读的不太重要)实现这一点的方法?我需要输出为逻辑(或整数)值的向量,以便我可以使用所选区域索引另一个向量。

假设我有以下数据:

x <- 1:20
lower <- c(0.8, 3.9,  9, 12, 19)
upper <- c(2.1, 6.1, 13, 17, 19)

输出应为:

out <- c(TRUE,  TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, 
         TRUE,  TRUE, TRUE,  TRUE, TRUE, TRUE, TRUE,  FALSE, TRUE, FALSE)

我有一个解决方案,但对我来说似乎有些笨拙,我不知道它是否有效:

library(dplyr)
library(purrr)

out.list <- map2(lower, upper, ~ between(x, .x, .y))
out.mat <- do.call(rbind, out.list)
out.vec <- apply(out.mat, 2, any)

# Check output
all(out.vec == out)
[1] TRUE

虽然预计x不会比一百万个元素大得多,但我需要为许多不同的x值重复该过程。

编辑:更新了浮点和重叠边界的示例。

更新:我认为这个问题比链接的问题更简洁和一般。我会在链接的问题中选择已删除的data.table答案,而不是选择的答案(对dplyr / tidyr有偏好)。

library(data.table)
library(microbenchmark)

lower <- runif(100, 0.5, 8.5)
upper <- runif(100, 0, 1)
x <- runif(1e5, 1, 10)

microbenchmark(inrange = inrange(x, lower, upper),
               sapply = sapply(x,function(v){ any(v >= lower & v <= upper) })) 

   expr        min         lq       mean    median         uq      max neval
inrange   5.757293   5.991459   6.527294   6.10907   6.417622  10.0425   100
 sapply 280.412724 290.914073 300.813885 295.15648 300.568322 356.7478   100

1 个答案:

答案 0 :(得分:1)

这个怎么样?

out <- sapply(x,function(v){ any(v >= lower & v <= upper) })

> out 
[1]  TRUE  TRUE FALSE  TRUE  TRUE  TRUE FALSE FALSE  TRUE  TRUE  TRUE
[12]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE FALSE