我有一个如下的数据帧,我想根据票号连接序列中的行(如果有连续的重复则删除它们)并确定它们如何被人们传递。
ticket<- c("1", "1", "1", "2", "2", "2", "2")
name<- c("Olg", "Jan", "Jan", "Olg", "Jan", "Jan","Olg")
df<- data.frame(ticket, name)
我想创建一个名为sequence的变量列,它提供路径并抑制连续重复,如图所示(Olg-Jan-Jan到Olg-Jan和Olg-Jan-Jan-Olg到Olg-Jan-Olg)。有什么建议?谢谢!
seq<- c("Olg-Jan", "Olg-Jan", ""Olg-Jan", "Olg-Jan-Olg","Olg-Jan-Olg","Olg-Jan-Olg" )
答案 0 :(得分:0)
name
是一个因素(如果不是,我们可以将其转换为因子),因此我们使用基础数字因子代码来检查连续重复并删除它们。我们使用dplyr
,以便我们可以使用链接运算符(ticket
)轻松地按%>%
和链函数分组。
library(dplyr)
df %>% group_by(ticket) %>%
filter(c(1, diff(as.numeric(name))) !=0) %>%
summarise(sequence = paste(name, collapse="-"))
ticket sequence 1 1 Olg-Jan 2 2 Olg-Jan-Olg
如果要保留原始数据框的所有行并只添加序列,则可以left_join
上面的输出到原始数据框:
df = df %>%
left_join(df %>% group_by(ticket) %>%
filter(c(1, diff(as.numeric(name))) !=0) %>%
summarise(sequence = paste(name, collapse="-")))
ticket name sequence 1 1 Olg Olg-Jan 2 1 Jan Olg-Jan 3 1 Jan Olg-Jan 4 2 Olg Olg-Jan-Olg 5 2 Jan Olg-Jan-Olg 6 2 Jan Olg-Jan-Olg 7 2 Olg Olg-Jan-Olg
答案 1 :(得分:-1)
如果我能正确理解你......
> df_to_list <- split(df, df$ticket)
> df_to_list
$`1`
ticket name
1 1 Olg
2 1 Jan
3 1 Jan
$`2`
ticket name
4 2 Olg
5 2 Jan
6 2 Jan
7 2 Olg
现在我们要循环并取消列出名称,然后删除连续出现相同名称的情况,然后绑定。
new_df <- lapply(df_to_list, function(i){
a <- as.character(unlist(i[['name']]))
endr <- length(a) - 1
b <- sapply(1:endr, function(x){
a[x] != a[x+1]
})
c <- a[b]
paste0(c, collapse = "-")
}) %>% melt %>% select(ticket = L1, seq = value)
> new_df
ticket seq
1 1 Olg-Jan
2 2 Olg-Jan-Olg
这是你之后的事吗?
注意:使用group_by方法与这种方式的速度差异产生了有趣的输出时序。我将该集复制到14000行并命名为新数据框addf
,并将两个解决方案包装到单独的函数using_group
和`no_group中。
> system.time(using_group(addf))
user system elapsed
0.012 0.000 0.011
> system.time(no_group(addf))
user system elapsed
0.004 0.000 0.004