在R中使用grep从数据框中删除行

14

我有一个类似于这样的数据框:

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

我想从这个数据框中删除某些行,具体取决于列z的内容:

要删除所有满足条件的行,可以使用以下代码:

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

这个很好用,第7行已经被删除:

    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

然而,当我使用grep搜索不在列z中的内容时,它似乎会删除数据框的所有内容:

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

我想以某种方式搜索并删除行,即使我要搜索的字符不在其中。 如何操作?

5个回答

26
你可以使用TRUE/FALSE子集替代数字。
grepl类似于grep,但它返回一个逻辑向量。否定也可以使用。
 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

7
这是你的问题:

以下是解决方法:

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

请使用grepl()代替:

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

这样做是因为取反的逻辑向量对于每一行都有一个条目:

> 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

4

为了完整性,自R 3.3.0版本以来,grep和相关函数都带有一个invert参数:

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

1

在这种情况下,您想要使用grepl,例如:new_d <- d[! grepl("K",d$z),]


0

如果您不想使用!invert = TRUE,您也可以仅使用正则表达式:

d[ grep('^((?!K).)*$', d$z, perl = TRUE), ]

摘自这里


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接