如何矢量化访问R中的邻居向量元素?
我有以下矢量如何矢量化访问R中的邻居向量元素?
v = c(F, F, F, T, F, F, F, F, F, T, F, F, F)
如何变更V SO是每个V真元前2种元素和下面的2个元素也被设置为TRUE,使用矢量操作?也就是说,该结果应该是:
F, T, T, T, T, T, F, T, T, T, T, T, F
当然,这可能是与每个V元素循环中完成的,但我想知道是否有可能向量化这种操作。也不同于this question,v中的元素是独立的,我不需要在每个元素上执行计算。这是一个纯粹的索引问题。
这类的事情可能是因为矢量,你会得到:
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元素比两个位置距离更近,会发生什么情况。
或者:
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
在基本层面,我们在这里做同样的事情,但第二个选项肯定是更紧凑,尽管可能很难理解。
这是另一个尝试。它似乎对你的数据有效,当第一个元素为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
+1 - 非常好! – flodel 2013-04-25 02:19:36
迟到了......你应该申请一个卷积过滤。它会比任何事情都快。唯一的困难是在两端都应该预先加入/追加一对FALSE
,所以过滤器不会使用NA
s进行初始化。这里有一个功能可以帮你:
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
很好的使用过滤器。 – 2013-04-25 03:08:53
证明第一个答案并不总是最好的。尼斯。 – joran 2013-04-25 21:33:58
还有另一种方法。创建一组滞后载体,并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))
}
您可以修改它包括那些约束:'v [独特(as.vector(sapply(其中(V),功能(X){如果( x> 2){x + c(-2,-1,1,2)} else {1:(x + 2)}})))] harkmug 2013-04-24 20:06:42
@rmk是的,虽然只处理我认为,左端点。当然,对于另一端可以做类似的事情,但是我想我们想放弃匿名功能,我想。 – joran 2013-04-24 20:09:42
@rmk检查此线程以讨论如何在边缘修剪矢量:http://stackoverflow.com/questions/16220521/how-to-trim-an-r-vector/16222580#16222580 – 2013-04-25 21:08:20