0

假设我有一个这样的数据集:

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

IE,

   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)。

谢谢你的帮助!

4

2 回答 2

1

在基础 R 中,这可以通过两次调用来完成aggregate。内部调用汇总小时数,外部调用“连接”小时数和类名。在 的外部调用中aggregatecbind用于在输出中包含小时和类名,并提供所需的变量名。

# 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函数设置变量名称。

于 2017-05-24T15:52:55.353 回答
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() ,但我将它保留在那里以匹配您已经拥有的部分。

于 2017-05-24T16:21:13.850 回答