Как найти последовательные значения <2 с длиной> = 3 в R? - PullRequest
0 голосов
/ 30 апреля 2018

У меня есть некоторые данные, и я хочу найти последовательные значения <= 2, а длина последовательных значений должна> 3. Мои цели: (1) найти длину различных групп последовательных значений и (2) найти местоположение первого значения в каждой группе. Я пробовал следующий код:

set.seed(100)
pre = sample(x=1:5, size = 90, replace = T)
which(pre<=2)

и результат будет ниже:

[1]  1  2  4  8 10 13 14 17 18 19 26 30 33 37 40 41 49 50 51 52 53 54 56 57 58 60 66 69 72 80 85 88 89

Итак, к группам консервативных значений относятся: (1) 17, 18, 19; (2) 40, 41; (3) 49, 59, 51, 52, 53, 54; (4) 56, 57, 58; (5) 88, 89.

Однако, поскольку мне нужны только последовательные значения с длиной> = 3, группу (2) и (5) следует исключить из результатов. Интересно, как я могу сделать это в R? Спасибо за любую помощь.

Ответы [ 2 ]

0 голосов
/ 01 мая 2018

Один из вариантов - использовать dplyr после преобразования вектора pre в data.frame.

set.seed(100)
pre = sample(x=1:5, size = 90, replace = T)

library(dplyr)
df <- data.frame(pre)

df %>% mutate(condition = (pre <= 2), rn = row_number()) %>%
  group_by(grp = cumsum(lag(condition, default = -1) != condition)) %>%
  filter(pre <= 2 & n() >= 3) %>%
  group_by(grp) %>%
  summarise(pos = min(rn), count = n()) %>%
  ungroup() %>%
  select(-grp) %>% as.data.frame()
#    pos count
# 1  17     3
# 2  49     6
# 3  56     3
0 голосов
/ 01 мая 2018

Используйте rle, чтобы получить длины каждого повторяемого сечения, затем найдите позицию, добавив эти длины, и поднабор, чтобы получить желаемые прогоны. В первой строке мне нужно сначала unclass rle, иначе data.frame не знает, как с этим справиться.

out <- data.frame(unclass(rle(pre<=2)))
out$pos <- head(cumsum(c(1, out$lengths)), -1)
out[out$lengths>=3  & out$values,c("pos", "lengths")]
##  pos lengths
##   17       3
##   49       6
##   56       3

Если вы предпочитаете цепочку с dplyr, вот версия с этой идиомой.

rle(pre <= 2) %>% unclass() %>% data.frame() %>%
  mutate(pos = c(1, lengths) %>% cumsum %>% head(-1)) %>%
  filter(lengths >=3 & values) %>% select(pos, lengths)

(В предыдущей версии я использовал do.call в первой строке, которая просто помещает результаты из rle в data.frame; do.call просто вызывает функцию, указанную в первом аргументе со вторым аргументом в качестве его параметров. Это полезно, когда у вас есть список вещей (например, rle return), которые вы хотите использовать в качестве параметров для функции. Код, безусловно, может быть написан без этого шага, он просто облегчает сохранение части и выводить только те строки, которые вы хотите.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...