2015-02-10 102 views
5

計數行我有一個看起來如下面的數據幀:分組,比較和r中

 system Id initial final 
665  9 16001 6070 6071 
683  10 16001 6100 6101 
696  11 16001 6101 6113 
712  10 16971 6150 6151 
715  11 16971 6151 6163 
4966  7 4118 10238 10242 
5031  9 4118 10260 10278 
5088  10 4118 10279 10304 
5115  11 4118 10305 10317 


structure(list(system = c(9L, 10L, 11L, 10L, 11L, 7L, 9L, 10L, 
11L), Id = c(16001L, 16001L, 16001L, 16971L, 16971L, 4118L, 4118L, 
4118L, 4118L), initial = c(6070, 6100, 6101, 6150, 6151, 10238, 
10260, 10279, 10305), final = c(6071, 6101, 6113, 6151, 6163, 
10242, 10278, 10304, 10317)), .Names = c("system", "Id", "initial", 
"final"), row.names = c(665L, 683L, 696L, 712L, 715L, 4966L, 
5031L, 5088L, 5115L), class = "data.frame") 

我想獲得一個新的數據幀與下一結構

 Id system length initial final 
1 16001 9,10,11  3 6070 6113 
2 16971 10,11  2 6150 6163 
3 4118  7  1 10238 10242 
4 4118 9,10,11  3 10260 10317 


structure(list(Id = c(16001L, 16971L, 4118L, 4118L), system =  structure(c(3L, 
1L, 2L, 3L), .Label = c("10,11", "7", "9,10,11"), class =  "factor"), 
    length = c(3L, 2L, 1L, 3L), initial = c(6070L, 6150L, 10238L, 
    10260L), final = c(6113, 6163, 10242, 10317)), .Names = c("Id", 
"system", "length", "initial", "final"), class = "data.frame",  row.names = c(NA, 
-4L)) 

分組是由Id和「系統」字段中的差異(行之間)等於1。此外,我想獲得不同的「系統」以及分組中涉及的數量。最後還包括第一個「初始」和最後一個「最終」的列。

有可能在r? 謝謝。

回答

3

您可以使用data.table。通過將「system」(diff(system)),cumsum的相鄰元素的差異轉換爲「data.table」(setDT),創建一個分組變量「indx」,使用「Id」和「indx 「作爲分組變量來獲得統計信息。

library(data.table) 
setDT(df)[,list(system=toString(system), length=.N, initial=initial[1L], 
    final=final[.N]), by=list(Id,indx=cumsum(c(TRUE, diff(system)!=1)))][, 
    indx:=NULL][] 

#  Id system length initial final 
#1: 16001 9, 10, 11  3 6070 6113 
#2: 16971 10, 11  2 6150 6163 
#3: 4118   7  1 10238 10242 
#4: 4118 9, 10, 11  3 10260 10317 

或基於@ jazzurro的有關使用從dplyrfirst/last評論功能,

library(dplyr) 
df %>% 
    group_by(indx=cumsum(c(TRUE, diff(system)!=1)), Id) %>% 
    summarise(system=toString(system), length=n(), 
    initial=first(initial), final=last(final)) 
+1

可以使用'第()'和' last()'是另一種選擇嗎? 'first()'是來自dplyr。 – jazzurro 2015-02-10 04:50:22

+0

@jazzurro我認爲它的作品。您可以將其作爲dplyr解決方案發布。 – akrun 2015-02-10 05:21:10

+0

我仍然想知道在'data.table'中使用'dplyr'中的某些函數是不是一件好事。 'dplyr'解決方案將只是你的代碼的翻譯。如果你很高興寫一個,請繼續。我會留給你的。 :) – jazzurro 2015-02-10 05:27:14

1

一個解決方案,而data.table,但plyr

library(plyr) 

func = function(subdf) 
{ 
    bool = c(diff(subdf$system),1)==1 
    ldply(split(subdf, bool), function(u){ 
     data.frame(system = paste(u$system, collapse=','), 
        Id  = unique(u$Id), 
        length = nrow(u), 
        initial= head(u,1)$initial, 
        final = tail(u,1)$final) 
    }) 
} 


ldply(split(df, df$Id), func) 

# .id system length Id initial final 
#1 FALSE  7  1 4118 10238 10242 
#2 TRUE 9,10,11  3 4118 10260 10317 
#3 TRUE 9,10,11  3 16001 6070 6113 
#4 TRUE 10,11  2 16971 6150 6163