2012-06-26 94 views
9

如何才能對以下示例數據框進行子集化,以僅返回最早發生的一個 觀察[即分(年)]每個ID?子集R數據框或有關重複變量的值

id <- c("A", "A", "C", "D", "E", "F") 
year <- c(2000, 2001, 2001, 2002, 2003, 2004) 
qty <- c(100, 300, 100, 200, 100, 500) 
df=data.frame(year, qty, id) 

在上面的例子中有在2000年和2001年在重複的ID的情況下,兩個意見爲「A」的ID,我想該子集的數據幀僅包括第一次出現(即在2000年)重複的id的觀察。

df2 = subset(df, ???) 

這就是我試圖返回:

df2 

year qty id 
2000 100 A 
2001 100 C 
2002 200 D 
2003 100 E 
2004 500 F 

任何援助將不勝感激。

回答

9

您可以在最小的一年+ ID彙總,然後與原始數據幀合併以獲得數量:

df2 <- merge(aggregate(year ~ id, df1, min), df1) 

# > df2 
# id year qty 
# 1 A 2000 100 
# 2 C 2001 100 
# 3 D 2002 200 
# 4 E 2003 100 
# 5 F 2004 500 
+0

非常直觀的解決方案。非常感謝你。 – MikeTP

8

這是你在找什麼?你的第二排對我來說看起來不對(這是重複的一年,而不是第一次)。

> duplicated(df$year) 
[1] FALSE FALSE TRUE FALSE FALSE FALSE 
> df[!duplicated(df$year), ] 
    year qty id 
1 2000 100 A 
2 2001 300 A 
4 2002 200 D 
5 2003 100 E 
6 2004 500 F 

編輯1:呃,我完全誤解了你的要求。儘管如此,我會保持這一點。

編輯2:

好吧,這裏是一個解決方案:按年份(所以每個ID的第一項具有最早的一年),然後使用duplicated。我覺得這是最簡單的解決方案:

> df.sort.year <- df[order(df$year), ] 
> df.sort.year[!duplicated(df$id), ] 
    year qty id 
1 2000 100 A 
3 2001 100 C 
4 2002 200 D 
5 2003 100 E 
6 2004 500 F 
+0

謝謝你,我不知道複製的功能 – MikeTP

5

使用plyr

library(plyr) 
## make sure first row will be min (year) 
df <- arrange(df, id, year) 
df2 <- ddply(df, .(id), head, n = 1) 


df2 
## year qty id 
## 1 2000 100 A 
## 2 2001 100 C 
## 3 2002 200 D 
## 4 2003 100 E 
## 5 2004 500 F 

或使用data.table。將密鑰設置爲id,year將確保第一行是年份的最小值。

library(data.table) 
DF <- data.table(df, key = c('id','year')) 
DF[,.SD[1], by = 'id'] 

##  id year qty 
## [1,] A 2000 100 
## [2,] C 2001 100 
## [3,] D 2002 200 
## [4,] E 2003 100 
## [5,] F 2004 500 
+2

同樣的,對於大型data.tables,這可能會更快:'DF [J(唯一的(DF [,ID])),MULT = 「第一」]'。 –

0

有可能是這樣的漂亮的方式,但是這是來到介意

# use which() to get index for each id, saving only first 
first_occurance <- with(df, sapply(unique(id), function(x) which(id %in% x)[1])) 
df[first_occurance,] 
# year qty id 
#1 2000 100 A 
#3 2001 100 C 
#4 2002 200 D 
#5 2003 100 E 
#6 2004 500 F 
相關問題