2012-06-26 11 views
9

¿Cómo puedo subconjuntar el siguiente marco de datos de ejemplo para que solo devuelva una observación de en cuanto a la primera ocurrencia [es decir min (año)] de cada identificación?Recuadro de datos del subconjunto R depende del valor de las variables duplicadas

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) 

En el ejemplo anterior hay dos observaciones sobre la "A" la identificación en los años 2000 y 2001. En el caso de de duplicados id, me gustaría la trama de datos subconjunto para incluir sólo la primera ocurrencia (es decir, en 2000) de las observaciones para la identificación duplicada.

df2 = subset(df, ???) 

Esto es lo que estoy tratando de volver:

df2 

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

Cualquier ayuda sería muy apreciada.

Respuesta

9

Puede agregarse en años mínimo + ID, y luego fusionar con la trama de datos original para obtener Cantidad:

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

gran solución intuitiva. muchas gracias. – MikeTP

8

¿Esto es lo que estás buscando? Su segunda fila me parece incorrecta (es el año duplicado, no el primero).

> 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 

Edit 1: Er, he entendido mal lo que pedías. Aunque lo mantendré aquí para completarlo.

Edición 2:

Ok, aquí hay una solución: Ordenar por año (lo que la primera entrada por ID tiene el primer año) y luego usar duplicated. Creo que esta es la solución más simple:

> 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

gracias, yo no era consciente de la función duplicada – MikeTP

5

Usando 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 

o el uso de data.table. Al establecer la clave como id, el año asegurará que la primera fila sea el mínimo del año.

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

Además, para grandes data.tables, esto puede ser más rápido: 'DF [J (único (DF [, id])), mult = "primero"] '. –

0

No es probable que una forma más bonita de hacer esto, pero esto es lo que vino a importa

# 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 
Cuestiones relacionadas