从矢量中提取元素,同时跳过固定数量的元素

时间:2017-12-30 02:52:34

标签: r

说我有这个载体:

a <- round(runif(100, 0, 1), digits = 0)

我想在向量中找到包含数字1的第一个元素。找到该元素后,跳过3个元素(即使它们包含1个),然后找到包含1的下一个元素并重复查找1并跳过找到1s后的3个元素。

我想要的输出是第一个包含1的元素的行号,后面是包含1的其余行号,在考虑跳过的元素之后。

3 个答案:

答案 0 :(得分:1)

我不认为你可以在不诉诸某种循环的情况下做到这一点。这是一种方法。首先,我们得到所有位置的向量。然后我们重复找到该向量的第一个元素,该元素与前一个元素相差3或更少,并从列表中删除它。重复,直到你删除了所有那些离他们的预先测试者太近的人。

x = which(a==1) 
repeat  {
  to.remove = which(diff(x) <= 3)[1] + 1  
  if (is.na(to.remove)) break
  x = x[-to.remove]
}

如果你正在处理非常大的向量,可能有更有效的方法来做到这一点,如果速度是一个问题,也许可以考虑RCpp。

答案 1 :(得分:0)

也许是while循环?

set.seed(123)
a <- round(runif(100,0,1), digits =0)
n <- length(a)
ind_less_n <- 1
i <- 1
index_save <- numeric(n)
while(ind_less_n){
  if(a[i] == 1){
    index_save[i] <- 1
    i <- i + 4
  } else {
    i <- i + 1
  }
  if(i > n) ind_less_n <- 0
}
head(cbind(a, index_save), 20)
      a index_save
 [1,] 0          0
 [2,] 1          1
 [3,] 0          0
 [4,] 1          0
 [5,] 1          0
 [6,] 0          0
 [7,] 1          1
 [8,] 1          0
 [9,] 1          0
[10,] 0          0
[11,] 1          1
[12,] 0          0
[13,] 1          0
[14,] 1          0
[15,] 0          0
[16,] 1          1
[17,] 0          0
[18,] 0          0
[19,] 0          0
[20,] 1          1

您可以使用which(index_save == 1)

提取行号

答案 2 :(得分:0)

您可以将Reduceaccumulate = TRUEpurrr::accumulate一起使用,但您需要迭代一个列表,其中包含结果和跳过计数的单独元素,例如

library(tidyverse)
set.seed(47)

df_ones <- data_frame(a = rbinom(100, 1, .5),    # make sample data
                      is_one = a,    # initialize result and count
                      count = NA) %>% 
    split(seq(nrow(.))) %>%    # split into list of one-row data frames
    accumulate(    # for each sequential pair of elements, return and pass on a list of...
        ~list(a = .y$a,    # the original value for checking,
              is_one = if(.x$count <= 3) 0 else .y$is_one,    # the result, changing 1 to 0 where required, and 
              # the count since a 1, resetting when a 1 is kept
              count = if(.x$count > 3 & .y$is_one) {
                  1
              } else {
                  .x$count + 1
              }),
        .init = list(a = NA, is_one = 0, count = 4)    # set initial .x value
    ) %>% 
    bind_rows() %>%    # collapse resulting list to data frame
    slice(-1)    # remove row for initializing value

df_ones
#> # A tibble: 100 x 3
#>        a is_one count
#>    <int>  <dbl> <dbl>
#>  1     1      1     1
#>  2     0      0     2
#>  3     1      0     3
#>  4     1      0     4
#>  5     1      1     1
#>  6     1      0     2
#>  7     0      0     3
#>  8     0      0     4
#>  9     1      1     1
#> 10     1      0     2
#> # ... with 90 more rows

提取指数

df_ones %>% 
    pull(is_one) %>%    # extract result as vector
    as.logical() %>%    # coerce to Boolean
    which()    # get indices of TRUE values
#>  [1]  1  5  9 14 22 29 35 40 44 48 52 56 61 66 71 75 79 84 88 93 97