объединить повторяющиеся записи и сохранить некоторые значения удаленных в R - PullRequest
0 голосов
/ 24 мая 2018

У меня есть огромный набор данных, который содержит четыре столбца user_id, action, start_time и end_time.Я хочу объединить последовательность действий "o" и start_time, если бы первые start_time и end_time были end_time последней объединенной записи.
скажем, df:

"user_id","action","start_time","end_time"
"11","o",23:25:27,23:25:49
"11","o",23:25:28,23:25:28
"11","o",23:25:48,23:26:50
"11","v",23:25:49,23:25:49
"11","v",23:25:49,23:25:50
"11","o",23:28:24,00:22:33
"11","o",00:10:48,00:23:44
"22","o",00:11:52,00:22:33
"22","o",00:22:32,00:27:44
"22","v",00:22:42,00:22:42
"22","o",00:22:42,00:22:42
"22","z",00:22:42,00:22:43

Я хочу объединить число 1, 2 и 3, потому что оба имеют действие "o", а слияние имеет start_time первого ряда и end_time второго.то же самое применимо к номеру строки 6 и 7, а также к числовому номеру 8 и 9.
Итак, желаемый результат:

    "user_id","action","start_time","end_time"
    "11","o",23:25:27,23:26:50
    "11","v",23:25:49,23:25:49
    "11","v",23:25:49,23:25:50
    "11","o",23:28:24,00:23:44
    "22","o",00:11:52,00:27:44
    "22","v",00:22:42,00:22:42
    "22","o",00:22:42,00:22:42
    "22","z",00:22:42,00:22:43   

Как я могу сделать это в R?ТНХ

Ответы [ 3 ]

0 голосов
/ 24 мая 2018

Мой процесс: сначала мы добавляем кодировку длины серии с rleid, что позволит нам рассматривать действия как отдельные группы.Затем мы добавляем два временных столбца st и et, которые обозначают время начала и окончания каждой группы.Затем мы filter получаем все действия, а не «o», или, если это «o», мы предпринимаем первое.Затем в группах, где действие «o», мы хотим заменить время начала и окончания временными столбцами.Наконец, мы select только те столбцы, которые вы хотите получить для финальной таблицы.

Это должно работать для нескольких последовательных прогонов действия "o".Я уверен, что есть лучший способ сделать последнее изменение, но я хотел выпустить это там.

library(data.table)
library(dplyr)
df  %>% 
  mutate(rlid = rleid(user_id,action)) %>% 
  group_by(rlid) %>% 
  mutate(st = start_time[row_number()==1], et = end_time[row_number = n()]) %>%
  filter(action!="o" | row_number()==1) %>% 
  mutate(start_time = case_when(action=="o"~st,
                                action!="o"~start_time),
         end_time = case_when(action=="o"~et,
                              action!="o"~end_time)) %>% 
  ungroup() %>% 
  select(user_id:end_time)

# # A tibble: 8 x 4
#   user_id action start_time end_time
#     <int> <fct>  <fct>      <fct>   
# 1      11 o      23:25:27   23:26:50
# 2      11 v      23:25:49   23:25:49
# 3      11 v      23:25:49   23:25:50
# 4      11 o      23:28:24   00:23:44
# 5      22 o      00:11:52   00:27:44
# 6      22 v      00:22:42   00:22:42
# 7      22 o      00:22:42   00:22:42
# 8      22 z      00:22:42   00:22:43
0 голосов
/ 25 мая 2018

Если вы не возражаете против решения data.table,

library(data.table)
setDT(df)
df[, {
    if (action[1L]=="o") {
        .(start_time=start_time[1L], end_time=end_time[.N])
    } else {
        .(start_time, end_time)
    }
}, by=.(rleid(action), user_id, action)][, -1L]

#   user_id action start_time end_time
#1:      11      o   23:25:27 23:26:50
#2:      11      v   23:25:49 23:25:49
#3:      11      v   23:25:49 23:25:50
#4:      11      o   23:28:24 00:23:44
#5:      22      o   00:11:52 00:27:44
#6:      22      v   00:22:42 00:22:42
#7:      22      o   00:22:42 00:22:42
#8:      22      z   00:22:42 00:22:43

data:

df <- read.csv(text='"user_id","action","start_time","end_time"
"11","o",23:25:27,23:25:49
"11","o",23:25:28,23:25:28
"11","o",23:25:48,23:26:50
"11","v",23:25:49,23:25:49
"11","v",23:25:49,23:25:50
"11","o",23:28:24,00:22:33
"11","o",00:10:48,00:23:44
"22","o",00:11:52,00:22:33
"22","o",00:22:32,00:27:44
"22","v",00:22:42,00:22:42
"22","o",00:22:42,00:22:42
"22","z",00:22:42,00:22:43')
0 голосов
/ 24 мая 2018

99% -ное решение проблемы с помощью @jasbner за предложение data.table::rleid:

Используя data.table::rleid, мы можем дать каждой последовательной группе уникальный идентификатор.Тогда достаточно просто сгруппировать по rlid и затем использовать summarize, чтобы найти самые ранние start_time и самые последние end_time.По умолчанию при суммировании отбрасываются все остальные переменные, поэтому вы должны явно сохранить их, как показано ниже.Наконец, мы отбрасываем переменную rlid, чтобы она соответствовала вашему примеру, но это может быть полезно сохранить в будущем.

library(dplyr)
library(data.table)

df  %>% 
    mutate(rlid = data.table::rleid(user_id,action)) %>% 
    group_by(rlid) %>%
    summarize(user_id = user_id[1],
              action = action[1],
              start_time = min(start_time),
              end_time = max(end_time)) %>%
    select(-rlid)

  user_id action start_time end_time
    <int> <chr>  <chr>      <chr>   
1      11 o      23:25:27   23:26:50
2      11 v      23:25:49   23:25:50
3      11 o      00:10:48   00:23:44
4      22 o      00:11:52   00:27:44
5      22 v      00:22:42   00:22:42
6      22 o      00:22:42   00:22:42
7      22 z      00:22:42   00:22:43

Этот метод свернет любое количество повторяющихся строк и (я думаю) оченьпроще для понимания, чем чистый data.table метод.

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