2017-05-24 114 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(),但是我将它保留在那里以匹配您已有的部分。