在数据帧中第一次出现变量时提取所有BUT

时间:2015-11-04 01:55:20

标签: r

我有一个类似的数据框:

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

建议的方法是什么?

我最初的直觉是使用链接答案中概述的方法,构建一个"第一个"子集,然后说,"从原始数据框,给我除了这些值以外的所有内容" ......但这看起来似乎更复杂。

3 个答案:

答案 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}}