2017-05-24 151 views
0

說我有一個這樣的數據集:[R總結總爲每類每個ID

df <- data.frame(id = c(1, 1, 1, 2, 2), 
     classname = c("Welding", "Welding", "Auto", "HVAC", "Plumbing"), 
     hours = c(3, 2, 4, 1, 2)) 

也就是說,

id classname hours 
1 1 Welding  3 
2 1 Welding  2 
3 1 Auto  4 
4 2 HVAC  1 
5 2 Plumbing 2 

我試圖找出如何總結數據一種方式,讓我爲每個id,他們採取的類的列表以及每個類的多少小時。我希望這些在列表中,這樣我就可以保持每行一行。所以,我想它會回來:

id  class.list  class.hours 
1 1 Welding, Auto  5,4 
2 2 HVAC, Plumbing  1,2  

我能弄清楚如何讓它返回class.list。

library(dplyr) 
classes <- df %>% 
group_by(id) %>% 
summarise(class.list = list(unique(as.character(classname)))) 

這給了我:

id  class.list  
1 1 Welding, Auto   
2 2 HVAC, Plumbing  

但我不知道我怎麼能得到它總結的小時數爲每個類(class.hours)的。

感謝您的幫助!

回答

1

在基數R中,這可以通過兩次調用aggregate來完成。內部調用將小時和外部調用相加「連接」小時和類名稱。在aggregate的外部調用中,cbind用於在輸出中包括小時和類名,並且還提供所需的變量名。

# convert class name to character variable 
df$classname <- as.character(df$classname) 
# aggregate 
aggregate(cbind("class.hours"=hours, "class.list"=classname)~id, 
      data=aggregate(hours~id+classname, data=df, FUN=sum), toString) 
    id class.hours  class.list 
1 1  4, 5 Auto, Welding 
2 2  1, 2 HVAC, Plumbing 

data.table中,用鏈式語句產生大致相同的輸出。

setDT(df)[, .(hours=sum(hours)), by=.(id, classname)][, lapply(.SD, toString), by=id] 
    id  classname hours 
1: 1 Welding, Auto 5, 4 
2: 2 HVAC, Plumbing 1, 2 

變量名然後可以使用data.tablesetnames功能設置。

+0

它似乎工作。謝謝! –

1

這是你如何能使用dplyr做到這一點:

classes <- df %>% 
    group_by(id, classname) %>% 
    summarise(hours = sum(hours)) %>% 
    summarise(class.list = list(unique(as.character(classname))), 
      class.hours = list(hours)) 

由(類名),最晚一班的首先總結果皮。不再需要使用unique(),但是我將它保留在那裏以匹配您已有的部分。