use*_*195 1 r concatenation dplyr
我希望得到一些专家建议,以有效的方式删除一列中的数据帧行(columnA),其中存在重复值,同时创建一个新变量,连接另一列(columnB)的条目其中columnA有重复项.下面我提供一个玩具数据框:
my_df <- data.frame('DateTime' = c('2017/05/05 08:30:00', '2017/05/05 08:30:00',
'2017/05/05 08:30:00', '2017/12/08 08:30:00',
'2018/01/15 18:50:00', '2017/12/20 21:46:00',
'2017/11/12 18:50:00', '2017/11/03 08:30:00',
'2017/11/03 08:30:00', '2017/12/03 08:30:00'),
'Event' = c('A', 'B', 'C', 'A', 'A', 'B', 'C', 'A', 'B', 'A'),
'Var1' = rnorm(10),
stringsAsFactors = FALSE)
Run Code Online (Sandbox Code Playgroud)
在此数据框中,DateTime列是一个字符列,2017/05/08 08:30:00出现3次,而2017/11/03 08:30:00出现两次.我的目标是折叠有重复项的行,DateTime并有一个连接Event条目的新列.所以新栏目,AllEvents应该有A-B-C2017/05/05 08:30:00行的参赛作品.对于行2017/11/03 08:30:00中的DateTime列AllEvents应该具有值A-B.最后,对于所有其他行,AllEvents应匹配Event列.
我的尝试似乎非常笨重.
我首先提取DateTime的唯一值,其中有多个entr:
require(dplyr)
duped_datetime <- unique(my_df[duplicated(my_df$DateTime), 'DateTime'])
Run Code Online (Sandbox Code Playgroud)
然后,我将my_df子集化,以提取存在重复项的条目
subset_df <- my_df[my_df$DateTime %in% duped_datetime,]
Run Code Online (Sandbox Code Playgroud)
接下来,我创建一个连接向量的函数:
my_concat <- function(x){
concat_str <- subset_df %>% filter(DateTime == x) %>%
select(Event) %>%
unlist() %>%
paste(collapse="+")
return(concat_str)
}
Run Code Online (Sandbox Code Playgroud)
接下来,我遍历重复的日期并应用my_concat函数:
named_vc <- sapply(duped_datetime, FUN = my_concat)
Run Code Online (Sandbox Code Playgroud)
结果合并为一个新的数据帧
new_df <- data.frame('DateTime' = duped_datetime,
'AllEvents' = unname(named_vc),
stringsAsFactors = FALSE)
Run Code Online (Sandbox Code Playgroud)
合并结果并清理final_df以保留我需要的行和列.
final_df <- left_join(my_df, new_df, by = 'DateTime') %>%
mutate(AllEvents = ifelse(is.na(AllEvents), Event, AllEvents))
final_df <- final_df[!duplicated(final_df$DateTime),]
final_df['Event'] <- NULL
Run Code Online (Sandbox Code Playgroud)
我得到了我需要的结果但是你可以看到代码是可怕的.整个事情可以在Python中使用groupby,apply和lambda函数在4行中完成,但对于我来说如何在R中干净地完成相同的任务并不是很明显.
DateTime Var1 AllEvents
2017/05/05 08:30:00 -0.8350209 A+B+C
2017/12/08 08:30:00 1.1534819 A
2018/01/15 18:50:00 -0.3501990 A
2017/12/20 21:46:00 -0.6664841 B
2017/11/12 18:50:00 1.7142981 C
2017/11/03 08:30:00 -2.0133559 A+B
2017/12/03 08:30:00 -0.6150040 A
Run Code Online (Sandbox Code Playgroud)
感谢任何有耐心阅读本文的人.
这可以直接进行dplyr,group_by适用于以下DateTime值:
my_df %>%
group_by(DateTime) %>%
summarise(Var1 = first(Var1),
Event = paste0(Event, collapse = "+"))
Run Code Online (Sandbox Code Playgroud)
输出:
# A tibble: 7 x 3
DateTime Var1 Event
<chr> <dbl> <chr>
1 2017/05/05 08:30:00 0.159 A+B+C
2 2017/11/03 08:30:00 -0.610 A+B
3 2017/11/12 18:50:00 0.465 C
4 2017/12/03 08:30:00 -1.89 A
5 2017/12/08 08:30:00 0.793 A
6 2017/12/20 21:46:00 0.755 B
7 2018/01/15 18:50:00 0.511 A
Run Code Online (Sandbox Code Playgroud)