Генерация счетчиков в группе и подгруппе - PullRequest
1 голос
/ 06 февраля 2020

Я хочу создать столбец, который будет подсчитывать, сколько раз подряд происходит инцидент. Представьте, что вы подбрасываете монету 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
...

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

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

Спасибо!

Ответы [ 4 ]

1 голос
/ 07 февраля 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")
1 голос
/ 06 февраля 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
1 голос
/ 06 февраля 2020

Вот решение с базой 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)][]
0 голосов
/ 06 февраля 2020
library(dplyr)

df = read.table(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
", header=T)

df %>%
  group_by(Round, Outcome) %>%
  mutate(NewCount = row_number()) %>%
  ungroup()

# # A tibble: 8 x 5
#    Toss Round Outcome Count NewCount
#   <int> <int> <fct>   <int>    <int>
# 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
...