R总结每个id的每个类的总数

时间:2017-05-24 15:45:29

标签: r dplyr summarize

假设我有这样的数据集:

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一行。所以,我希望它回归:

   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)的小时数相加。

感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

在基础R中,这可以通过两次调用aggregate来完成。内部呼叫将小时和外部呼叫相加并且#34;连接&#34;小时和班级名称。在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.table setnames函数设置变量名称。

答案 1 :(得分:1)

这是使用dplyr执行此操作的方法:

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

首先按(classname)总结最新组的皮肤。没有必要再使用unique()了,但是我把它保存在那里以匹配你已经拥有的部分。