我有一个类似的数据框:
ID DATE N Price
1 2013-02-04 3 29.99
1 2013-03-18 1 9.99
1 2013-04-13 2 19.99
2 2013-02-18 1 18.99
2 2013-05-11 2 19.99
这个答案Extract rows for the first occurrence of a variable in a data frame讲述了如何提取目标值的第一次出现......但我需要所有但是第一次出现,又名:
ID DATE N Price
1 2013-03-18 1 9.99
1 2013-04-13 2 19.99
2 2013-05-11 2 19.99
建议的方法是什么?
我最初的直觉是使用链接答案中概述的方法,构建一个"第一个"子集,然后说,"从原始数据框,给我除了这些值以外的所有内容" ......但这看起来似乎更复杂。
答案 0 :(得分:6)
您可以非常轻松地使用 data.table 包执行此操作。
library(data.table)
setDT(df)[, .SD[-1], by = ID]
# ID DATE N Price
# 1: 1 2013-03-18 1 9.99
# 2: 1 2013-04-13 2 19.99
# 3: 2 2013-05-11 2 19.99
其中df
是您的原始数据。这将删除每个组的第一行,按ID
分组。
另一个选项是 dplyr 包。
library(dplyr)
slice(group_by(df, ID), -1)
# ID DATE N Price
# (int) (fctr) (int) (dbl)
# 1 1 2013-03-18 1 9.99
# 2 1 2013-04-13 2 19.99
# 3 2 2013-05-11 2 19.99
这些删除所有组的第一行。如果组中只有一行,则不指定应该发生的情况。如果你需要保留这些行,你需要考虑到这一点。因此,让我们将一行添加为一组并进行查看。
dff <- rbind(df, df[4, ])
dff[6, 1] <- 3
然后 data.table 代码将是
setDT(dff)[, .SD[if(.N == 1L) 1 else -1], by = ID]
# ID DATE N Price
# 1: 1 2013-03-18 1 9.99
# 2: 1 2013-04-13 2 19.99
# 3: 2 2013-05-11 2 19.99
# 4: 3 2013-02-18 1 18.99
和 dplyr 代码将是
slice(group_by(dff, ID), if(n() == 1L) 1 else -1)
# ID DATE N Price
# (dbl) (fctr) (int) (dbl)
# 1 1 2013-03-18 1 9.99
# 2 1 2013-04-13 2 19.99
# 3 2 2013-05-11 2 19.99
# 4 3 2013-02-18 1 18.99
对于那些情况。
数据:强>
df <- structure(list(ID = c(1L, 1L, 1L, 2L, 2L), DATE = structure(c(1L,
3L, 4L, 2L, 5L), .Label = c("2013-02-04", "2013-02-18", "2013-03-18",
"2013-04-13", "2013-05-11"), class = "factor"), N = c(3L, 1L,
2L, 1L, 2L), Price = c(29.99, 9.99, 19.99, 18.99, 19.99)), .Names = c("ID",
"DATE", "N", "Price"), class = "data.frame", row.names = c(NA,
-5L))
答案 1 :(得分:5)
如果您不想使用附加软件包:
dx1 * dy2 - dx2 * dy1 == 0
答案 2 :(得分:1)
另一个选项是 df[with(df, ave(ID, ID, FUN= seq_along)!=1),]
# ID DATE N Price
#2 1 2013-03-18 1 9.99
#3 1 2013-04-13 2 19.99
#5 2 2013-05-11 2 19.99
{{1}}