使用ddply删除每个子集的第一个条目

时间:2017-05-10 14:22:53

标签: r plyr

我有一个标题为“id”和“date”的数据框,其中每个id可以有多个日期。例如:

id    date
001   03/05/2000
001   06/05/2001
001   01/09/2002
002   03/05/2000
002   03/09/2004
003   03/05/2000
003   03/07/2001
003   02/10/2002

我想删除第一个条目的行(按日期排序)。因此,对于上面的示例,我希望最终得到:

id    date
001   06/05/2001
001   01/09/2002
002   03/09/2004
003   03/07/2001
003   02/10/2002

我尝试过以下方面的事情:

reduced <- ddply(data, .(id), function(x) x[-1,])
没有运气。

我有什么想法可以有效地做到这一点?

问题是根据id将其分解为子集,删除第一行(按日期排序)然后将它们重新加入到最终数据框中,这正是ddply通常有用但我似乎无法让它在这里工作。

3 个答案:

答案 0 :(得分:0)

dplyr解决方案:

library(dplyr)
data %>% group_by(id) %>% slice(-1)

     id       date
  <chr>      <chr>
1   001 06/05/2001
2   001 01/09/2002
3   002 03/09/2004
4   003 03/07/2001
5   003 02/10/2002

slice(-1)删除每个组的第一行。

答案 1 :(得分:0)

使用dplyr:

dat1 %>% 
  group_by(id) %>% 
  do(tail(.,-1))

使用BaseR,假设我有一个有序数据:

dat1[duplicated(dat1$id,fromLast = F),]

使用data.table

 setDT(dat1)[,tail(.SD,-1),by="id"]

关于效率部分,我在四个查询上运行了一个微基准测试以及OP的ddply查询。下面是运行= 10000的结果。对于我以我编写的方式编写的查询,似乎BaseR重复是不成熟的。它可能会有所变化,如果有其他方式编写这些查询可以更有效,可能有人可以指导我。感谢

Unit: microseconds
                                      expr      min
   setDT(dat1)[, tail(.SD, -1), by = "id"] 1458.790
 dat1[duplicated(dat1$id, fromLast = F), ]  170.227
 dat1 %>% group_by(id) %>% do(tail(., -1)) 2014.897
   ddply(dat1, .(id), function(x) x[-1, ]) 1667.238
       lq      mean   median       uq        max neval
 1644.247 1788.5900 1715.314 1805.304  24960.212 10000
  230.614  263.3895  251.405  277.276   4469.816 10000
 2237.728 2490.9345 2329.737 2480.637 213565.874 10000
 1845.771 2027.1384 1910.950 2003.320 237116.650 10000

输出:

     id      date
  <int>     <chr>
1     1 06-May-01
2     1 01-Sep-02
3     2 03-Sep-04
4     3 03-Jul-01
5     3 02-Oct-02

答案 2 :(得分:0)

data <- data[order(data$date),]
data <- data[ duplicated(data$id),]