Rimozione di righe specifiche da un dataframe

Ho un data frame ad esempio:

sub day 1 1 1 2 1 3 1 4 2 1 2 2 2 3 2 4 3 1 3 2 3 3 3 4 

e vorrei rimuovere le righe specifiche che possono essere identificate dalla combinazione di sub e giorno. Ad esempio, dire che volevo rimuovere le righe dove sub = ‘1’ e day = ‘2’ e sub = 3 e day = ‘4’. Come potrei farlo? Mi rendo conto che potrei specificare i numeri delle righe, ma questo deve essere applicato a un enorme dataframe che sarebbe noioso da esaminare e identificare ogni riga.

 DF[ ! ( ( DF$sub ==1 & DF$day==2) | ( DF$sub ==3 & DF$day==4) ) , ] # note the ! (negation) 

Oppure se sub è un fattore suggerito dall’uso delle virgolette:

 DF[ ! paste(sub,day,sep="_") %in% c("1_2", "3_4"), ] 

Potrebbe anche usare sottoinsieme:

 subset(DF, ! paste(sub,day,sep="_") %in% c("1_2", "3_4") ) 

(E approvo l’uso di which nella risposta di Dirk quando si usa “[” anche se alcuni affermano che non è necessario.)

Questo si riduce a due passaggi distinti:

  1. Capisci quando la tua condizione è vera, e quindi calcola un vettore di booleani, o, come preferisco, i loro indici avvolgendoli in which()
  2. Creare un data.frame aggiornato escludendo gli indici del passaggio precedente.

Ecco un esempio:

 R> set.seed(42) R> DF <- data.frame(sub=rep(1:4, each=4), day=sample(1:4, 16, replace=TRUE)) R> DF sub day 1 1 4 2 1 4 3 1 2 4 1 4 5 2 3 6 2 3 7 2 3 8 2 1 9 3 3 10 3 3 11 3 2 12 3 3 13 4 4 14 4 2 15 4 2 16 4 4 R> ind <- which(with( DF, sub==2 & day==3 )) R> ind [1] 5 6 7 R> DF <- DF[ -ind, ] R> table(DF) day sub 1 2 3 4 1 0 1 0 3 2 1 0 0 0 3 0 1 3 0 4 0 2 0 2 R> 

E vediamo che sub==2 ha solo una voce rimanente con day==1 .

Modifica La condizione composta può essere eseguita con un ‘o’ come segue:

 ind <- which(with( DF, (sub==1 & day==2) | (sub=3 & day=4) )) 

ed ecco un nuovo esempio completo

 R> set.seed(1) R> DF <- data.frame(sub=rep(1:4, each=5), day=sample(1:4, 20, replace=TRUE)) R> table(DF) day sub 1 2 3 4 1 1 2 1 1 2 1 0 2 2 3 2 1 1 1 4 0 2 1 2 R> ind <- which(with( DF, (sub==1 & day==2) | (sub==3 & day==4) )) R> ind [1] 1 2 15 R> DF <- DF[-ind, ] R> table(DF) day sub 1 2 3 4 1 1 0 1 1 2 1 0 2 2 3 2 1 1 0 4 0 2 1 2 R> 

Ecco una soluzione al tuo problema usando la funzione di filter dplyr .

Sebbene tu possa passare il tuo frame di dati come primo argomento a qualsiasi funzione di dplyr, ho usato il suo operatore %>% , che canalizza il tuo frame di dati su una o più funzioni di dplyr (semplicemente filtro in questo caso).

Una volta che hai familiarità con dplyr, il cheat sheet è molto utile.

 > print(df <- data.frame(sub=rep(1:3, each=4), day=1:4)) sub day 1 1 1 2 1 2 3 1 3 4 1 4 5 2 1 6 2 2 7 2 3 8 2 4 9 3 1 10 3 2 11 3 3 12 3 4 > print(df <- df %>% filter(!((sub==1 & day==2) | (sub==3 & day==4)))) sub day 1 1 1 2 1 3 3 1 4 4 2 1 5 2 2 6 2 3 7 2 4 8 3 1 9 3 2 10 3 3 

una soluzione semplice

cond1 <- df$sub == 1 & df$day == 2

cond2 <- df$sub == 3 & df$day == 4

df <- df[!cond1,]

df <- df[!cond2,]