2014-10-08 26 views
7

Ho un frame di dati che assomiglia a questo:Bandiera prima dal gruppo in R frame di dati

id score 
1 15 
1 18 
1 16 
2 10 
2 9 
3 8 
3 47 
3 21 

mi piacerebbe identificare un modo per segnalare la prima occorrenza di id - simile alla prima. e ultimo. in SAS. Ho provato la funzione! Duplicata, ma ho bisogno di aggiungere effettivamente la colonna "flag" al mio frame di dati poiché la sto eseguendo in un ciclo successivo. Mi piacerebbe avere qualcosa di simile:

id score first_ind 
1 15  1 
1 18  0 
1 16  0 
2 10  1 
2 9  0 
3 8  1 
3 47  0 
3 21  0 

risposta

15
> df$first_ind <- as.numeric(!duplicated(df$id)) 
> df 
    id score first_ind 
1 1 15   1 
2 1 18   0 
3 1 16   0 
4 2 10   1 
5 2  9   0 
6 3  8   1 
7 3 47   0 
8 3 21   0 
+0

Brillante, grazie! – davids12

+0

+1 il mio pensiero esattamente. –

+2

Anche '(! Duplicato (df $ id)) + 0' è abbastanza pulito. –

6

si possono trovare i bordi con diff.

x <- read.table(text = "id score 
1 15 
1 18 
1 16 
2 10 
2 9 
3 8 
3 47 
3 21", header = TRUE) 

x$first_id <- c(1, diff(x$id)) 
x 

    id score first_id 
1 1 15  1 
2 1 18  0 
3 1 16  0 
4 2 10  1 
5 2  9  0 
6 3  8  1 
7 3 47  0 
8 3 21  0 
+0

Questo funziona solo finché le voci di identificazione vengono ordinate in ordine crescente e numerate successivamente, giusto? Per favore correggimi se sbaglio. –

+0

Sì, sei corretto. –

3

Utilizzando plyr:

library("plyr") 
ddply(x,"id",transform,first=as.numeric(seq(length(score))==1)) 

o se si preferisce dplyr:

x %>% group_by(id) %>% 
    mutate(first=c(1,rep(0,n-1))) 

(anche se si opera completamente nel quadro plyr/dplyr probabilmente wouldn 't bisogno di questa variabile di bandiera comunque ...)

+0

Nella versione 'dplyr', vuoi dire 'mutare' invece di' trasformare'? Puoi anche scrivere 'df%>% group_by (id)%>% mutate (first = row_number() == 1)' (se le logiche sono accettabili) –

+0

grazie. (Sono più abituato a 'plyr') –

2

Un'altra opzione di base R:

df$first_ind <- ave(df$id, df$id, FUN = seq_along) == 1 
df 
# id score first_ind 
#1 1 15  TRUE 
#2 1 18  FALSE 
#3 1 16  FALSE 
#4 2 10  TRUE 
#5 2  9  FALSE 
#6 3  8  TRUE 
#7 3 47  FALSE 
#8 3 21  FALSE 

Questo funziona anche in caso di non ordinati id s. Se vuoi 1/0 invece di T/F puoi facilmente avvolgerlo in as.integer(.).

Problemi correlati