【发布时间】:2017-06-07 22:35:35
【问题描述】:
我有一个相对较大的数值向量x,我只对在n 子区域中找到的值感兴趣,这些子区域由lower 和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
【问题讨论】:
-
刚开始查找
inrange函数时才看到这篇文章。 -
如果链接的答案正常,我们可以将其作为欺骗关闭
-
@docendodiscimus 没问题,但我更喜欢您发布的
inrange()解决方案。链接的问题对 dplyr/tidyr 有明确的偏好。