我有一个数据框(称为“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
我怎样才能得到描述的结果?
谢谢。
答案 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 ID
和Country
。请注意,如果您按Description
和ID
进行分组,并且每个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