Поиск значений в последовательных строках - PullRequest
0 голосов
/ 14 января 2019

Пример моего кадра данных приведен ниже.

ID     X      
1      1     
2      2      
3      1      
4      0      
5      0      
6      1      
7      4
8      5 
9      6
10     7
11     0 
12     0

Я хочу применить к нему логику, которая проверяет, имеют ли 3 или более последовательных строки значение> 0. Если они это сделают, я хочу отметить их в другом столбце. Следовательно, результат будет выглядеть следующим образом.

ID     X      Y
1      1      1
2      2      1
3      1      1
4      0      0
5      0      0
6      1      1
7      4      1
8      5      1
9      6      1
10     7      1
11     0      0
12     0      0

РАСШИРЕНИЕ - Как бы получить следующий вывод, предоставив разные значения Y для каждой группы?

ID     X      Y
1      1      1
2      2      1
3      1      1
4      0      0
5      0      0
6      1      2
7      4      2
8      5      2
9      6      2
10     7      2
11     0      0
12     0      0

Ответы [ 2 ]

0 голосов
/ 14 января 2019

Мы можем использовать rleid из data.table для создания групп и использовать его в ave и получать length каждой группы и назначать 1 группам, длина которых больше, чем равна 3.

library(data.table)
df$Y <- as.integer(ave(df$X, rleid(df$X > 0), FUN = length) >= 3)

df
#   ID X Y
#1   1 1 1
#2   2 2 1
#3   3 1 1
#4   4 0 0
#5   5 0 0
#6   6 1 1
#7   7 4 1
#8   8 5 1
#9   9 6 1
#10 10 7 1
#11 11 0 0
#12 12 0 0

EDIT

В обновленном сообщении мы можем включить вышеуказанную часть data.table с dplyr, выполнив

library(dplyr)
library(data.table)

df %>%
  group_by(group = rleid(X > 0)) %>%
  mutate(Y = ifelse(n() >= 3 & row_number() == 1, 1, 0)) %>%
  ungroup() %>%
  mutate(Y = cumsum(Y) * Y) %>%
  group_by(group) %>%
  mutate(Y = first(Y)) %>%
  ungroup() %>%
  select(-group)


#     ID     X     Y
#   <int> <int> <dbl>
# 1     1     1     1
# 2     2     2     1
# 3     3     1     1
# 4     4     0     0
# 5     5     0     0
# 6     6     1     2
# 7     7     4     2
# 8     8     5     2
# 9     9     6     2
#10    10     7     2
#11    11     0     0
#12    12     0     0
0 голосов
/ 14 января 2019

Один вариант с base R. Используя rle, чтобы найти соседние значения в 'X', которые больше 0, затем выполните связывание rep на основе lengths

df1$Y <- with(rle(df1$X > 0), as.integer(rep(values & lengths > 2, lengths)))
df1$Y
#[1] 1 1 1 0 0 1 1 1 1 1 0 0

За обновленным случаем в посте ОП

df1$Y <- inverse.rle(within.list(rle(df1$X > 0), {
             i1 <- values & (lengths > 2)
      values[i1] <- seq_along(values[i1])}))
df1$Y
#[1] 1 1 1 0 0 2 2 2 2 2 0 0

Или используя rleid из data.table

library(data.table)
setDT(df1)[, Y := as.integer((.N > 2) * (X > 0)),rleid(X > 0)]

данные

df1 <- structure(list(ID = 1:12, X = c(1L, 2L, 1L, 0L, 0L, 1L, 4L, 5L, 
 6L, 7L, 0L, 0L)), class = "data.frame", row.names = c(NA, -12L
 ))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...