создать последовательность вдоль группы, которая перезапускается на основе значения другого столбца - PullRequest
0 голосов
/ 29 сентября 2018

У меня есть df как это:

id <- c(rep(380,6),rep(381,4),rep(382,4),rep(383,5))
T_F <- c(FALSE,FALSE,TRUE,FALSE,TRUE,FALSE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,TRUE,FALSE,FALSE,TRUE,FALSE,FALSE,FALSE)
df <- data.frame(id,T_F)

Мой желаемый выход увеличивается на 1 при изменении T_F, но также перезапускает нумерацию при изменении id:

df$result <- c(1,1,2,3,4,5,1,2,3,3,1,1,2,3,1,2,3,3,3)

Я могу получитьМой результат увеличивается на 1 при изменении T_F с использованием следующего кода:

df$result <- cumsum(c(1,diff(df$T_F) != 0))

Однако это не перезапускает нумерацию при изменении идентификатора.Я пробовал следующие варианты, но безуспешно:

ave(df$id,cumsum(c(1,diff(df$id) != 0))|cumsum(c(1,diff(df$T_F) != 0)),FUN=seq_along)

Ответы [ 2 ]

0 голосов
/ 29 сентября 2018

Другой подход заключается в использовании оператора сдвига для вектора T_F для определения последовательных изменений:

id <- c(rep(380,6),rep(381,4),rep(382,4),rep(383,5))
T_F <-c(FALSE,FALSE,TRUE,FALSE,TRUE,FALSE,FALSE,TRUE, 
FALSE,FALSE,FALSE,FALSE,TRUE,FALSE,FALSE,TRUE,FALSE,FALSE,FALSE)
df <- data.frame(id,T_F)
df$result <- c(1,1,2,3,4,5,1,2,3,3,1,1,2,3,1,2,3,3,3)

library(binhf)
df %>% group_by(id) %>% mut(result2=cumsum(T_F!=shift(T_F,1))+1)

#          id T_F   result result2
#       <dbl> <lgl>  <dbl>   <dbl>
#     1   380 FALSE      1       1
#     2   380 FALSE      1       1
#     3   380 TRUE       2       2
#     4   380 FALSE      3       3
#     5   380 TRUE       4       4
#     6   380 FALSE      5       5
#     7   381 FALSE      1       1
#     8   381 TRUE       2       2
#     9   381 FALSE      3       3
#    10   381 FALSE      3       3
#    11   382 FALSE      1       1
#    12   382 FALSE      1       1
#    13   382 TRUE       2       2
#    14   382 FALSE      3       3
#    15   383 FALSE      1       1
#    16   383 TRUE       2       2
#    17   383 FALSE      3       3
#    18   383 FALSE      3       3
#    19   383 FALSE      3       3
0 голосов
/ 29 сентября 2018

Вы можете сделать

transform(df,
          result_2 = ave(T_F, id, FUN = function(x) cumsum(c(1, diff(x) != 0))))
#    id   T_F result result_2
#1  380 FALSE      1        1
#2  380 FALSE      1        1
#3  380  TRUE      2        2
#4  380 FALSE      3        3
#5  380  TRUE      4        4
#6  380 FALSE      5        5
#7  381 FALSE      1        1
#8  381  TRUE      2        2
#9  381 FALSE      3        3
#10 381 FALSE      3        3
#11 382 FALSE      1        1
#12 382 FALSE      1        1
#13 382  TRUE      2        2
#14 382 FALSE      3        3
#15 383 FALSE      1        1
#16 383  TRUE      2        2
#17 383 FALSE      3        3
#18 383 FALSE      3        3
#19 383 FALSE      3        3

Мы применяем ваш код группами id, используя ave.

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