2012-07-18 29 views
9

ich man einen Datenrahmen wie diese habe:in R Mit grep Zeilen aus einer data.frame löschen

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

Ich mag einige Zeilen aus diesem Datenrahmen löschen, auf dem Inhalt der Spalte z je :

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

Das funktioniert gut; Zeile 7 ist nun gelöscht:

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 

Allerdings, wenn ich grep nach Inhalten suchen verwenden, die nicht in Spalte z, so scheint es, alle Inhalte des Datenrahmen zu löschen:

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

würde ich Ich mag es, Zeilen auf diese oder andere Weise zu suchen und zu löschen, auch wenn die Zeichenkette, nach der ich suche, nicht vorhanden ist. Wie geht das?

Antwort

18

Sie können die TRUE/FALSE-Teilmenge anstelle von numerisch verwenden.

grepl ist wie Grep, aber es gibt einen logical Vektor zurück. Negation funktioniert damit.

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

Sie möchten in diesem Fall grepl verwenden, z. B. new_d <- d[! grepl("K",d$z),].

7

Hier ist Ihr Problem:

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

Try Grepl() statt:

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

Das funktioniert, weil der negierte logische Vektor einen Eintrag für jede Zeile hat:

> 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

Der Vollständigkeit halber, seit R 3.3.0, grep und Freunde kommen mit einem invert Argument:

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