在R中过滤1s和-1s的向量

时间:2014-12-09 14:36:48

标签: r for-loop vectorization

我想对以下向量应用几个过滤器:

v <-c(1,1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,-1,-1,-1,-1,-1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,-1,-1,-1,-1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,1,-1,-1,-1,-1,1,1,1,1,1,1,-1,-1,-1,-1-1,-1,-1,-1,-1,1,1,1,-1,-1,1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1-1,-1,-1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,-1,-1,-1,-1,-1,1,1,1,1,1-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,1,-1,-1,-1,-1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,-1,-1,-1,1,1,1,1,1,1,-1,-1,-1,-1-1,-1,-1,-1,-1,1,1,1,1,1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1-1,1,1,1)

我想申请的过滤器应该在-1之间删除1,反之亦然。过滤器应该是3,4,5和6个元素,如下所示:

( - 1,1,-1)到(-1,-1,-1)

(1,-1,1)至(1,1,1)

( - 1,1,1,-1)到(-1,-1,-1,-1)

(1,-1,-1,1)到(1,1,1,1)

( - 1,1,1,1,-1)到(-1,-1,-1,-1,-1)

(1,-1,-1,-1,1)到(1,1,1,1,1)

( - 1,1,1,1,1,-1)到(-1,-1,-1,-1,-1,-1)

(1,-1,-1,-1,-1,1)到(1,1,1,1,1,1)

我先使用for-loop然后尝试使用paste和gsub对循环进行矢量化(请参阅下面的完整示例)

然而,矢量化版本不会产生与for循环相同的结果(因为它没有考虑在下一个步骤中的一个步骤中发生的变化)

该代码的矢量化版本是否实际上与for-loop具有相同的效果?


两个使用for-loop vs paste和gsub的完整示例:

v <-c(1,1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,-1,-1,-1,-1,-1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,-1,-1,-1,-1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,1,-1,-1,-1,-1,1,1,1,1,1,1,-1,-1,-1,-1-1,-1,-1,-1,-1,1,1,1,-1,-1,1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1-1,-1,-1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,-1,-1,-1,-1,-1,1,1,1,1,1-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,1,-1,-1,-1,-1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,-1,-1,-1,1,1,1,1,1,1,-1,-1,-1,-1-1,-1,-1,-1,-1,1,1,1,1,1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1-1,1,1,1)
t1 <- v
t2 <- v

-1 1 -1到-1 -1 -1

for (i in 2:(length(t1)-1)) {
        if (t1[i-1]==-1 & t1[i+1]==-1 & t1[i]==1){
                t1[i] <- -1   
        } 
}

1 -1 1到1 1 1

for (i in 2:(length(t1)-1)) {
        if (t1[i-1]==1 & t1[i+1]==1 & t1[i]==-1){
                t1[i] <- 1
        } 
}

-1 1 1 -1至-1 -1 -1 -1

for (i in 3:(length(t1)-1)) {
        if (t1[i-2]==-1 & t1[i+1]==-1 & t1[i]==1 & t1[i-1] ==1) {
                t1[i]   <- -1
                t1[i-1] <- -1
        }
}

1 -1 -1 1到1 1 1 1

for (i in 3:(length(t1)-1)) {
        if (t1[i-2]==1 & t1[i+1]==1 & t1[i]==-1 & t1[i-1] ==-1) {
                t1[i]   <- 1
                t1[i-1] <- 1
        }
}

-1 1 1 1 -1至-1 -1 -1 -1 -1

for (i in 4:(length(t1)-1)) {
        if (t1[i-3]==-1 & t1[i+1]==-1 & t1[i-2]==1 & t1[i-1] ==1 & t1[i] ==1) {
                t1[i-2]   <- -1
                t1[i-1]   <- -1
                t1[i]     <- -1
        }
}

1 -1 -1 -1 1到1 1 1 1 1

for (i in 4:(length(t1)-1)) {
        if (t1[i-3]==1 & t1[i+1]==1 & t1[i-2]==-1 & t1[i-1] ==-1 & t1[i] ==-1) {
                t1[i-2]   <- 1
                t1[i-1]   <- 1
                t1[i]     <- 1
        }
}

-1 1 1 1 1 -1至-1 -1 -1 -1 -1 -1

for (i in 5:(length(t1)-1)) {
        if (t1[i-4]==-1 & t1[i+1]==-1 & t1[i-3]==1 & t1[i-2]==1 & t1[i-1] ==1 & t1[i] ==1) {
                t1[i-3]   <- -1
                t1[i-2]   <- -1
                t1[i-1]   <- -1
                t1[i]     <- -1
        }
}

1 -1 -1 -1 -1 1至1 1 1 1 1 1

for (i in 5:(length(t1)-1)) {
        if (t1[i-4]==1 & t1[i+1]==1 & t1[i-3]==-1 & t1[i-2]==-1 & t1[i-1] ==-1 & t1[i] ==-1) {
                t1[i-3]   <- 1
                t1[i-2]   <- 1
                t1[i-1]   <- 1
                t1[i]     <- 1
        }
}

现在是矢量化的gsub版本:

t2 <- paste(v, collapse="")

-1 1 -1到-1 -1 -1

t2 <- gsub("-11-1", "-1-1-1", t2)

1 -1 1到1 1 1

t2 <- gsub("1-11", "111", t2)

-1 1 1 -1至-1 -1 -1 -1

t2 <- gsub("-111-1", "-1-1-1-1", t2)

1 -1 -1 1到1 1 1 1

t2 <- gsub("1-1-11", "1111", t2)

-1 1 1 1 -1至-1 -1 -1 -1 -1

t2 <- gsub("-1111-1", "-1-1-1-1-1", t2)

1 -1 -1 -1 1到1 1 1 1 1

t2 <- gsub("1-1-1-11", "11111", t2)

-1 1 1 1 1 -1至-1 -1 -1 -1 -1 -1

t2 <- gsub("-11111-1", "-1-1-1-1-1-1", t2)

1 -1 -1 -1 -1 1至1 1 1 1 1 1

t2 <- gsub("1-1-1-1-11", "111111", t2)

t2 <-as.integer(strsplit(t2, "(?<=\\d)", perl = TRUE)[[1]])
all.equal(t1, t2)

[1]&#34;平均相对差异:2&#34;

1 个答案:

答案 0 :(得分:1)

您可以轻松地将其翻译为Rcpp:

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
IntegerVector myfilter(IntegerVector x) {
  for (int i = 1; i < (x.size() - 1); i++) {
    if (x(i-1) == -1 && x(i+1) == -1 && x(i) == 1) {
      x(i) = -1;
    }    
  }

  for (int i = 2; i < (x.size() - 1); i++) {
    if (x(i-2) == -1 && x(i-1) == 1 && x(i+1) == -1 && x(i) == 1) {
      x(i) = -1;
      x(i-1) = -1;
    }    
  }  
   return x;
}

在R中测试它:

t1 <- myfilter(t)

for (i in 2:(length(t)-1)) {
  if (t[i-1]==-1 & t[i+1]==-1 & t[i]==1){
    t[i] <- -1   
  } 
}

for (i in 3:(length(t)-1)) {
  if (t[i-2]==-1 & t[i+1]==-1 & t[i]==1 & t[i-1] ==1) {
    t[i]   <- -1
    t[i-1] <- -1
  }
}

all.equal(t, t1)
#[1] TRUE