2015-11-04 37 views
1

我有一个像数据帧:提取所有,但一个变量的数据帧中第一次出现

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 

这是什么建议?

我最初的直觉是使用链接答案中概述的方法,构建“第一个”子集,然后说,“从原始数据框中,给我除了这些值之外的所有东西”......但是这似乎也许更复杂。

回答

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)) 
5

如果你不希望使用添加的包:

df[duplicated(df$ID),] 
+0

我喜欢它的简单。我想出的最好的是'df [--match(unique(df $ ID),df $ ID)]],但这更好。 – thelatemail

1

另一种选择是ave

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 
相关问题