在R中选择包含字符但不包含另一个字符的行

u5rb5r59  于 2022-12-25  发布在  其他
关注(0)|答案(3)|浏览(139)

从下面的 Dataframe

df <- data.frame(col1 = c("ap(pl)e", "or(a)ng%e", "pe%ar", "bl(u%)e", "red"),
                 col2 = c(1,3,5,4,8))
df
       col1 col2
1   ap(pl)e    1
2 or(a)ng%e    3
3     pe%ar    5
4   bl(u%)e    4
5       red    8

我想过滤col1中的值包含(但%。

col1 col2
1 ap(pl)e    1
2   pe%ar    5
3     red    8

所以我使用case_when沿着gprel。这将是dplyr管道的一部分。

#works
df %>%
    mutate(result = case_when((grepl("p", .[[1]]) & !grepl("r", .[[1]])) ~"Yes",
#does not work                                      TRUE~"No"))
df %>%
    mutate(result = case_when((grepl("(", .[[1]]) & !grepl("%", .[[1]])) ~"Yes",
                                      TRUE~"No"))

这对%和(不起作用。有什么窍门可以使它起作用吗?

b1payxdu

b1payxdu1#

我们可以将(后跟任意字符(.*)的模式与str_detect中的%进行匹配,对于行的求反情况(negate = TRUE)到filter返回TRUE/FALSE

library(dplyr)
library(stringr)
df %>% 
  filter(str_detect(col1, "\\(.*%", negate = TRUE))
  • 输出
col1 col2
1 ap(pl)e    1
2   pe%ar    5
3     red    8

如果它必须是列

df %>% 
  mutate(result = case_when(str_detect(col1, "\\(.*%", 
     negate = TRUE) ~ "Yes", TRUE ~ "No"))
       col1 col2 result
1   ap(pl)e    1    Yes
2 or(a)ng%e    3     No
3     pe%ar    5    Yes
4   bl(u%)e    4     No
5       red    8    Yes

或者使用base R

subset(df, seq_along(col1) %in% grep("\\(.*%", col1, invert = TRUE))
      col1 col2
1 ap(pl)e    1
3   pe%ar    5
5     red    8
4xrmg8kj

4xrmg8kj2#

如果你想知道为什么你的代码不工作,那么在'('前面添加斜线。

df %>%
  mutate(result = case_when((grepl("\\(", .[[1]]) & !grepl("%", .[[1]])) ~"Yes",TRUE~"No"))

输出:

col1 col2 result
1   ap(pl)e    1    Yes
2 or(a)ng%e    3     No
3     pe%ar    5     No
4   bl(u%)e    4     No
5       red    8     No
bgibtngc

bgibtngc3#

您可以使用grepl部署正则表达式。

df[!grepl('\\(.*%', df$col1, perl=TRUE), ]
#      col1 col2
# 1 ap(pl)e    1
# 3   pe%ar    5
# 5     red    8

相关问题