Как мне найти последовательные значения - PullRequest
3 голосов
/ 05 февраля 2020

Предположим, у меня есть этот вектор:

x <- c(1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0)

Я хочу узнать, сколько раз у нас ¨1¨ 3 раза подряд. Для этого я использую этот код -

n.hot <- which(df, df$vector = 1,1,1)

Что я могу сделать, чтобы он действительно работал? Спасибо

Ответы [ 5 ]

3 голосов
/ 05 февраля 2020

В случае, если 1 1 1 1 означает для вас, что 1 1 1 действительно появляется дважды, вы можете сделать:

sum(stats::filter(x, c(1, 1, 1), circular = TRUE, sides = 2) == 3)

[1] 7
3 голосов
/ 05 февраля 2020

Один из вариантов может быть:

sum(with(rle(x), lengths[as.logical(values)]) == 3)

[1] 2
2 голосов
/ 05 февраля 2020

Вы можете рассчитать скользящую сумму, и если она равна 3, вы знаете, что это то, что вы хотите.

library(zoo)

x <- c(1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0)

threetogether <- rollsum(x, 3, fill = NA, align = "right")

threetogether == 3

Вывод:

 [1]    NA    NA FALSE FALSE  TRUE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE
1 голос
/ 05 февраля 2020

Вот еще одна (менее традиционная) идея,

sum(tapply(x, cumsum(x != 1), FUN = length) == 4)
#[1] 2
0 голосов
/ 05 февраля 2020

Если вам нужно ровно три последовательных единицы или если вы хотите хотя бы три последовательных единицы, вот функция, использующая решение base R, которое использует cumsum()diff(). Это просто смещает вектор cumsum для сравнения, если есть n последовательных. В настоящее время он предназначен для работы с логическими векторами или векторами 0/1. И, если у вас "at least" в качестве типа, он выберет первое совпадение, но его легко адаптировать для выбора последнего если хотите.

consecutive_n <- function(vector, n, type = c("equal", "at least")) {

  length_vec <- length(vector)
  cumsum_vec <- cumsum(vector)

  difference <- cumsum_vec - c(rep(0, n), cumsum(vector)[-c((length_vec-n+1):length_vec)]) == n

  type <- match.arg(type)

  if(type == "equal") {
    difference & c(0, diff(difference)) == 1
  } else {
    difference
  } 

}

consecutive_n(x, 3)
[1] FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE
sum(consecutive_n(x, 3))
[1] 4
which(consecutive_n(x, 3))
[1]  5 10 14 21

sum(consecutive_n(x, 3, type = "at least"))
[1] 7
which(consecutive_n(x, 3, type = "at least"))
[1]  5  6 10 14 15 16 21

Данные :

x <- c(1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...