使用 ddply 删除每个子集的第一个条目
Removing the first entry of each subset using ddply
我有一个带有标题 "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 擅长的,但我做不到似乎让它在这里工作。
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)
删除每个组的第一行。
使用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 查询进行了微基准测试。下面是 运行 for = 10000 的结果。似乎 BaseR duplicated 对于我以我编写的方式编写的查询来说有点领先。如果有另一种更有效的方式来编写这些查询,它可能会发生变化,也许有人可以指导我。谢谢
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
data <- data[order(data$date),]
data <- data[ duplicated(data$id),]
我有一个带有标题 "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 擅长的,但我做不到似乎让它在这里工作。
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)
删除每个组的第一行。
使用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 查询进行了微基准测试。下面是 运行 for = 10000 的结果。似乎 BaseR duplicated 对于我以我编写的方式编写的查询来说有点领先。如果有另一种更有效的方式来编写这些查询,它可能会发生变化,也许有人可以指导我。谢谢
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
data <- data[order(data$date),]
data <- data[ duplicated(data$id),]