Иметь определенный «буфер» для значений ИСТИНА и превратить ИСТИНА в ЛОЖЬ, если внутри «буфера» - PullRequest
0 голосов
/ 27 ноября 2018

buffer означает минимальное количество мест после TRUE, где не может жить TRUE.

data:

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 ]

0 голосов
/ 27 ноября 2018

Вариант ответа @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
0 голосов
/ 27 ноября 2018

Все кредиты идут на решение @ Cath

Версия без 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)

Не уверен, будет ли это быстрее.

0 голосов
/ 27 ноября 2018

Возможно, есть лучший способ, но здесь есть опция, циклически перебирающая значения 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...