Reputation: 609
I have a dataframe such as this one:
d <- data.frame(x=1,
y=1:10,
z=c("apple","pear","banana","A","B","C","D","E","F","G"),
stringsAsFactors = FALSE)
I'd like to delete some rows from this dataframe, depending on the content of column z:
new_d <- d[-grep("D",d$z),]
This works fine; row 7 is now deleted:
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
However, when I use grep to search for content that is not present in column z, it seems to delete all content of the dataframe:
new_d <- d[-grep("K",d$z),]
new_d
# [1] x y z
# <0 rows> (or 0-length row.names)
I would like to search and delete rows in this or another way, even if the character string I am searching for is not present. How to go about this?
Upvotes: 14
Views: 24599
Reputation: 3973
If you don't want to use !
or invert = TRUE
you can also use a REGEX only:
d[ grep('^((?!K).)*$', d$z, perl = TRUE), ]
Taken from here.
Upvotes: 0
Reputation: 16089
For completeness, since R 3.3.0, grep
and friends come with an invert
argument:
new_d <- d[grep("K", d$z, invert = TRUE), ]
Upvotes: 4
Reputation: 72741
Here's your problem:
> grep("K",c("apple","pear","banana","A","B","C","D","E","F","G"))
integer(0)
Try grepl() instead:
d[!grepl("K",d$z),]
This works because the negated logical vector has an entry for every row:
> 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
Upvotes: 7
Reputation: 49810
You can use TRUE/FALSE subsetting instead of numeric.
grepl
is like grep, but it returns a logical
vector. Negation works with it.
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
Upvotes: 26
Reputation: 44614
You want to use grepl
in this case, e.g., new_d <- d[! grepl("K",d$z),]
.
Upvotes: 1