说我有这个载体:
a <- round(runif(100, 0, 1), digits = 0)
我想在向量中找到包含数字1的第一个元素。找到该元素后,跳过3个元素(即使它们包含1个),然后找到包含1的下一个元素并重复查找1并跳过找到1s后的3个元素。
我想要的输出是第一个包含1的元素的行号,后面是包含1的其余行号,在考虑跳过的元素之后。
答案 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)
您可以将Reduce
与accumulate = TRUE
或purrr::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