在一列中聚合数据,同时在其他列中维护/返回数据

时间:2014-05-30 09:25:14

标签: r dataframe sumifs

我有一个数据框(称为“dk”),如下所示:

Date        Country  ID      Description    Qty
21/05/2014  DK       17423   Frontline      240
26/05/2014  DK       17423   Frontline      360
21/05/2014  DK       73663   Frontline      77
21/05/2014  DK       73663   Frontline      120
...

我想按ID计算数量。结果应该仍然显示国家和描述(除了ID和数量)。如果一个ID的日期不同,请使用较早的日期标记,如下所示:

Date        Country ID      Description      Qty
21/05/2014  DK      17423   Frontline        600
21/05/2014  DK      73663   Frontline        197

我使用了aggregate,但它从其他列中删除了信息。

data <- aggregate(dk$Qty ~ dk$ID, subset(dk, ID == 17423),sum)

ID      Qty
17423   600
73663   197

我怎样才能得到描述的结果?

谢谢。

2 个答案:

答案 0 :(得分:4)

另一种选择是使用dplyr

require(dplyr)

dk %>%
  mutate(Date = as.Date(as.character(Date), format="%d/%m/%Y")) %>%
  group_by(ID) %>%
  summarize(Date = min(Date),
            Qty = sum(Qty),
            Country = first(Country),
            Description = first(Description))

#     ID       Date Qty Country Description
#1 17423 2014-05-21 600      DK   Frontline
#2 73663 2014-05-21 197      DK   Frontline

通过这种方式,您将获得每ID行一行,Qty的{​​{1}},每ID的最小Date和第一项每个ID IDCountry。请注意,如果您按DescriptionID进行分组,并且每个Description有不同的说明,则结果会有所不同。只是因为您的样本数据没有不同的描述和国家,结果看起来都是一样的。

答案 1 :(得分:3)

也可以使用data.table套餐(我假设您的日期为Date类)

library(data.table)
setDT(dk)[, list(Qty = sum(Qty), Date = min(Date)), by = c("ID", "Country", "Description")]

如果您只想按ID聚合,可以执行以下操作(当我假设您需要其余列的第一个参数时)

setDT(dk)[, lapply(.SD, function(x) ifelse(is.numeric(x), sum(x), head(as.character(x), 1))), by = ID]

如果Date不是Date上课你可以先做

dk <- data.table(dk, key = "ID") # Creates a data.table object and sorts it by "ID"
dk[, Date:= as.Date(as.character(Date), "%d/%m/%Y")] #Transforms Date to "Date" class

然后你可以照常进行(只是没有setDT,因为它已经是data.table类),例如:

dk[, list(Qty = sum(Qty), Date = min(Date)), by = c("ID", "Country", "Description")]

##       ID Country Description Qty       Date
## 1: 17423      DK   Frontline 600 2014-05-21
## 2: 73663      DK   Frontline 197 2014-05-21