使用-grep从data.frame中删除行时,如果没有找到匹配项,则会删除所有行(--如何防止这种情况?)

c2e8gylq  于 2023-01-22  发布在  其他
关注(0)|答案(2)|浏览(109)

我有一个经常更新的数据框,如果在其中发现某些字符串,则需要删除其中的一些行。我之前已经使用-grep删除了包含有问题的字符串的行,例如:

dataframe[-grep('some string', dataframe$column),]

但是,有时候这个字符串并没有出现在 Dataframe 中,在这种情况下,-grep返回的是一个空的 Dataframe 。

> test.df<-data.frame(number=c(1:10), letter=letters[1:10])

> test.df
   number letter
1       1      a
2       2      b
3       3      c
4       4      d
5       5      e
6       6      f
7       7      g
8       8      h
9       9      i
10     10      j

> test.df[-grep('h', test.df$letter),]
   number letter
1       1      a
2       2      b
3       3      c
4       4      d
5       5      e
6       6      f
7       7      g
9       9      i
10     10      j

> test.df[-grep('k', test.df$letter),]
[1] number letter
<0 rows> (or 0-length row.names)

我可以将“test.df[-grep...” Package 在“if”测试中,以检查在删除搜索字符串之前是否找到它,例如:

if(any(grepl('k',test.df$letter))){test.df<-test.df[-grep('k', test.df$letter),]}

...但在我看来,这应该隐含在-grep命令中。有没有更好(更有效)的方法来完成行删除,而不会在数据框中缺少搜索字符串时威胁到删除所有数据?

jjjwad0x

jjjwad0x1#

使用grepl可以执行以下操作:

test.df <- data.frame(number = c(1:10), letter = letters[1:10])

test.df[!grepl("h", test.df$letter), ]
#>    number letter
#> 1       1      a
#> 2       2      b
#> 3       3      c
#> 4       4      d
#> 5       5      e
#> 6       6      f
#> 7       7      g
#> 9       9      i
#> 10     10      j

test.df[!grepl("k", test.df$letter), ]
#>    number letter
#> 1       1      a
#> 2       2      b
#> 3       3      c
#> 4       4      d
#> 5       5      e
#> 6       6      f
#> 7       7      g
#> 8       8      h
#> 9       9      i
#> 10     10      j

创建于2023年1月19日,使用reprex v2.0.2

5cnsuln7

5cnsuln72#

grep中可以使用invert,而不是在子集化时使用-

test.df[grep('k', test.df$letter, invert=TRUE),]
#   number letter
#1       1      a
#2       2      b
#3       3      c
#4       4      d
#5       5      e
#6       6      f
#7       7      g
#8       8      h
#9       9      i
#10     10      j

test.df[grep('h', test.df$letter, invert=TRUE),]
#   number letter
#1       1      a
#2       2      b
#3       3      c
#4       4      d
#5       5      e
#6       6      f
#7       7      g
#9       9      i
#10     10      j

在这种情况下,似乎整个字符串都应该匹配,其中一种替代方法是使用==!=

test.df[test.df$letter != "k",]
test.df[test.df$letter != "h",]

相关问题