【发布时间】:2013-08-19 18:10:33
【问题描述】:
我想根据每个人每个日期的最大数量,通过每个人每个日期只进行一次观察来缩小我的 df。
这是我的 df:
names dates quantity
1 tom 2010-02-01 28
3 tom 2010-03-01 7
2 mary 2010-05-01 30
6 tom 2010-06-01 21
4 john 2010-07-01 45
5 mary 2010-07-01 30
8 mary 2010-07-01 28
11 tom 2010-08-01 28
7 john 2010-09-01 28
10 john 2010-09-01 30
9 john 2010-07-01 45
12 mary 2010-11-01 28
13 john 2010-12-01 7
14 john 2010-12-01 14
我首先通过找到每个人每个日期的最大数量来做到这一点。这没问题,但正如您所看到的,如果一个人的数量相等,他们每个日期保留相同数量的 obs。
merge(df, aggregate(quantity ~ names+dates, df, max))
names dates quantity
1 john 2010-07-01 45
2 john 2010-07-01 45
3 john 2010-09-01 30
4 john 2010-12-01 14
5 mary 2010-05-01 30
6 mary 2010-07-01 30
7 mary 2010-11-01 28
8 tom 2010-02-01 28
9 tom 2010-03-01 7
10 tom 2010-06-01 21
11 tom 2010-08-01 28
所以,我的下一步是只取每个日期的第一个 obs(鉴于我已经选择了最大的数量)。我无法得到正确的代码。这是我尝试过的:
merge(l, aggregate(names ~ dates, l, FUN=function(z) z[1]))->m ##doesn't get rid of one obs for john
还有一个 data.table 选项
l[, .SD[1], by=c(names,dates)] ##doesn't work at all
我喜欢聚合和 data.table 选项,因为它们速度很快,并且 df 有大约 100k 行。
提前感谢您!
解决方案
我发的太快了——抱歉!!解决这个问题的一个简单方法就是找到重复项,然后删除它们。例如。,;
merge(df, aggregate(quantity ~ names+dates, df, max))->toy
toy$dup<-duplicated(toy)
toy<-toy[toy$dup!=TRUE,]
这里是系统时间
system.time(dt2[, max(new_quan), by = list(hai_dispense_number, date_of_claim)]->method1)
user system elapsed
20.04 0.04 20.07
system.time(aggregate(new_quan ~ hai_dispense_number+date_of_claim, dt2, max)->rpp)
user system elapsed
19.129 0.028 19.148
【问题讨论】:
-
您应该将您的解决方案作为答案发布并接受它,而不是将其包含在您的问题中。
-
@user2363642 有一个更好的方法,使用
unique()。请参考下面我的回答。 -
我可以接受我自己的答案吗?这合乎道德吗?!
-
如果你能证明它比其他所有的都快,那么它就是“道德的”。我认为我们仍在等待真正的 data.table 解决方案,它很可能会获胜。 (我怀疑这是重复的。)
-
我也不明白合并在做什么。为什么不只是:
aggregate(quantity ~ names+dates, df, max)?
标签: r aggregate data.table