匹配一个向量的某个值与其他向量的值范围

时间:2016-01-25 17:54:06

标签: r matching

我有两个向量(相同的长度),只包含0和1(为了简化,我在本例中使用了v1和v2)。我想计算每次v1和v2在同一位置的值为1或在v2的某个范围内。例如,对于范围+ -3(rad = 3),如果v1 [10]的值为1,我想知道v2的下列值之一是否也是1:v2 [7],v2 [8 ],v2 [9],v2 [10],v2 [11],v2 [12]或v [13]。我现在使用的脚本,但它也会在值为0时对匹配进行计数。如何更改它以便只考虑值为1的匹配?

set.seed(1)
v1 <- sample(0:1, 20, replace = TRUE)
v2 <- sample(0:1, 20, replace = TRUE)

matches <- vector()
rad <- 3 

for (i in 1:length(v1)){

  if ((i - rad) < 0){

    matches[i] <- ifelse(v1[i] %in% v2[1:rad], TRUE, FALSE)

  } else{

    matches[i] <- ifelse(v1[i] %in% v2[(i-rad):(i+rad)], TRUE, FALSE)

 }

}

4 个答案:

答案 0 :(得分:4)

另一个想法:

ff = function(x, y, rad)
{
    wx = which(x == 1L)
    wy = which(y == 1L)
    i = findInterval(wx, wy, all.inside = TRUE)

    ans = logical(length(x))
    ans[wx[pmin(abs(wx - wy[i]), abs(wy[i + 1] - wx)) <= rad]] = TRUE
    ans
}
ff(v1, v2, 3)
#[1] FALSE FALSE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE  TRUE FALSE  TRUE FALSE  TRUE  TRUE FALSE  TRUE

答案 1 :(得分:1)

我会在答案之前说你正在用一点C语言说R:循环很少是在R中完成某些事情的正确选择。如果你是R的新手,你可能看不到矢量化一切的重点 - 使用矢量化代码的理由通常是谈论它如何运行得更快,而对于现代计算机上的小型应用程序,你不太可能看到差异。你通常可以使用循环来破解你想要做的事情。但是矢量化内置于语言中,而在R中,矢量化解决方案通常更加清晰。对矢量化而不是通过循环做一些事情感到满意将长期帮助你从真正非常强大和有用的语言中获得更多。

所有这一切,我将建议一种方法,你可以使用sapply函数完成你想要的。首先,您可以定义一个函数,给定索引i检查(a)向量1的i元素是否为1,以及(b)是否有任何元素在向量2的i加或减rad条目中也是1

f <- function(i, rad, x, y) {
  range_min <- max(i - rad, 1)
  range_max <- min(i + rad, length(y))
  a <- x[i] == 1
  b <- 1 %in% y[range_min:range_max]
  return(a & b)
}

接下来,定义你的向量和半径,并创建一个f的版本,它接受一个参数,即索引i,并将其他三个设置为你的特定值:

set.seed(1)
v1 <- sample(0:1, 20, replace = TRUE)
v2 <- sample(0:1, 20, replace = TRUE)
radius <- 3

g <- function(i) {
  return(f(i, radius, v1, v2))
}

然后,您可以对sapply的索引向量使用1v1的长度,以生成向量v,其中每个元素{{1} }是将v[i]应用于g索引的结果:

i

请注意,您可以通过在v <- sapply(1:length(v1), g) 语句中定义g来合并最后两个步骤,如下所示:

sapply

R越多,你就越发现R语言的各种功能比使用循环的代码更好地支持这种代码。话虽如此,如果你已经开始修改现有代码以使循环工作,你可以将你v <- sapply(1:length(v1), function(i){f(i, radius, v1, v2)}) 函数的逻辑向量更改为两个条件的ifelse,如此:

&

答案 2 :(得分:1)

还有一个,使用滚动窗口。

owlCarousel.trigger('add.owl.carousel', [item])

答案 3 :(得分:0)

这是一个data.table解决方案

library(data.table)
dt=data.table(v1,v2)
rad = 3L
dt[,mtch:=(v1!=0L)&(v1%in%dt$v2[max(.I-rad,0):min(.I+rad,nrow(dt))]),
   by=1L:nrow(dt)]$mtch

这给出了

#[1] FALSE FALSE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE  TRUE FALSE  TRUE FALSE  TRUE  TRUE FALSE  TRUE