从下面的数据框
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中的值包含(but %.
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"))
这对%和(不起作用。有什么技巧可以让它起作用吗?
我们可以匹配(
后面任何字符(.*
)和%
在str_detect
中的模式,对于否定的情况(negate = TRUE
)返回TRUE/FALSE到filter
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
如果你想知道为什么你的代码不能工作,那么在'('前添加斜杠。
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
您可以使用grepl
部署正则表达式。
df[!grepl('\(.*%', df$col1, perl=TRUE), ]
# col1 col2
# 1 ap(pl)e 1
# 3 pe%ar 5
# 5 red 8