2012-07-18 27 views
9

Ho una dataframe come questo:Uso grep in R per eliminare righe da una data.frame

d <- data.frame(cbind(x=1, y=1:10, z=c("apple","pear","banana","A","B","C","D","E","F","G")), stringsAsFactors = FALSE) 

Vorrei eliminare alcune righe da questo dataframe, a seconda del contenuto della colonna z :

new_d <- d[-grep("D",d$z),] 

Questo funziona correttamente; riga 7 è cancellato:

new_d 
    x y  z 
    1 1 1 apple 
    2 1 2 pear 
    3 1 3 banana 
    4 1 4  A 
    5 1 5  B 
    6 1 6  C 
    8 1 8  E 
    9 1 9  F 
    10 1 10  G 

Tuttavia, quando uso grep per la ricerca di contenuti che non è presente nella colonna z, sembra di eliminare tutto il contenuto della dataframe:

new_d <- d[-grep("K",d$z),] 
    new_d 
    [1] x y z 
    <0 rows> (or 0-length row.names) 

lo farei piace cercare ed eliminare righe in questo o in un altro modo, anche se la stringa di caratteri che sto cercando non è presente. Come andare su questo?

risposta

18

È possibile utilizzare la sottoregolazione TRUE/FALSE anziché numerica.

grepl è come grep, ma restituisce un vettore logical. La negazione funziona con esso.

d[!grepl("K",d$z),] 
    x y  z 
1 1 1 apple 
2 1 2 pear 
3 1 3 banana 
4 1 4  A 
5 1 5  B 
6 1 6  C 
7 1 7  D 
8 1 8  E 
9 1 9  F 
10 1 10  G 
1

Si desidera utilizzare grepl in questo caso, ad es. new_d <- d[! grepl("K",d$z),].

7

Ecco il problema:

> grep("K",c("apple","pear","banana","A","B","C","D","E","F","G")) 
integer(0) 

Try Grepl() invece:

d[!grepl("K",d$z),] 

Questo funziona perché il vettore logica negata ha una voce per ogni riga:

> grepl("K",d$z) 
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE 
> !grepl("K",d$z) 
[1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE 
0

Per completezza, dal R 3.3.0, grep e gli amici hanno un argomento invert:

new_d <- d[grep("K", d$z, invert = TRUE)] 
Problemi correlati