Создать последовательность идентификаторов для флага с определенным условием - PullRequest
3 голосов
/ 15 апреля 2019

Мне нужно создать последовательность идентификаторов для конкретного условия: flag == 1, пример моей проблемы:

library(dplyr)
set.seed(123)
a <- data.frame(id = 1:10,
                flag = rbinom(10,1,0.2))
print(a)

   id flag
1   1    0
2   2    0
3   3    0
4   4    1
5   5    1
6   6    0
7   7    0
8   8    1
9   9    0
10 10    0

Я пытался создать переменную id только для flag == 1, но, к сожалению,также укажите флаг == 0, пример результата моей команды и желаемого результата:

a %>%
mutate(try_seq = cumsum(c(TRUE, diff(flag) != 0)))

>  id flag try_seq desire_seq
1   1    0       1      NA
2   2    0       1      NA    
3   3    0       1      NA
4   4    1       2      1
5   5    1       2      1
6   6    0       3      NA
7   7    0       3      NA
8   8    1       4      2
9   9    0       5      NA
10 10    0       5      NA
10 10    0       5      NA

Ответы [ 3 ]

1 голос
/ 15 апреля 2019

Это вернет искомый результат:

cumsum(c(a$flag[1], diff(a$flag)) > 0) * NA^!a$flag
 [1] NA NA NA  1  1 NA NA  2 NA NA

В уловке NA^a$flag используется идея, что любое значение, возведенное в 0-ую степень, равно 1. В противном случае мы используем diff для проверкидля положительного изменения переменной.

0 голосов
/ 15 апреля 2019

Мы также можем использовать rle без каких-либо ifelse

library(dplyr)
na_if(inverse.rle(within.list(rle(a$flag), {
    i1 <- as.logical(values)
    values[i1] <- seq_along(values[i1])} )), 0)
#[1] NA NA NA  1  1 NA NA  2 NA NA

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

library(data.table)
setDT(a)[, grp := rleid(flag)][flag != 0, desire_seq := .GRP , grp][, grp := NULL][]
#    id flag desire_seq
# 1:  1    0         NA
# 2:  2    0         NA
# 3:  3    0         NA
# 4:  4    1          1
# 5:  5    1          1
# 6:  6    0         NA
# 7:  7    0         NA
# 8:  8    1          2
# 9:  9    0         NA
#10: 10    0         NA
0 голосов
/ 15 апреля 2019

Мы можем использовать rle для создания последовательности для каждого 1 и изменить ее на NA в противном случае

library(dplyr)

a %>%
  mutate(ans_seq = ifelse(flag == 1, with(rle(flag == 1), 
                         rep(cumsum(!values), lengths)), NA))


#   id flag ans_seq
#1   1    0      NA
#2   2    0      NA
#3   3    0      NA
#4   4    1       1
#5   5    1       1
#6   6    0      NA
#7   7    0      NA
#8   8    1       2
#9   9    0      NA
#10 10    0      NA

, который также может быть записан с использованием только базы R как

with(a, ifelse(flag == 1, with(rle(flag == 1), rep(cumsum(!values), lengths)), NA))
#[1] NA NA NA  1  1 NA NA  2 NA NA
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...