Цель
У меня есть набор данных, df, я хотел бы взять длительность, основанную на определенных условиях, и отобразить вывод Recipient
, starttime
, endtime
, Duration
и Length
.
Проблема
Мне нужно сначала сгруппировать сообщение вместе, если выполняются следующие условия: если Folder == 'out'
ИЛИ drafts
, Message == ""
, Edit == "T"
, и если содержимое столбцов «Получатель» и «Длина» последовательно совпадают.
В идеале это даст мне группу А. вместе с ее продолжительностью. Например, этот первый «блок» данных будет помечен как «Группа A», будет иметь время начала 1/2/2020 1:00:01 AM
и время окончания 1/2/2020 1:00:30 AM
.
. Кроме того, я хотел бы «сопоставить» 'группа A с другим' блоком 'данных, если последняя строка столбца Subject, Re и Length совпадает с другими группами Subject, Re и Length первой строки. Таким образом, вторая группа А будет иметь время начала 1/2/2020 1:02:00 AM
и время окончания 1/2/2020 1:02:05 AM
.
Subject Re Length Folder Message Date Edit
a@mail.com,b@mail.com 80 out 1/2/2020 1:00:01 AM T
a@mail.com,b@mail.com 80 out 1/2/2020 1:00:05 AM T
hey a@mail.com,b@mail.com 80 out 1/2/2020 1:00:10 AM T
hey a@mail.com,b@mail.com 80 out 1/2/2020 1:00:15 AM T
hey a@mail.com,b@mail.com 80 out 1/2/2020 1:00:30 AM T
some
some
some
hey a@mail.com,b@mail.com 80 draft 1/2/2020 1:02:00 AM T
hey a@mail.com,b@mail.com 80 draft 1/2/2020 1:02:05 AM T
no
no
no
no
hey a@mail.com,b@mail.com 80 out 1/2/2020 1:03:10 AM T
hey a@mail.com,b@mail.com 80 out 1/2/2020 1:03:20 AM T
Желаемый выход
Start End Duration Group Subject Length
1/2/2020 1:00:01 AM 1/2/2020 1:00:30 AM 29 A hey 80
1/2/2020 1:02:00 AM 1/2/2020 1:02:05 AM 5 A hey 80
1/2/2020 1:03:10 AM 1/2/2020 1:03:20 AM 10 A hey 80
dput:
structure(list(Subject = structure(c(1L, 1L, 2L, 2L, 2L, 4L,
4L, 4L, 2L, 2L, 3L, 3L, 3L, 3L, 2L, 2L, 1L, 1L), .Label = c("",
"hey", "no", "some"), class = "factor"), Recipient = structure(c(3L,
3L, 3L, 3L, 3L, 1L, 1L, 1L, 3L, 3L, 1L, 1L, 1L, 1L, 3L, 3L, 1L,
2L), .Label = c("", " ", "a@mail.com,b@mail.com"), class = "factor"),
Length = c(80L, 80L, 80L, 80L, 80L, NA, NA, NA, 80L, 80L,
NA, NA, NA, NA, 80L, 80L, NA, NA), Folder = structure(c(3L,
3L, 3L, 3L, 3L, 1L, 1L, 1L, 2L, 2L, 1L, 1L, 1L, 1L, 2L, 2L,
1L, 1L), .Label = c("", "draft", "out"), class = "factor"),
Message = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA), Date = structure(c(2L, 2L, 2L, 2L,
2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 1L, 1L), .Label = c("",
"1/2/2020 1:00", "1/2/2020 1:02", "1/2/2020 1:03"), class = "factor"),
Edit = c(TRUE, TRUE, TRUE, TRUE, TRUE, NA, NA, NA, TRUE,
TRUE, NA, NA, NA, NA, TRUE, TRUE, NA, NA)), class = "data.frame", row.names = c(NA,
-18L))
Я использую это, но я буду sh, чтобы сохранить строки, где тема пуста, я не хочу, чтобы это отфильтровывалось. Как видно из первых нескольких строк в этом примере, хотя поля «Тема» не заполнены, они все равно должны быть включены в первый «блок». Когда я удаляю эту часть:
filter(Subject != '') %>%, I get some errors, should I remove another part in the code too? (Keep in mind, I still want to display the Subject output). Any advice is appreciated.
df1<-df %>%
mutate_if(is.factor, as.character) %>%
mutate_at(c("Subject", "Recipient"), ~if_else(is.na(.), "", stringr::str_trim(.))) %>%
filter(Subject != '') %>%
mutate(Date = as.POSIXct(Date, format = '%m/%d/%Y %H:%M:%OS')) %>%
mutate(cond = Edit & Folder %in% c('out', 'draft') & Message == '') %>%
mutate(segment = cumsum(!cond)) %>%
filter(cond) %>%
group_by(Subject, Recipient, Length, segment) %>%
summarize(Start = min(Date),
End = max(Date),
Duration = End - Start) %>%
mutate(new_group = (Subject != lag(Subject, 1, "")) *
(Recipient != lag(Recipient, 1, "")) *
(Length != lag(Length, 1, ""))) %>%
ungroup() %>%
mutate(group = LETTERS[cumsum(new_group)])