R 删除向量中至少N个连续值的序列

R 删除向量中至少N个连续值的序列,r,optimization,vector,R,Optimization,Vector,这是我的问题。我有大量的正面数据。我的目标是删除至少N个连续值的序列​​在向量中重复的(所有重复值必须严格大于0) 我已经编写了一个程序,如下所示: X是我的数值向量; N是重复序列的最小长度 rmpParNASerieRepetee <- function(X, N) { X_ <- paste("T", paste(X, collapse="T"), "T", sep="") ind.parcours <- 1 ind.sup <- c()

这是我的问题。我有大量的正面数据。我的目标是删除至少N个连续值的序列​​在向量中重复的(所有重复值必须严格大于0)

我已经编写了一个程序,如下所示: X是我的数值向量; N是重复序列的最小长度

rmpParNASerieRepetee <- function(X, N)
{
    X_ <- paste("T", paste(X, collapse="T"), "T", sep="")
    ind.parcours <- 1
    ind.sup <- c()

    # Loop on the values
    while ( ind.parcours <= (length(X)-N+1) )
    {
        # indices of my sequence of N values
        deb <- ind.parcours
        fin <- ind.parcours + N-1

        # sequence of N values to search in the vector
        serie  <- X[deb:fin]
        serie_ <- paste("T", paste(serie, collapse="T"), "T", sep="")


        borne <- 1*(ind.parcours < (length(X)-N+1)) + 0*(ind.parcours == (length(X)-N+1))
        if (sum(X[(length(X)-N+1):length(X)]==serie)==3) borne <- 0

        # split my string vector by my sequence vector of N values and count the pieces of result
        if ( length(unlist(strsplit(X_, serie_)))-1 > borne && length(which(serie!=0))>=N)
        { ind.sup <- unique(c(ind.sup, deb:fin)) }
        ind.parcours <- ind.parcours+1
    }
    if (length(ind.sup !=0)) { X[ind.sup] <- NA }

    list_return <- list(X=X, Ind.sup=unique(sort(ind.sup)))
    return (list_return)
}

rmpparnaserieretee考虑这一点的一种方法是,在一个序列中,每个元素与最后一个元素相差1,因此:

X    <- c(1,2,3,4,0,0,0,0,1,4,1,2,3,4,8,9,1,2,3,1,4,1,0,0,0)
y    <- X[-1]
diff <- y-X[1:length(X)-1]
diff
[1]  1  1  1 -4  0  0  0  1  3 -3  1  1  1  4  1 -8  1  1 -2  3 -3 -1  0  0

X尝试使用
表格
和%
中的
%in%
来获得更快的速度,因为矢量化

rmpParNASerieRepetee<-function(X,N){
  tab<-table(X[X>0])
  over.n<-as.numeric(names(tab)[tab>=N])
  ind<-X %in% over.n
  Ind.sup<-which(ind)
  X<-ifelse(ind,NA,X)
  list(Ind.sup,X)
}

X <- c(1,2,3,4,0,0,0,0,1,4,1,2,3,4,8,9,1,2,3,1,4,1,0,0,0)
rmpParNASerieRepetee(X,3)
# [[1]]
# [1]  1  2  3  4  9 10 11 12 13 14 17 18 19 20 21 22
# 
# [[2]]
# [1] NA NA NA NA  0  0  0  0 NA NA NA NA NA NA  8  9 NA NA NA NA NA NA  0  0  0
rmpparanserierepeteA方法:


f我已经优化了我的函数,现在对于长度为92000的向量,“只”需要10分钟。
也许有人能找到比我更快的解决方案


假设我的向量是
x为什么不描述一下你要做的事情,它比放代码有用得多。你的数据看起来像整数。如果是这种情况,按原样存储(
integer
而不是
numeric
)可以使建议的答案更快。问题:单个元素可以有多大?它们都在(0,9)中吗?不,我不知道这些值。它可以是2作为1256。我添加了一个例子,你能看到我的新编辑吗?谢谢+1,但您真的应该在代码中留出一些空间。例如
Ind可能使用
over.n=n)
X[Ind.sup]我的序列是由n个连续的值组成的。事实是:让
X@sandikou抱歉,我想我误解了你的问题。我的误解恰好有相同的结果,这使我相信我理解正确。我的重复序列可能是
c(1,4,1)
,在这种情况下,
diff
函数不能帮助记忆序列由N个连续值组成
c(1,4,1,4,1,4,1,4,1,4)
在大多数人对这个词的理解中不是“连续的”。这是一个循环长度为2的重复序列。我的序列由N个连续序列组成values@sandikou,它们返回的输出与您在问题中显示的相同。所以,如果这不是你想要的,你需要更清楚一点并编辑你的问题。这是不够的。请提供一个例子,说明您对连续性的定义与此相关。同样,这里的答案给出的输出与您的相同…@sandikou:您能否添加一个示例,说明您的函数与此处发布的函数之间的输出不同?一、 老实说,我不能得到它。这也给出了一个与OP的代码
x不同的结果
rmpParNASerieRepetee<-function(X,N){
  tab<-table(X[X>0])
  over.n<-as.numeric(names(tab)[tab>=N])
  ind<-X %in% over.n
  Ind.sup<-which(ind)
  X<-ifelse(ind,NA,X)
  list(Ind.sup,X)
}

X <- c(1,2,3,4,0,0,0,0,1,4,1,2,3,4,8,9,1,2,3,1,4,1,0,0,0)
rmpParNASerieRepetee(X,3)
# [[1]]
# [1]  1  2  3  4  9 10 11 12 13 14 17 18 19 20 21 22
# 
# [[2]]
# [1] NA NA NA NA  0  0  0  0 NA NA NA NA NA NA  8  9 NA NA NA NA NA NA  0  0  0
X<-sample(1:10000,92000,TRUE)
system.time(rmpParNASerieRepetee(X,3))
#   user  system elapsed 
#   0.14    0.00    0.14 
f <- function(X, N)
{
 .rle <- rle(sort(X))
 res <- .rle$values[.rle$lengths >= N]
 res <- res[res > 0]
 inds <- X %in% res
 X[inds] <- NA 
 list(X = X, Ind = which(inds)) 
}

#> f(X, 3)
#$X
# [1] NA NA NA NA  0  0  0  0 NA NA NA NA NA NA  8  9 NA NA NA NA NA NA  0  0  0
#
#$Ind
# [1]  1  2  3  4  9 10 11 12 13 14 17 18 19 20 21 22
# Function to count NA in a vector
count.na <- function(vec) { return (length(which(is.na(vec)))) }

# Function to detect sequence of stricly postive numbers of length at least N
rmpParNASerieRepetee <- function(X, N, val.min=0)
{
    # Collapse the vector to make a big string
    X_ <- paste("T", paste(X, collapse="T"), "T", sep="")

    # Index term
    ind.parcours <- 1
    ind.sup <- c()

    # Loop on X values
    while ( ind.parcours <= (length(X)-N+1) )
    {
         # Selection of the sequence to be detected
         deb <- ind.parcours
         fin <- ind.parcours + N-1
         serie <- X[deb:fin]

            # All values are > 0
            if ( length(which(serie>0)) >= (N-count.na(serie)) )
            {
                    # Research of repetition with strsplit
                    serie_ <- paste("T", paste(serie, collapse="T"), "T", sep="")
                    borne <- 1*(ind.parcours < (length(X)-N+1)) + 0*(ind.parcours == (length(X)-N+1)) 
                    if (sum(X[(length(X)-N+1):length(X)]==serie, na.rm=TRUE)==N) borne <- 0

                    if (length(unlist(strsplit(X_, serie_)))-1 > borne) 
                         ind.sup <- unique( c(ind.sup, deb:fin) )

                    # Incrementation
                    ind.parcours <- ind.parcours + 1
             }
            # Contains 0
            else
            {   ind.parcours <- ind.parcours + max(which(serie==0))
            }
    }

    # Invalidaion of repeated sequences
    if (length(ind.sup !=0)) { X[ind.sup] <- NA }

    # Return
    list_return <- list(X=X, Ind.sup=unique(sort(ind.sup)))
    return (list_return)

 }