2016-11-30 82 views
-1

我有一个数据框如下,我想根据票号连续排列顺序中的行(如果连续重复,请丢弃它们)并确定它们如何交叉人。连接行并丢弃连续的重复或重复元素

ticket<- c("1", "1", "1", "2", "2", "2", "2") 
    name<- c("Olg", "Jan", "Jan", "Olg", "Jan", "Jan","Olg") 
    df<- data.frame(ticket, name) 

我想建立一个所谓的可变称为序列列,其提供路径和抑制连续重复如图所示(OLG-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

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

如果我正确理解你....

> 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 
+0

为什么选择更快的解决方案? –