R 合并按发件人分组的在同一时间范围内包含邮件的行
我有一个数据框,其中包含来自whatsapp发件人的消息。通常,人们倾向于在whatsapp中使用不止一条消息来表达某件事。我的目标是将大约5分钟内发送的消息合并为一行。这必须按发件人分组,因为数据帧包含多个发件人。我的数据框看起来如下所示:R 合并按发件人分组的在同一时间范围内包含邮件的行,r,time,group-by,merge,R,Time,Group By,Merge,我有一个数据框,其中包含来自whatsapp发件人的消息。通常,人们倾向于在whatsapp中使用不止一条消息来表达某件事。我的目标是将大约5分钟内发送的消息合并为一行。这必须按发件人分组,因为数据帧包含多个发件人。我的数据框看起来如下所示: Message Time Sender hello 2018-12-14 16:27:00 300 how are you? 2018-12-1
Message Time Sender
hello 2018-12-14 16:27:00 300
how are you? 2018-12-14 16:29:00 300
do you reply? 2018-12-15 12:00:00 300
Hi 2018-12-14 16:30:00 200
Hi 2018-12-15 16:36:00 200
现在我想让它看起来像这样:
Message Time Sender
hello how are you? 2018-12-14 16:27:00 300
do you reply? 2018-12-15 12:00:00 300
Hi 2018-12-14 16:30:00 200
Hi 2018-12-15 16:3600 200
第一个和第二个已经合并。到目前为止,我的尝试是将组映射与reduce一起使用,但似乎找不到解决方案
joinedMessageTable <- messageTable %>% group_by(Sender) %>% group_map(function(table, sender) {
Reduce(function(firstElement, result) {
value <- (firstElement + 5 *60 > result)
}, table$time)
})
joinedMessageTable%group\U by(发送方)%>%group\U映射(函数(表,发送方){
减少(函数(第一个元素,结果){
价值(结果)
},表$time)
})
有人知道如何解决这个问题吗?这行得通吗:
library(stringr)
library(dplyr)
df %>% group_by(Sender) %>%
mutate(flag = +(difftime(lead(Time), Time, units = 'min') < 5), flag = replace_na(flag, 0),
Message = case_when(flag == 1 ~ str_c(Message, lead(Message), sep = ' '), TRUE ~ Message),
Time = case_when(lag(flag) == 1 & flag == 0 ~ lag(Time), TRUE ~ Time)) %>% select(-flag) %>% filter(!duplicated(Time))
# A tibble: 4 x 3
# Groups: Sender [2]
Message Time Sender
<chr> <dttm> <dbl>
1 hello how are you? 2018-12-14 16:27:00 300
2 do you reply? 2018-12-15 12:00:00 300
3 Hi 2018-12-14 16:30:00 200
4 Hi 2018-12-15 16:36:00 200
库(stringr)
图书馆(dplyr)
df%%>%分组人(发件人)%%>%
变异(flag=+(difftime(超前(时间),时间,单位='min')<5),flag=replace_na(flag,0),
消息=case_当(标志==1~str_c(消息,引导(消息),sep=''),真消息),
时间=情况(滞后(标志)=1&标志==0~滞后(时间),真~时间))%>%select(-flag)%>%filter(!duplicated(时间))
#一个tibble:4x3
#分组:发件人[2]
消息时间发送器
你好,你好吗?2018-12-14 16:27:00 300
你回答了吗?2018-12-15 12:00:00 300
3嗨2018-12-14 16:30:00 200
4嗨2018-12-15 16:36:00 200
这是否有效:
library(stringr)
library(dplyr)
df %>% group_by(Sender) %>%
mutate(flag = +(difftime(lead(Time), Time, units = 'min') < 5), flag = replace_na(flag, 0),
Message = case_when(flag == 1 ~ str_c(Message, lead(Message), sep = ' '), TRUE ~ Message),
Time = case_when(lag(flag) == 1 & flag == 0 ~ lag(Time), TRUE ~ Time)) %>% select(-flag) %>% filter(!duplicated(Time))
# A tibble: 4 x 3
# Groups: Sender [2]
Message Time Sender
<chr> <dttm> <dbl>
1 hello how are you? 2018-12-14 16:27:00 300
2 do you reply? 2018-12-15 12:00:00 300
3 Hi 2018-12-14 16:30:00 200
4 Hi 2018-12-15 16:36:00 200
库(stringr)
图书馆(dplyr)
df%%>%分组人(发件人)%%>%
变异(flag=+(difftime(超前(时间),时间,单位='min')<5),flag=replace_na(flag,0),
消息=case_当(标志==1~str_c(消息,引导(消息),sep=''),真消息),
时间=情况(滞后(标志)=1&标志==0~滞后(时间),真~时间))%>%select(-flag)%>%filter(!duplicated(时间))
#一个tibble:4x3
#分组:发件人[2]
消息时间发送器
你好,你好吗?2018-12-14 16:27:00 300
你回答了吗?2018-12-15 12:00:00 300
3嗨2018-12-14 16:30:00 200
4嗨2018-12-15 16:36:00 200
您可以使用上限日期
创建每5分钟一组-
library(dplyr)
library(lubridate)
messageTable %>%
group_by(Sender, Time = ceiling_date(mdy_hm(Time), unit = '5 mins')) %>%
summarise(Message = paste0(Message, collapse = ' ')) %>%
ungroup
5分钟的持续时间,如果你想考虑连续值之间的差异,你可以做-/P>
df %>%
mutate(Time = mdy_hm(Time)) %>%
group_by(Sender) %>%
mutate(group = cumsum(difftime(Time,
lag(Time, default = first(Time)), units = 'mins') > 5)) %>%
group_by(group, .add = TRUE) %>%
summarise(Message = paste0(Message, collapse = ' ')) %>%
ungroup
您可以使用
ceiling\u date
创建每5分钟一组-
library(dplyr)
library(lubridate)
messageTable %>%
group_by(Sender, Time = ceiling_date(mdy_hm(Time), unit = '5 mins')) %>%
summarise(Message = paste0(Message, collapse = ' ')) %>%
ungroup
5分钟的持续时间,如果你想考虑连续值之间的差异,你可以做-/P>
df %>%
mutate(Time = mdy_hm(Time)) %>%
group_by(Sender) %>%
mutate(group = cumsum(difftime(Time,
lag(Time, default = first(Time)), units = 'mins') > 5)) %>%
group_by(group, .add = TRUE) %>%
summarise(Message = paste0(Message, collapse = ' ')) %>%
ungroup
如果输出对您有帮助,您也可以使用
runner
(用于计算滑动窗口/滚动计算的库)
my_df%
变异(msg=runner)(消息,
idx=时间,
k=‘5分钟’,
f=toString)
#>#A tibble:5 x 4
#>#组:发送方[2]
#>消息时间发送者消息
#>
#>你好2018-12-14 16:27:00 300你好
#>你好吗?2018-12-14 16:29:00你好,你好吗?
#>你回答了吗?2018-12-15 12:00:00 300您回复了吗?
#>4嗨2018-12-14 16:30:00 200嗨
#>5嗨2018-12-15 16:36:00 200嗨
由(v2.0.0)于2021年5月30日创建,如果输出对您有所帮助,您也可以使用runner(用于计算滑动窗口/滚动计算的库)
my_df%
变异(msg=runner)(消息,
idx=时间,
k=‘5分钟’,
f=toString)
#>#A tibble:5 x 4
#>#组:发送方[2]
#>消息时间发送者消息
#>
#>你好2018-12-14 16:27:00 300你好
#>你好吗?2018-12-14 16:29:00你好,你好吗?
#>你回答了吗?2018-12-15 12:00:00 300您回复了吗?
#>4嗨2018-12-14 16:30:00 200嗨
#>5嗨2018-12-15 16:36:00 200嗨
由(v2.0.0)于2021年5月30日创建,我们可以使用
library(dplyr)
library(lubridate)
messageTable %>%
group_by(Sender, Time = ceiling_date(mdy_hm(Time), unit = '5 mins')) %>%
summarise(Message = toString(Message), .groups = 'drop')
我们可以使用
library(dplyr)
library(lubridate)
messageTable %>%
group_by(Sender, Time = ceiling_date(mdy_hm(Time), unit = '5 mins')) %>%
summarise(Message = toString(Message), .groups = 'drop')
结束检查后,@Ronak提供的解决方案没有完全起作用。我使用了一些代码来实现自己的功能。Ronak的代码存在的问题是,它使用false和true进行分组,因此只能生成两组时间。事实上,我需要有多个组和多个发送者,基于时间和累积窗口 我提出的解决方案并不能真正证实R的理念,所以请随意改进它
my_df <- read.table(text = "Message Time Sender
'hello' '2018-12-14 16:27:00' 300
'how are you?' '2018-12-14 16:34:00' 300
'are you good?' '2018-12-14 16:29:00' 300
'do you reply?' '2018-12-15 12:00:00' 300
'Have you received?' '2018-12-15 16:34:00' 300
'are you good?' '2018-12-15 16:29:00' 300
'Hi' '2018-12-14 16:30:00' 200
'Hi' '2018-12-15 16:36:00' 200
'Who is this?' '2018-12-15 16:35:00' 100
'Hi' '2018-12-15 16:35:00' 100", header = T)
my_df$Time <- as.POSIXct(my_df$Time)
merged_df <- my_df %>%
group_by(Sender, Time) %>%
mutate(Message = paste0(Message, collapse = " ")) %>%
distinct(Message, Sender, Time, .keep_all = TRUE) %>%
group_by(Sender) %>%
arrange(Time) %>%
group_modify(function(table, sender) {
counter <<- 1
begin <<- first(table$Time)
for (i in seq_len(nrow(table))) {
if (isTRUE(abs(difftime(begin, table[i,]$Time, units = "mins")) > 5)) {
counter <<- counter + 1
}
begin <<- table[i,]$Time
table[i, "counter"] <- counter
}
table
}) %>%
group_by(Sender, counter, add = TRUE) %>%
mutate(
Message = paste0(Message, collapse = ' ')
) %>%
distinct(Sender, counter, .keep_all = TRUE) %>%
select(-counter)
my_df%
不同(消息、发件人、时间、.keep_all=TRUE)%>%
分组人(发件人)%>%
安排时间%>%
组\修改(功能(表、发送方){
计数器在结束检查后,@Ronak给出的解决方案没有完全起作用。我使用了一些代码来实现自己的实现。Ronak的代码存在的问题是,它使用false和true分组,因此只能生成两组时间。事实上,我需要根据使用c的时间,使用多个发送者创建多个组累积窗口
我提出的解决方案并不能真正证实R的理念,所以请随意改进它
my_df <- read.table(text = "Message Time Sender
'hello' '2018-12-14 16:27:00' 300
'how are you?' '2018-12-14 16:34:00' 300
'are you good?' '2018-12-14 16:29:00' 300
'do you reply?' '2018-12-15 12:00:00' 300
'Have you received?' '2018-12-15 16:34:00' 300
'are you good?' '2018-12-15 16:29:00' 300
'Hi' '2018-12-14 16:30:00' 200
'Hi' '2018-12-15 16:36:00' 200
'Who is this?' '2018-12-15 16:35:00' 100
'Hi' '2018-12-15 16:35:00' 100", header = T)
my_df$Time <- as.POSIXct(my_df$Time)
merged_df <- my_df %>%
group_by(Sender, Time) %>%
mutate(Message = paste0(Message, collapse = " ")) %>%
distinct(Message, Sender, Time, .keep_all = TRUE) %>%
group_by(Sender) %>%
arrange(Time) %>%
group_modify(function(table, sender) {
counter <<- 1
begin <<- first(table$Time)
for (i in seq_len(nrow(table))) {
if (isTRUE(abs(difftime(begin, table[i,]$Time, units = "mins")) > 5)) {
counter <<- counter + 1
}
begin <<- table[i,]$Time
table[i, "counter"] <- counter
}
table
}) %>%
group_by(Sender, counter, add = TRUE) %>%
mutate(
Message = paste0(Message, collapse = ' ')
) %>%
distinct(Sender, counter, .keep_all = TRUE) %>%
select(-counter)
my_df%
不同(消息、发件人、时间、.keep_all=TRUE)%>%
分组人(发件人)%>%
安排时间%>%
组\修改(功能(表、发送方){
如果消息在5分钟内发送,但时间间隔>5分钟,计数器会如何处理?例如:发件人300的消息在1:05、1:09、1:11和1:15发送。是否仍要将这四个消息合并在一起?是的,我仍要合并这些消息。我希望它基于时间范围内最新的发送消息。因此1:05+5=1:10。包括1:09。1:09+