Подсчет количества вхождений комбинации значений в r - PullRequest
0 голосов
/ 01 ноября 2018

Я работаю с данными, касающимися разных случаев, проходящих процесс, состоящий из разных стадий, в течение определенного периода времени. Каждый случай имеет уникальный идентификационный номер. Процесс может начинаться в нескольких этапах и заканчиваться этапом «Завершено» (за исключением еще не прошедших этапов). Дело может пройти процесс несколько раз. Данные выглядят примерно так:

library(dplyr)
df1 <- structure(list(id = c("1", "1", "2", "2", "2", "2", "3", "3", 
"3", "3", "3", "3", "3", "3", "3", "3"), time = structure(c(17453, 
17458, 17453, 17462, 17727, 17735, 17453, 17484, 17568, 17665, 
17665, 17709, 17727, 17727, 17757, 17819), class = "Date"), old_fase = 
c(NA, "Fase 1", NA, "Fase 1", "Finished", "Fase 1", NA, "Fase 1", "Fase 2A", 
"Finished", "Fase 2A", "Fase 2B", "Finished", "Fase 2B", "Fase 1", 
"Fase 2A"), new_fase = c("Fase 1", "Finished", "Fase 1", "Finished", 
"Fase 1", "Finished", "Fase 1", "Fase 2A", "Finished", "Fase 2A", 
"Fase 2B", "Finished", "Fase 2B", "Fase 1", "Fase 2A", "Fase 2B"
)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -16L))

Для моего анализа я хочу создать новый идентификатор на основе встречаемости каждого процесса для каждого идентификатора. Использование group_by и mutate для «id» и «new_fase» создает следующее неправильное решение. Это происходит из-за первого появления «Fase 2B» в строке 11.

df1 %>% 
group_by(id,new_fase) %>% 
mutate(occurrence=row_number())

Правильное решение должно выглядеть так:

df1 %>% 
mutate(occurrence = c(rep(1, 4), 2, 2, rep(1, 3), rep(2, 3), rep(3, 4)))

Я попробовал несколько подходов и прочитал несколько сообщений Stackoverflow, но не могу понять это правильно. Мы ценим любую помощь, желательно с помощью решения tidyverse.

Ответы [ 3 ]

0 голосов
/ 01 ноября 2018

Мы можем использовать ave от base R

df2$occurrence <- with(df2, ave(seq_along(id), id, fase, FUN = seq_along))

Или с data.table

library(data.table)
setDT(df2)[, occurrence := seq_len(.N), .(id, fase)]
0 голосов
/ 07 ноября 2018

Я нашел это временное решение (благодаря решению iod в первом примере с использованием group_by и mutate).

df1 %>% filter(is.na(old_fase) | old_fase == "Finished") %>% # indicates the beginning of a new proces
group_by(id) %>% 
mutate(occurrence = row_number()) %>% 
select(id, time, occurrence) %>% 
left_join(df1, ., by = c("id", "time")) %>% 
fill(occurrence)
0 голосов
/ 01 ноября 2018
df3<- df1 %>% 
  group_by(id,fase) %>% 
  mutate(occurrence=row_number())

df3
# A tibble: 18 x 4
# Groups:   id, fase [9]
      id fase  time       occurrence
   <dbl> <chr> <date>          <int>
 1     1 a     2018-01-01          1
 2     1 b     2018-01-02          1
 3     1 c     2018-01-03          1
 4     2 a     2018-01-01          1
 5     2 b     2018-01-02          1
 6     2 c     2018-01-03          1
 7     2 a     2018-01-04          2
 8     2 b     2018-01-05          2
 9     2 c     2018-01-06          2
10     2 a     2018-01-07          3
11     2 b     2018-01-08          3
12     2 c     2018-01-09          3
13     3 a     2018-01-01          1
14     3 b     2018-01-02          1
15     3 c     2018-01-03          1
16     3 a     2018-01-04          2
17     3 b     2018-01-05          2
18     3 c     2018-01-06          2

all(df2==df3)
[1] TRUE

Вы разбиваете (группируете) df на части, где каждая часть имеет одинаковый идентификатор и фазу, а затем просто нумеруете строки в каждой из этих частей. Обратите внимание, что предполагается, что df уже отсортирован в хронологическом порядке, как в ваших примерах данных. Если это не так, вам придется отсортировать заранее по time.

...