2016-11-30 81 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

爲什麼選擇更快的解決方案? –