Группировать и переименовывать на основе двух условий в R (dplyr)

У меня есть набор данных df:

В конечном итоге я хотел бы иметь возможность сгруппировать данные в «куски», где столбец папки содержит строку «Out», при этом обязательно учтите ДАТУ и пустые значения сообщений, с которыми они связаны. Есть ли способ создать блок для каждого экземпляра, в котором возникает сообщение «Out» и пустая строка сообщения, при вычислении его продолжительности.

  Folder               DATE                         Message
  Outdata              9/9/2019 5:46:00                   
  Outdata              9/9/2019 5:46:01
  Outdata              9/9/2019 5:46:02
  In                   9/9/2019 5:46:03            hello
  In                   9/9/2019 5:46:04            hello
  Outdata              9/10/2019 6:00:01
  Outdata              9/10/2019 6:00:02
  In                   9/11/2019 7:50:00           hello
  In                   9/11/2019 7:50:01           hello

Я хотел бы получить такой результат:

 New Variable        Duration        Message
 Outdata1              2 sec
 Outdata2              1 sec

Я включил dput:

dput(sample)
structure(list(Folder = structure(c(2L, 2L, 2L, 1L, 1L, 2L, 2L, 
1L, 1L), .Label = c("In", "Outdata"), class = "factor"), Date = structure(c(5L, 
6L, 7L, 8L, 9L, 1L, 2L, 3L, 4L), .Label = c("9/10/2019 6:00:01 AM", 
"9/10/2019 6:00:02 AM", "9/11/2019 7:50:00 AM", "9/11/2019 7:50:01 AM", 
"9/9/2019 5:46:00 AM", "9/9/2019 5:46:01 AM", "9/9/2019 5:46:02 AM", 
"9/9/2019 5:46:03 AM", "9/9/2019 5:46:04 AM"), class = "factor"), 
Message = structure(c(1L, 1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L), .Label = c("", 
"hello"), class = "factor")), class = "data.frame", row.names = c(NA, 
-9L))

Это то, что я пробовал, и это хорошо работает, мне просто нужно учитывать состояние пустых значений сообщений.

  library(dplyr)

  df  %>%
  mutate(DATE = as.POSIXct(DATE, format = "%m/%d/%Y %I:%M:%S %p"), 
     gr = cumsum(Folder != lag(Folder, default = TRUE))) %>%
 filter(Folder == "Out") %>%
 arrange(gr, DATE) %>%
 group_by(gr) %>%
 summarise(Duration = difftime(last(DATE), first(DATE), units = "secs")) %>%
 mutate(gr = paste0('Out', row_number()))

Приведенный выше код работает нормально, но я не уверен, как выполнить условие, в котором row == ""


person Lynn    schedule 30.01.2020    source источник
comment
Может, поменять filter(Folder == "Out") %>% на filter(Folder == "Out", Message == "") %>%?   -  person Jon Spring    schedule 30.01.2020
comment
Да я вижу! Полагаю, я бы выполнил это до кода выше? Спасибо!   -  person Lynn    schedule 30.01.2020


Ответы (1)


Наверное, просто paste Message вместе в одну строку.

library(dplyr)

sample  %>%
  mutate(DATE = as.POSIXct(Date, format = "%m/%d/%Y %I:%M:%S %p"), 
         gr = cumsum(Folder != lag(Folder, default = TRUE))) %>%
  filter(Folder == "Outdata") %>%
  arrange(gr, DATE) %>%
  group_by(gr) %>%
  summarise(Duration = difftime(last(DATE), first(DATE), units = "secs"), 
            Message = paste0(Message, collapse = "")) %>%
  mutate(gr = paste0('Out', row_number()))
person Ronak Shah    schedule 30.01.2020
comment
Я вижу @Ronak, позволь мне попробовать. Что именно делают «collapse» и «paste0»? - person Lynn; 30.01.2020
comment
@TanishaHudson Он захватывает все значения Message в группе как одну строку. - person Ronak Shah; 30.01.2020
comment
Хорошо, это сработало, вау, спасибо! (Мне нужно подождать несколько минут, прежде чем принять!) Спасибо! - person Lynn; 30.01.2020
comment
Здравствуйте @Ronak, есть еще одно условие. Я должен сгруппировать по столбцу Тема, и вот как я в конечном итоге нахожу время различия. Могу я просто добавить: group_by (Тема)? Думаю, я поставлю новый вопрос. Спасибо - person Lynn; 30.01.2020