2012-06-26 16 views
9

Làm cách nào tôi có thể đặt khung dữ liệu ví dụ sau để chỉ trả lại một số quan sát cho sự xuất hiện sớm nhất [tức là phút (năm)] của mỗi id?Nhóm dữ liệu nhóm con R trên giá trị của các biến trùng lặp

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) 

Trong ví dụ trên có hai quan sát cho "A" id ở năm 2000 và năm 2001. Trong trường hợp trùng lặp của id, tôi muốn khung dữ liệu tập hợp con để chỉ bao gồm những sự xuất hiện đầu tiên (tức là vào năm 2000) của các quan sát cho id trùng lặp.

df2 = subset(df, ???) 

Đây là những gì tôi đang cố gắng để trở lại:

df2 

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

Bất kỳ trợ giúp sẽ được đánh giá rất nhiều.

Trả lời

9

Bạn có thể tổng hợp vào năm tối thiểu + id, sau đó hợp nhất với khung dữ liệu gốc để có được qty:

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

giải pháp trực quan tuyệt vời. Cảm ơn nhiều. – MikeTP

8

Đây có phải là những gì bạn đang tìm kiếm không? Hàng thứ hai của bạn trông sai với tôi (đó là năm trùng lặp, không phải là lần đầu tiên).

> 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 

Chỉnh sửa 1: Er, tôi hoàn toàn hiểu lầm những gì bạn đang yêu cầu. Tôi sẽ giữ điều này ở đây cho đầy đủ mặc dù.

Chỉnh sửa 2:

Ok, đây là một giải pháp: Sắp xếp theo năm (do sự xâm nhập đầu tiên cho mỗi ID có năm đầu tiên) và sau đó sử dụng duplicated. Tôi nghĩ rằng đây là giải pháp đơn giản nhất:

> 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

cảm ơn bạn, tôi đã không nhận thức được chức năng nhân đôi – MikeTP

5

Sử dụng 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 

hoặc sử dụng data.table. Đặt khóa là id, năm sẽ đảm bảo hàng đầu tiên là tối thiểu trong năm.

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

Ngoài ra, đối data.tables lớn, điều này có thể nhanh hơn: 'DF [J (unique (DF [id])), mult = "đầu tiên"] '. –

0

Có khả năng một cách đẹp hơn để làm điều này, nhưng đây là những gì đã đến tâm

# 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