Генерация подсчетов внутри группы и подгруппы

Я хочу создать столбец, который подсчитывает, сколько раз подряд происходит инцидент. Представьте, что вы подбрасываете монету 100 раз, и вы подсчитываете количество орлов («H») и сказок («T»), которые встречаются в ряду:

результат: "H","H","H","H","T","T","T","H","T","T",...

Количество: 1,2,3,4,1,2,3,1,1,2...

Я могу добиться этого с помощью следующего синтаксиса: df$count <- sequence(rle(df$outcome)$lengths) - 0

Однако представьте, что я беру раунды из 100 подбрасываний монет. Раунды имеют неравную длину, и мне нужно разделить их в столбце подсчета:

Toss   Round  Outcome  Count
1      1      H        1
2      1      H        2
3      1      H        3
4      1      H        4
5      1      T        1
6      2      T        1
7      2      T        2
8      2      H        1
...

Как я могу реализовать такое различие (т. Е. Группировать по раундам при подсчете в пределах результата) между раундами в моем коде?

Изменить: просто хотел объявить, что это очень упрощенная версия того, что мне нужно сделать в наборе данных из 46000 строк, поэтому решение не может быть основано на таблице, которую я предоставляю, но предпочтительнее в коде rle или аналогичном.

Спасибо!


person Astcar    schedule 06.02.2020    source источник


Ответы (4)


Вот решение с базой R:

D <- read.table(header=TRUE, text=
"Toss   Round  Outcome  Count
1      1      H        1
2      1      H        2
3      1      H        3
4      1      H        4
5      1      T        1
6      2      T        1
7      2      T        2
8      2      H        1")

D$C <- ave(D$Toss, D$Round, D$Outcome, FUN=seq_along)
D
#   Toss Round Outcome Count C
# 1    1     1       H     1 1
# 2    2     1       H     2 2
# 3    3     1       H     3 3
# 4    4     1       H     4 4
# 5    5     1       T     1 1
# 6    6     2       T     1 1
# 7    7     2       T     2 2
# 8    8     2       H     1 1

С data.table:

library("data.table")

D <- fread(
"Toss   Round  Outcome  Count
1      1      H        1
2      1      H        2
3      1      H        3
4      1      H        4
5      1      T        1
6      2      T        1
7      2      T        2
8      2      H        1")

D[, C:=1:.N, .(Round, Outcome)][]
person jogo    schedule 06.02.2020
comment
Спасибо, но по какой-то причине это не работает, как предполагалось, в моем реальном наборе данных. Он не прекращает счет, и поэтому вместо перезапуска счетчика с 1 после последовательности противоположных результатов он продолжает с того места, где он остановился. так что я получаю 1,2,3,4,1,2,3,5, ... Я действительно не понимаю, почему, поскольку это кажется таким простым. - person Astcar; 06.02.2020
comment
@Astcar Приведите примерные данные, эквивалентные вашим реальным данным, чтобы я мог изменить свой код. Прочтите https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example ... затем отредактируйте свой вопрос. - person jogo; 06.02.2020

Вот решение data.table:

library(data.table)

DF <- data.frame(
  stringsAsFactors = FALSE,
              Toss = c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L),
             Round = c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L),
           Outcome = c("H", "H", "H", "H", "T", "T", "T", "H")
)

setDT(DF)

DF[, .(Toss, Count = seq_len(.N)), by = .(Round, Outcome)]

   Round Outcome Toss Count
1:     1       H    1     1
2:     1       H    2     2
3:     1       H    3     3
4:     1       H    4     4
5:     1       T    5     1
6:     2       T    6     1
7:     2       T    7     2
8:     2       H    8     1
person ismirsehregal    schedule 06.02.2020

Еще один data.table вариант, который должен быть быстрее:

DT[, Count := rowid(rleid(Round, Outcome))]

вывод:

   Toss Round Outcome Count
1:    1     1       H     1
2:    2     1       H     2
3:    3     1       H     3
4:    4     1       H     4
5:    5     1       T     1
6:    6     2       T     1
7:    7     2       T     2
8:    8     2       H     1

данные:

library(data.table)
DT <- fread("Toss   Round  Outcome  Count
1      1      H        1
2      1      H        2
3      1      H        3
4      1      H        4
5      1      T        1
6      2      T        1
7      2      T        2
8      2      H        1")
person chinsoon12    schedule 07.02.2020
comment
О, может ты тоже поможешь мне с дополнительным вопросом? Мне нужен столбец, который дает каждой счетной группе идентичность, просто основанную на n + 1, так что каждый раз, когда Count == 1 запускается новая группа счетчиков (т.е. в примере строка 1-4 будет счетной группой 1 , строка 5 = счетная группа 2, строка 6 + 7 = счетная группа 3 и т. д. Я ценю это! - person Astcar; 11.02.2020
comment
возможно DT[, Count := rowid(rleid(Round, Outcome))][, CountGroup := cumsum(Count==1L)] - person chinsoon12; 11.02.2020
comment
Да, в самом деле! Большое спасибо! - person Astcar; 11.02.2020

person    schedule
comment
Когда я пытаюсь использовать dplyr, я получаю эту ошибку: Error: .onLoad failed in loadNamespace() for 'vctrs', details: call: loadNamespace(name) error: there is no package called ‘backports’ - person Astcar; 06.02.2020
comment
Не знаю почему, но убедитесь, что все ваши пакеты обновлены. Похоже на проблему / конфликт зависимости. - person AntoniosK; 06.02.2020