我有以下载体
v = c(F, F, F, T, F, F, F, F, F, T, F, F, F)
如何使用向量化操作更改v以使每个v TRUE元素的前2个元素和后2个元素也设置为TRUE?也就是说,结果应该是:
F, T, T, T, T, T, F, T, T, T, T, T, F
当然,这可以通过每个v元素上的循环来完成,但我想了解是否可以对这种操作进行矢量化。与this question不同,v中的元素是独立的,我不需要对每个元素执行计算。这是一个纯粹的索引问题。
答案 0 :(得分:11)
这个排序的东西可能会像你想要的那样被矢量化:
v[unlist(sapply(which(v),function(x) {x + c(-2,-1,1,2)},simplify = FALSE))] <- TRUE
> v
[1] FALSE TRUE TRUE TRUE TRUE TRUE FALSE TRUE TRUE TRUE TRUE TRUE FALSE
但请注意,您尚未指定在向量末端附近的TRUE元素中应该发生什么。这需要更多的工作。如果有两个TRUE元素彼此相距两个以上的位置,那么你也没有说明会发生什么。
可替换地:
v[outer(which(v),c(-2,-1,1,2),"+")] <- TRUE
> v
[1] FALSE TRUE TRUE TRUE TRUE TRUE FALSE TRUE TRUE TRUE TRUE TRUE FALSE
在基本层面,我们在这里做同样的事情,但第二种选择肯定更紧凑,虽然可能更难理解。
答案 1 :(得分:5)
晚会......您应该应用卷积过滤器。它会比任何东西都快。唯一的困难是,在两个末端你应该预先添加/追加一对FALSE
,这样过滤器就不会用NA
进行初始化。这是一个可以为您完成的功能:
within.distance <- function(x, d = 2) {
xxx <- c(rep(FALSE, d), x, rep(FALSE, d))
yyy <- as.logical(filter(xxx, rep(1, 2*d+1)))
head(tail(yyy, -d), -d)
}
within.distance(v)
# [1] FALSE TRUE TRUE TRUE TRUE TRUE FALSE TRUE TRUE TRUE TRUE TRUE FALSE
答案 2 :(得分:3)
这是另一次尝试。它似乎适用于您的数据以及第一个元素为TRUE时。
as.logical(rowSums(embed(c(FALSE, FALSE, v, FALSE, FALSE), 5)))
# [1] FALSE TRUE TRUE TRUE TRUE TRUE FALSE TRUE TRUE TRUE TRUE TRUE FALSE
# another attempt with beginning and end TRUE
v = c(T, F, F, F, F, F, T, F, F, F, F, F, T)
# [1] TRUE TRUE TRUE FALSE TRUE TRUE TRUE TRUE TRUE FALSE TRUE TRUE TRUE
类似于@ flodel的想法,可以在这里创建一个函数:
rollOR <- function(vec, dir="both", dist=2) {
stopifnot(dir %in% c("left", "right", "both"))
stopifnot(dist >= 0)
stopifnot(is.logical(vec))
cvec <- rep(FALSE, dist)
switch(dir,
both = {
vec <- c(cvec, vec, cvec)
dist <- dist * 2 + 1
},
left = {
vec <- c(vec, cvec)
dist <- dist + 1
},
right = {
vec <- c(cvec, vec)
dist <- dist + 1
})
as.logical(rowSums(embed(vec, dist)))
}
# direction both sides
rollOR(v, "both", 2)
# [1] FALSE TRUE TRUE TRUE TRUE TRUE FALSE TRUE TRUE TRUE TRUE TRUE FALSE
# left alone
rollOR(v, "left", 2)
# [1] FALSE TRUE TRUE TRUE FALSE FALSE FALSE TRUE TRUE TRUE FALSE FALSE FALSE
# right alone
rollOR(v, "right", 2)
# [1] FALSE FALSE FALSE TRUE TRUE TRUE FALSE FALSE FALSE TRUE TRUE TRUE FALSE
答案 3 :(得分:1)
又一种方法。创建一组滞后向量,并将or
组合在一起:
library(Hmisc)
library(functional)
within.distance <- function(x, d=2) {
FLag <- function(x, shift) {
x <- Lag(x, shift)
x[is.na(x)] <- FALSE
return(x)
}
l <- lapply((-d):d, Curry(FLag, x=x))
return(Reduce(`|`, l))
}