代码之家  ›  专栏  ›  技术社区  ›  Andre Elrico

为真值定义一个“缓冲区”,如果在“缓冲区”内,则将真变为假

r
  •  2
  • Andre Elrico  · 技术社区  · 7 年前

    buffer 之后 TRUE 哪里没有 我可以活下去。

    数据:

    vec <- as.logical(c(1,0,1,1,1,0,1,1,0,1))
    
    #[1]  TRUE FALSE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE FALSE  TRUE
    

    buffer = 1
    #[1]  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE FALSE  TRUE
    

    和

    buffer = 2
    #[1]  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE
    

    buffer = 3
    #[1]  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE
    
    3 回复  |  直到 7 年前
        1
  •  7
  •   Cath    7 年前

    也许有更好的方法,但这里有一个选择,通过 TRUE 价值观 vec :

    changeTRUE <- function(vec, buffer){
                     first_TRUE <- which(vec)[1] # get the first TRUE value index
                     i <- 1 # just so we can move on other TRUE values later
                     while(first_TRUE < length(vec)){ # while there are some TRUE
                       vec[(first_TRUE+1):min((first_TRUE+buffer), length(vec))] <- FALSE # put FALSE after the TRUE value according to buffer value (but not further than the end of vec)
                       i <- i+1 # to go to next TRUE
                       first_TRUE <- which(vec)[i] # get next TRUE index...
                     }
                     return(vec)
                 }
    
    changeTRUE(vec, 1)
     [1]  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE FALSE  TRUE
    changeTRUE(vec, 2)
     [1]  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE
    changeTRUE(vec, 3)
     [1]  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE
    
        2
  •  2
  •   Tensibai    7 年前

    使用递归函数的@ CATH答案的变体,我不期望它比原始WILE循环更快,这是为了教育目的(将在大向量上断裂,R将考虑在某个点上的无限递归):

    cT2 <- function(vec, buffer, index = 1) {
      if (!is.na(first_TRUE <- which(vec)[index])) {
        vec[(first_TRUE+1):min((first_TRUE+buffer), length(vec))] <- FALSE
        vec <- cT2(vec,buffer, index+1)
      }
      vec
    }
    

    出于好奇,目前为止所有解决方案的一个小基准(我的系统因更大的向量而崩溃,我没有深入研究哪个函数导致它崩溃,我怀疑是我的):

    library(microbenchmark)
    set.seed(123)
    vec <- sample(c(TRUE,FALSE),1e4,TRUE)
    microbenchmark(changeTRUE(vec,3),cT2(vec,3),changeTRUE2(vec,3),times=10)
    

    Unit: milliseconds
                    expr       min        lq     mean    median        uq       max neval
      changeTRUE(vec, 3)  64.58125  65.36158  67.4990  66.26165  67.70284  73.94888    10
             cT2(vec, 3)  75.84567  81.25721 111.0525 122.09651 124.63022 134.54896    10
     changeTRUE2(vec, 3) 179.11084 185.51882 201.1573 193.79123 217.79790 234.92004    10
    
        3
  •  1
  •   Andre Elrico    7 年前

    一个没有 i<-

    changeTRUE2 <- function(vec, buffer){
        first_TRUE <- which(vec)[1]
            while(first_TRUE < length(vec)){
            vec[(first_TRUE+1):min((first_TRUE+buffer), length(vec))] <- FALSE
            first_TRUE <- which(c(rep(FALSE,first_TRUE),vec[-(1:first_TRUE)]))[1]
        }
        return(vec)
    }
    
    changeTRUE(vec, 1)
    changeTRUE2(vec, 1)
    changeTRUE(vec, 2)
    changeTRUE2(vec, 2)
    changeTRUE(vec, 3)
    changeTRUE2(vec, 3)
    

    不知道这是否更快。